All articles
· 7 min read

PWA SEO: what changes, what doesn’t, and what breaks

A grounded guide to SEO for Progressive Web Apps — what Google actually indexes in 2026, the SSR/CSR trade-off, and the four mistakes that tank rankings.

TI
The InstantPWA team
Product & engineering

The myth that "PWAs are bad for SEO" comes from 2016-era single-page apps that shipped an empty <div id="app">. In 2026 the story is different: Googlebot renders JavaScript reliably, and every serious framework ships SSR. Here’s what actually matters.

What Google indexes

Googlebot does a two-pass render: an HTML pass, then a JS pass after a queue delay. Bing and other engines are less reliable. The safe rule is: whatever you want indexed must be present in the first HTML response.

SSR / SSG versus CSR

  • SSR/SSG — required for organic-driven pages: landing pages, blog posts, product pages, docs.
  • CSR — fine for authenticated app surfaces that don’t need to rank.

The four mistakes that tank rankings

  1. Hash routing. example.com/#/pricing is one URL to Google. Use History API paths.
  2. Missing canonicals. A PWA that swaps content client-side needs a per-route <link rel="canonical"> that self-references.
  3. Blank first paint. If the HTML response is empty, ranking speed collapses even if the page eventually renders.
  4. Duplicate og:image on every route. A single root-level og:image overrides your per-page share cards — set og:image at the leaf route.

What doesn’t change

Everything you already know about SEO: intent-matched titles, useful descriptions, internal linking, fast LCP, unique content. A PWA doesn’t change the fundamentals; it just adds a rendering discipline.

What a PWA can help with

Core Web Vitals. Once a PWA is installed, TTFB is effectively zero on repeat visits (service worker cache), and INP improves because you’ve shipped fewer bytes on the critical path. Google factors CWV into ranking, so the second-visit performance boost has a compounding effect.

Ship your install prompt in 60 seconds

InstantPWA is one line of code. Free forever for one widget, no card required.

Get started free