Migration playbook
SPA to prerendered architecture
A guide for teams running a React, Vue, or Svelte SPA where rewriting to SSR is too costly but crawlers (especially AI crawlers) cannot see the content. Prerendering serves static HTML snapshots to bots, keeping the SPA architecture intact for users.
Pre-flight
Before kickoff
- Confirm the SPA is hitting real indexation problems (not just suspected ones) via Search Console URL Inspection.
- Decide on managed (Prerender.io, Rendertron) vs self-hosted prerendering — see the build-vs-buy analysis.
- Inventory routes that need prerendering vs routes that should remain SPA-only (auth-walled, etc.).
- Verify that current canonical, OG, and JSON-LD logic works at first paint, not after JS hydration.
- Plan bot-detection rules at the edge or at the origin proxy.
If things break
Rollback plan
- Disable bot routing at the edge — bots fall back to SPA origin (slow but functional).
- Keep bot detection toggleable per route family for partial rollback.
- Maintain prerender infrastructure even after rollback to avoid cold-start delays on re-enable.
Steps
Sequenced execution
Step 1
Set up prerendering infrastructure
Deploy the prerender service (managed account or self-hosted cluster). Verify it can render a sample route correctly.
Step 2
Wire bot detection at edge or proxy
Add user-agent based routing: verified bots (Googlebot, OAI-SearchBot, PerplexityBot, etc.) go to prerender; humans go to SPA origin. Use IP verification for compliance.
Step 3
Validate semantic parity
Diff SPA-rendered content vs prerendered HTML. Visible content must match — different markup is fine, different meaning is cloaking.
Step 4
Roll out per route family
Start with one route template (e.g., product pages). Verify Search Console picks up the new HTML over 7-14 days. Expand to more templates.
Step 5
Configure cache TTLs and invalidation
Set per-template cache TTLs based on freshness requirements. Wire invalidation hooks for content updates.
Expected metrics
Concrete expectations
- Expected downtime
- < 15 min (edge config flip)
- Typical rollback time
- < 5 min
- Time to first verified indexation
- 14-28 days
- Typical prerender cache hit ratio target
- > 85%
After cutover
Monitoring discipline
- Search Console Page indexing — expect indexation improvement within 14-28 days.
- Crawler hit rate in server logs — segment by verified bot user-agent.
- AI engine citation rate (manual sampling weekly) for branded and category queries.
- Prerender cache hit ratio — should stabilize above 85% for healthy operation.
- Origin load — bot traffic should be largely offloaded, freeing capacity.
FAQ
Common questions
Is prerendering for SPAs considered cloaking?
Not when implemented correctly. Compliant prerendering serves the same semantic content to bots and humans — only the delivery path differs (static snapshot vs JS render). Cloaking is when bots see materially different content. Match the rendered DOM between prerender output and runtime browser view to stay compliant.
Which bots should I route to the prerender?
At minimum: Googlebot, Bingbot, OAI-SearchBot, GPTBot, ClaudeBot, PerplexityBot, ChatGPT-User. Verify each via reverse DNS or published IP ranges to avoid impersonation. Avoid blanket User-Agent matching for non-bot traffic.
How long does prerendered HTML stay fresh?
Depends on content volatility. Editorial pages: 6-24 hours. Product/inventory: 5-30 minutes. Use shorter TTLs with on-publish cache invalidation triggered by your CMS. Set `stale-while-revalidate` so bots never wait for a cold render.
What if a page exists in the SPA but the prerender 404s?
Configure prerender to fall back to live SPA render with a 503 + Retry-After, never a 200 stub. Returning 200 for unrendered routes creates soft-404s that waste crawl budget.
Last updated:
Get this scoped to your stack
Generic playbooks are useful for orientation; the actual migration plan needs your routes, your CMS, your team capacity. The scoping call is 30 minutes — bring the constraints.
Other migration guides
SSR to SSG migration on Next.js
Move from server-rendered Next.js to fully static generation without losing SEO equity, with sane fallbacks for content that still needs freshness.
WordPress to headless CMS migration
Move from monolithic WordPress to a headless setup (WP-as-CMS + JS frontend, or full migration to Sanity/Contentful) without losing the SEO baseline.
Domain migration with SEO equity preservation
Move from one domain to another (rebrand, M&A, ccTLD consolidation) without losing rankings, indexation, or backlink equity.