--- title: "JavaScript Rendering for SaaS: SSR, SSG, and the Empty-Shell Bug" description: "Why a SaaS marketing page can render perfectly in Chrome and still be invisible to Google — and the SSR/SSG decisions that close the gap." url: "https://serpnaut.xyz/playbook/technical-seo-for-saas/rendering-for-saas" verifiedAt: "2026-06-09" canonical: "https://serpnaut.xyz/playbook/technical-seo-for-saas/rendering-for-saas" --- # JavaScript Rendering for SaaS: SSR, SSG, and the Empty-Shell Bug > TL;DR — Googlebot renders JavaScript, but with a delay and a budget — and on commercial templates (pricing, comparison, feature pages) the delay is enough to silently break indexation. SSR or SSG those templates; CSR is acceptable only behind a login wall. The single most common SaaS rendering bug is a Next.js or Vite app that ships marketing pages as 'use client' by default. In plain English: Rendering for SaaS is the template-level decision of whether each marketing URL is server-rendered, static-generated, or client-rendered. SSR or SSG is required for commercial templates because Googlebot's two-pass JavaScript rendering introduces delay and failure modes that CSR pages cannot reliably survive. ## Key takeaways - Googlebot renders JavaScript in a deferred second pass — never assume parity with what Chrome shows. - Server-render or static-generate every marketing template; reserve client-side rendering for authenticated app surfaces. - URL Inspection → View tested page → Rendered HTML is the only reliable verification of what Google sees. - Hydration mismatches in Next.js / Remix / Vite leak server HTML and client HTML disagreements straight into Google's index. - Third-party scripts (chat widgets, A/B tools) that mutate the DOM before Googlebot's render budget expires are a top cause of empty-shell bugs. ## Definition Rendering for SaaS is the decision of where each marketing URL's HTML is generated — server-side at request time (SSR), at build time (SSG), or in the browser after fetch (CSR) — and the consequences each choice has for indexation and ranking. ## Why it matters A SaaS pricing page that renders correctly in Chrome and loads in 1.2s on a fast laptop can be silently invisible to Google. The cause is almost always rendering: 'use client' applied as the framework default, hydration that depends on a network fetch, or a third-party script that overwrites content after Googlebot's render budget expires. Fixing the rendering decision once at the template level usually moves more pages out of 'Crawled — not indexed' than a quarter of content work does. ## Why Googlebot's two-pass render is the trap Googlebot processes pages in two passes: the initial HTML pass (immediate) and the JavaScript render pass (deferred, sometimes by days). The first pass is what indexes the page; the second pass updates what's indexed if it ever runs. Pages that rely on the JS pass for their H1, product copy, or CTA enter the index missing those elements — sometimes permanently. This is not a bug Google plans to fix. The render queue exists because rendering JavaScript at web scale is expensive, and it always will be. Treat the deferred render as an optimization tier, not a base case. ## Which pages to SSR/SSG (and which not to) The five SaaS templates that have to be SSR or SSG: home page, pricing page, comparison/alternative pages, feature pages, integration pages. These are the pages that earn ranking and that lose the most when rendering breaks. Blog and documentation: SSG is the default and the right choice — static, cacheable, fast. SSR is overkill unless you personalise content per-visitor. Authenticated app surfaces: CSR is fine and often preferable. Google doesn't index logged-in screens regardless of how they render, so render mode is purely a UX decision there. ## How to verify rendering for any URL Open Search Console → URL Inspection → enter the URL → 'Test live URL' → 'View tested page' → Rendered HTML tab. Read the actual HTML Googlebot constructed after its render pass. If the H1, product copy, pricing table, or CTA is missing, the page is broken for Google. Compare against the rendered HTML in Chrome DevTools (Elements panel). Differences between the two are the bugs — usually a script that runs in Chrome but times out in Googlebot's render environment, or content that mounts after a network fetch Googlebot didn't wait for. ## Hydration mismatches and third-party scripts Next.js / Remix / Vite warn loudly about hydration mismatches in development but ship them silently to production. A common SaaS pattern: the server renders the pricing table with a default currency, the client re-renders it with a geo-detected currency, and Googlebot indexes one version while users see another. Third-party scripts (Intercom, Drift, Optimizely, Hotjar) that mutate the DOM after page load are the most common cause of empty-shell bugs on otherwise well-built SaaS sites. Defer them past Googlebot's render window or load them conditionally on user interaction. ## Quick answers ### Can Googlebot render JavaScript on SaaS pages? (https://serpnaut.xyz/playbook/technical-seo-for-saas/rendering-for-saas#qa-googlebot-js) Yes, in a deferred second-pass render — but with a render budget and known failure modes. Pages that depend on JavaScript to insert the H1, product copy, or pricing table routinely lose those elements when Googlebot's render budget expires. SSR or SSG those templates; never rely on the JS pass for commercial copy. ### SSR or SSG for a SaaS marketing site — which should I pick? (https://serpnaut.xyz/playbook/technical-seo-for-saas/rendering-for-saas#qa-ssr-vs-ssg) SSG when the content rarely changes (homepage, feature pages, comparison pages) — fastest and cheapest. SSR when the page composes per-request data (logged-in state, geo pricing, A/B variants). Mixed in the same app is normal; Next.js, Remix, and Astro all support per-route choice. ### How do I verify Google sees the same HTML I see? (https://serpnaut.xyz/playbook/technical-seo-for-saas/rendering-for-saas#qa-verify-render) Open Search Console URL Inspection → enter the URL → 'Test live URL' → 'View tested page' → Rendered HTML tab. If the H1, product copy, or call-to-action is missing there, the page is broken for Google regardless of how it looks in Chrome. This is the only diagnostic that matters. ### Can I run my SaaS marketing site as a single-page React app? (https://serpnaut.xyz/playbook/technical-seo-for-saas/rendering-for-saas#qa-spa-marketing) Technically yes; in practice it consistently underperforms a server-rendered equivalent. SPAs leak indexation issues that compound: missing H1s after hydration, scripts that fail under Googlebot's CPU constraints, third-party widgets that overwrite content after render. If you're starting fresh, choose Next.js, Astro, Remix, or TanStack Start — not a Vite SPA — for the marketing site.