Migrating a React SPA to SSG: Why and How

You have shipped a React application that is fast, fluid and polished. Lighthouse Performance shows 95. And yet, three weeks later, Google Search Console flags Soft 404 on half of your routes. Your product pages, your articles, your services pages: indexed at a trickle, sometimes not at all. The issue is not your code, it is the rendering. A classic SPA serves a near-empty HTML document that Googlebot has to hydrate itself, with a limited and unpredictable JavaScript budget.
The good news: switching to Static Site Generation (SSG) does not require rebuilding the whole application. On three client projects migrated in early 2026, I kept the same Vite + React base and only added a pre-rendering step route by route. Here is the method and the pitfalls.
Why Googlebot ignores your React SPA
An SPA delivers an index.html file that essentially contains <div id="root"></div> and a JavaScript bundle. The actual content is injected on the client side after hydration. Googlebot can run JavaScript, but with a constrained and asynchronous budget: the page first goes through a render queue, sometimes for several days. If your TTFB or your bundle crosses certain thresholds, Google indexes the raw HTML, meaning nothing. The result: Soft 404, empty snippets in the search results, broken OpenGraph shares on LinkedIn and iMessage.
SSG reverses the logic. Each route is pre-rendered to full HTML at build time. Googlebot, Bingbot, social crawlers and RSS readers receive a document that is immediately readable, without running a single line of JavaScript. The client-side hydration step remains, preserving the usual React interactivity.
SSG without rebuilding the whole application
For an existing Vite + React project, vite-react-ssg is the most direct option. We keep the router, the components, the hooks, the Supabase calls. We simply replace the main.tsx entry point with a ViteReactSSG export that lists the routes to pre-render, and replace in package.json the vite build script with vite-react-ssg build. The rest of the application code does not move.
At build time, each route generates a folder with its own index.html: dist/contact/index.html, dist/portfolio/z-depannage/index.html, and so on. On the Vercel side, we set cleanUrls: true in vercel.json and remove any SPA rewrite rule that would forward everything to index.html, otherwise the pre-rendering is masked.
vite-react-ssg vs Next.js vs Astro: which to choose
vite-react-ssg is the right choice when the codebase already runs on Vite + React and you just want to add the pre-rendering step. Migration in one day on a medium-sized project, zero rewrite of the business code.
Next.js is a full framework with its own router, its conventions and its App Router. Excellent for a new project, but a migration from Vite means rewriting the routing, the layouts, the file conventions and often the authentication. Several days to several weeks depending on size.
Astro shines on purely editorial sites (blogs, docs, landing pages). On a React-heavy interactive application, its islands model forces the interface to be split into isolated components hydrated on demand, which complicates global state sharing.
Post-migration validation checklist
Three non-negotiable checks after each build. First, the dist/ folder must contain one index.html per route, and each file must weigh several kilobytes, not just the SPA shell. Second, open one of these HTML files and confirm the presence of data-server-rendered="true" on the root element, along with full semantic sections (main, article, section) containing the real text. Third, validate via curl or the Google Search Console inspector that the version served in production matches the pre-rendered HTML.
Three recurring pitfalls. The manifest-undefined bug in vite-react-ssg breaks the 404 pages for SEO: simple workaround, create an empty public/static-loader-data-manifest-undefined.json file containing {}. The script-src CSP directive must keep 'unsafe-inline' because hydration injects mandatory inline scripts. Finally, double-check that the build script in package.json is indeed vite-react-ssg build and not vite build, otherwise Vercel deploys a CSR version without anyone noticing.
Results across 3 sites
Three migrations delivered: Z-Dépannage and Milena Glow Up, plus a personal portfolio. Lighthouse scores moved from 60-70 to 95-100 across all four categories. Google indexation time divided by five: from 1-4 weeks to 3-7 days on average, measured in Search Console. Reliable OpenGraph on every social share, correct snippets in the search results, no Soft 404 flagged anymore.
If your React project is starting to receive organic traffic and your indexation metrics are stalling, SSG via vite-react-ssg is probably the lever with the best effort-to-impact ratio. A few hours of integration, lasting gains on ranking and on perceived performance. For an audit or migration support, the contact page remains the most direct entry point.
Articles liés
Développeur web freelance à Morsang-sur-Orge et en Essonne (91)
Pourquoi choisir un freelance local plutôt qu'une agence parisienne, mes services pour les PME de l'Essonne, communes couvertes, projets 2026 et tarifs transparents.
Création de site vitrine PME avec React + Vite : standards 2026
Pourquoi React + Vite + SSG bat WordPress sur la performance, la sécurité et le coût d'hébergement, avec deux études de cas Clad-Primeco et Milena Glow Up.