How We Made Our React SPA Rank on Google
SPAs and SEO don’t mix — unless you pre-render. Here’s how we added static HTML generation to a Vite + React site in 30 minutes.
The SPA SEO problem
Single-page applications render content with JavaScript. When a crawler (or someone sharing your link on LinkedIn) hits your URL, they get an empty div. Google can execute JS, but it’s slower to index, and social platforms don’t run JS at all — your link previews are blank.
The options
You can solve this three ways: 1) Move to a framework with SSR (Next.js, Remix) — big rewrite. 2) Use a prerender service (prerender.io) — monthly cost, third-party dependency. 3) Pre-render at build time — free, fast, zero runtime cost.
Our approach: build-time pre-rendering
We wrote a simple Puppeteer script that runs after `vite build`. It spins up a local server, navigates to each route, waits for React to render, captures the full HTML, and writes it to the corresponding directory. 12 routes render in under 10 seconds.
What the crawler sees now
Before: `<div id="root"></div>`. After: fully rendered HTML with meta tags, headings, content, and structured data. The same HTML file also serves as the initial load for real users — React hydrates on top of it, so there’s no flash or layout shift.
The compounding SEO benefit
Pre-rendered pages index faster, generate better social previews, and have better Core Web Vitals (content is in the initial HTML, not waiting for JS). Over 6-12 months, this compounds into significantly better organic traffic than a JS-only SPA.
Cost: zero
This runs at build time. No server. No monthly subscription. No runtime compute. The output is static HTML files served from a CDN (Firebase Hosting in our case). It’s the highest ROI SEO improvement you can make on an existing SPA.