Google can render JavaScript. That doesn’t mean Google renders your JavaScript well, or quickly, or at all. The gap between “Google supports JS” and “Google indexed my JS-rendered page accurately” is where most JavaScript SEO problems live.
Modern web frameworks (React, Vue, Angular, Next.js, Nuxt, SvelteKit) render some or all of their content with JavaScript at runtime. The HTML the server initially sends may be a near-empty shell; the actual content gets injected by JavaScript after the page loads. For users with modern browsers, the experience is fine. For search engine crawlers, the experience depends on whether the crawler executes the JavaScript at all, how soon it does, and what state of the page it sees when execution completes.
Here’s the picture: how the rendering choices interact with indexing, what trade-offs each pattern carries, and the framework decisions that consistently produce results.
The rendering patterns:
Four patterns dominate modern web development, each with different SEO implications:
| Pattern | What it does | SEO position |
|---|---|---|
| <strong>SSR (Server-Side Rendering)</strong> | Server generates full HTML on each request. Client receives complete page. | Strongest. Crawlers see content immediately, no rendering delay. |
| <strong>SSG (Static Site Generation)</strong> | Server pre-builds all pages at build time. Client receives static HTML. | Strongest, same as SSR. Faster than SSR because no per-request rendering. |
| <strong>CSR (Client-Side Rendering)</strong> | Server sends minimal HTML shell. Client's JavaScript builds the page. | Weakest. Crawlers must execute JS, may delay or skip rendering. |
| <strong>Hybrid (Hydration, ISR, Streaming SSR)</strong> | Server pre-renders, client JavaScript "hydrates" interactivity. | Strong when implemented correctly, fragile when implementation has gaps. |
Single Page Applications (SPAs) built without server rendering fall into CSR. Most modern frameworks default to hybrid patterns because the pure SSR/CSR trade-off has been understood since 2016, and the framework authors have built better defaults.
How Googlebot processes JavaScript:
The pipeline:
- Stage 1 (Crawl): Googlebot fetches the URL. The HTML response is parsed. Links and resources are discovered. If the HTML is complete, indexing can proceed immediately.
- Stage 2 (Render queue): When the page requires JavaScript execution to display content, the URL enters the rendering queue. The Web Rendering Service processes URLs from the queue using Chromium-based rendering. The median render delay is about 5 seconds based on Martin Splitt’s published numbers from Chrome Dev Summit 2019, and Vercel’s 2024 analysis of 37,000 nextjs.org page renders found the 25th percentile at 4 seconds. The tail is longer than the median: Onely’s research has shown 5-50% of newly added JavaScript-dependent pages still partially unindexed two weeks after sitemap submission, depending on the sample. The queue isn’t the killer it once was, but the variance is real.
- Stage 3 (Index): After rendering completes, the rendered DOM is what gets indexed. Content that appeared only after JavaScript execution is now visible.
The implications:
- CSR pages enter the render queue, while SSR and SSG pages skip it.
- The render queue prioritizes URLs. High-authority sites and important pages render fast. Low-authority sites and tail pages wait longer.
- Rendering uses a recent Chromium version. Old browser quirks don’t apply, but framework-specific issues (hydration mismatches, missing meta tags, scripts that fail to execute) do.
- Resources required for rendering must be crawlable. If robots.txt blocks the JavaScript file that builds the content, Google can’t render the page.
Martin Splitt has discussed the render queue in multiple Search Off the Record episodes, framing it as the pipeline stage where delays accumulate most visibly. Vercel’s 2024 analysis of 37,000+ nextjs.org pages showed median delays in seconds rather than minutes, but the tail behavior matters more for SEO: sites with heavy JavaScript dependencies and lower authority can wait substantially longer for full indexation, and they operate on Google’s render schedule rather than their own.
What CSR breaks:
Pure client-side rendering produces five recurring problems:
- Slow indexation. Pages enter the render queue and wait. The median delay is seconds, but for low-authority sites with heavy JavaScript dependencies, the tail can stretch to days, and Onely’s research has shown a portion of newly added JS-dependent pages still partially unindexed weeks later.
- Incomplete indexation. When the render times out or fails (heavy JavaScript, blocked resources, runtime errors), Google indexes whatever was in the HTML, which may be a near-empty page.
- Missing metadata. Title tags, meta descriptions, and structured data injected by JavaScript appear in the rendered DOM but may not be evaluated correctly. Some SEO signals are read from the HTML response, before rendering.
- Internal link discovery delays. Links injected by JavaScript get discovered only after render. When the entire site navigation depends on JavaScript, crawl efficiency suffers.
- Social media previews break. Facebook, X, LinkedIn, and Slack preview crawlers don’t execute JavaScript at all. CSR pages produce empty previews when shared.
The combined effect: pure CSR works for sites where SEO is a minor concern and most traffic comes from direct sources. For sites where organic search matters, CSR is the wrong default.
Why hybrid patterns dominate:
The frameworks that handle SEO well in 2026 all converge on the same answer. Render the initial HTML on the server (or at build time), then let JavaScript take over for interactivity.
The patterns:
- Next.js with getServerSideProps or getStaticProps: Server or build-time rendering for the initial response. JavaScript handles client-side navigation and interactivity afterward.
- Nuxt with server-side rendering enabled: Vue framework equivalent. Server renders, client hydrates.
- SvelteKit with adapter-node or adapter-static: Svelte’s approach to the same pattern.
- Remix with loader functions: Server-rendered by default, client hydrates.
- Astro with islands architecture: Most of the page is static HTML; JavaScript “islands” handle specific interactive components.
The common element: search crawlers see the content without needing to execute JavaScript, while users get the interactivity that JavaScript provides after the initial load.
The trade-off is server cost and complexity. Server rendering requires server resources for every request (SSR) or longer build times (SSG). Hybrid patterns add architectural complexity that pure CSR doesn’t have. The cost is paid for the SEO and performance benefits.
The hydration mismatch problem:
Hydration is the process where client-side JavaScript attaches to server-rendered HTML, adding event listeners and reactive behavior without re-rendering the DOM. When it works, users get fast initial loads (from SSR) and full interactivity (from hydration). When it fails, the symptoms are subtle and damaging:
- Content flashing. The page renders one version, then JavaScript re-renders a different version, producing visible flicker.
- Layout shifts. Hydration changes the DOM in ways that move content, hurting CLS scores.
- Interactive elements that don’t work. Buttons render but don’t respond because hydration failed silently.
- Different content for crawlers and users. The HTML response contains one version; the post-hydration DOM contains another. Search Console may show one set of content while users see another.
The diagnosis is browser-based. Open the page with JavaScript disabled in DevTools. Compare what’s visible to what shows when JavaScript runs. Significant differences indicate hydration mismatches, and the framework’s documentation has specific guidance for the pattern.
The fix is framework-specific but follows a pattern. Ensure the server-rendered output and the client-rendered output are byte-identical for the parts that affect SEO (content, metadata, links). Differences in non-SEO elements (analytics tags, A/B test variants applied after hydration) are usually acceptable.
Streaming SSR and the islands architecture:
The traditional SSR-then-hydrate pattern has a TTFB cost: the server has to render the full HTML before sending anything. Streaming SSR addresses this by sending HTML in chunks as it’s generated, with Suspense boundaries marking the parts that can stream independently. React’s renderToPipeableStream, Next.js App Router, and Remix all support this pattern.
For SEO purposes, streaming SSR matters because it produces faster TTFB without sacrificing initial HTML content. Googlebot receives the same indexable HTML; the user receives meaningful content sooner. The catch: content that streams in after Suspense boundaries may or may not be in the HTML when Googlebot captures it, depending on how Google handles partial responses. The practical guidance is to ensure that SEO-critical content (headings, body copy, meta tags) is in the initial HTML shell, with non-critical content (related products, recommendations, comments) streaming after.
Islands architecture (Astro, Fresh, Qwik) takes a different approach. Most of the page renders as static HTML at build time; only specific interactive components hydrate client-side. The hydration boundary is per-component (the “island”) rather than per-page. The SEO advantage is that the static parts are always in the initial HTML response with no JavaScript execution required for indexing.
The framework landscape in 2026:
- Next.js App Router uses React Server Components by default; the HTML rendered on the server includes the full content, with client components hydrating on the client. SEO-friendly out of the box for most patterns.
- Remix uses server-rendered routes with progressive enhancement. Initial HTML is complete; JavaScript adds interactivity but isn’t required for content to display.
- Astro generates static HTML with optional islands. SEO-friendly by default because most content ships as HTML, not JavaScript.
- Qwik uses resumability instead of hydration. The framework serializes execution state into HTML and resumes on client interaction. For Googlebot, the experience is similar to static HTML.
- SvelteKit with SSR enabled produces server-rendered HTML similar to Next.js patterns. Without SSR (SPA mode), it has the CSR problems described above.
The framework choice still matters more than any individual optimization. A site built on Astro or Next.js App Router rarely has the rendering problems that CSR SPAs produce. A site that picks the wrong framework spends years working around it.
The patterns that consistently work:
Five practices recur across sites that handle JavaScript rendering successfully:
- SSR or SSG for primary content. The page’s title, meta description, body text, structured data, and primary navigation come from the server. JavaScript adds interactivity, not foundational content.
- Critical content above the fold in the initial HTML. Even with hybrid patterns, the content that appears immediately on page load should be in the HTML response, not added after hydration.
- Internal links as standard HTML anchor tags. When navigation depends on JavaScript-injected links, crawl discovery slows. Plain anchor tags with href attributes get discovered immediately, even when JavaScript adds enhanced behavior.
- Resources that aren’t blocked by robots.txt. JavaScript files, CSS files, and API endpoints used by rendering must be crawlable. Blocking them blocks rendering.
- Testing with rendered HTML comparison. Tools like Google’s Rich Results Test or Mobile-Friendly Test show what Google sees after rendering. Comparison with the source HTML reveals what depends on JavaScript and confirms whether the rendering produces the expected result.
The pattern across all of these: trust the server for what matters to SEO, use JavaScript for what improves the user experience after the initial load.
What to do with existing CSR sites:
Migration paths vary by framework and codebase. Four options recur, in descending order of effort:
- Convert to a hybrid framework. React applications migrate to Next.js. Vue applications migrate to Nuxt. The migration is non-trivial but produces lasting benefits and rarely needs revisiting.
- Add dynamic rendering as a bridge. The server detects search crawler user agents and serves pre-rendered HTML to them while serving the standard CSR experience to users. Google’s documentation describes this as a workaround rather than a recommendation, but it works when full framework migration isn’t feasible. Prerender.io and Rendertron handle the implementation.
- Pre-render the high-value pages only. The homepage, category pages, and product pages get pre-rendered or moved to SSR, while the long tail of tertiary pages stays on CSR. The cost-benefit favors migrating high-value pages first and leaving the rest until the impact justifies more work.
- Accept CSR for the application, surface SEO elsewhere. When SEO isn’t a priority for the application itself, search visibility lives on the marketing pages, the blog, and the help center, all of which render server-side. The application stays CSR.
Framework choice as foundational SEO:
JavaScript framework choice has become a foundational SEO decision. Sites that pick frameworks with strong SSR/SSG defaults get the performance and indexability benefits by default. Sites that pick pure CSR frameworks pay the cost in slower indexation, weaker rankings for new content, and degraded social previews.
For new sites, the decision is the framework selection itself. The frameworks that handle SEO well in 2026 (Next.js, Nuxt, Astro, Remix, SvelteKit) all default to hybrid patterns. Picking one of them produces SEO-friendly output without explicit SEO work.
For existing CSR sites, the question is whether the SEO cost of staying on CSR exceeds the engineering cost of migration. The answer varies by traffic profile, by the importance of organic search to the business, and by the size of the codebase. The decision is rarely about whether JavaScript SEO is technically possible; the decision is about whether the operational overhead of working around JavaScript SEO limitations exceeds the migration cost.
The sites that handle JavaScript SEO well treat the rendering decision as architectural, not as a fix-it-later concern. The cost of getting it right at the framework level is far smaller than the cost of patching it after the site is deployed.
The business case is measurable. Sites that migrate from CSR to hybrid frameworks typically see organic traffic recovery in 3-6 months, with new-content indexation latency dropping from days to hours. The engineering cost (rebuild of routing layer, refactor of data-fetching patterns) ranges from $200K to $2M depending on codebase size; the cost of leaving CSR in place compounds annually as content velocity grows.