Migration playbook
SSR to SSG migration on Next.js
A guide for Next.js teams whose SSR is overkill for the route shape — content rarely changes, the user-facing data is largely static, and SSR is paying for freshness the site does not need. The migration removes the SSR origin from the critical rendering path while preserving canonical URLs, sitemap structure, and indexation status.
Pre-flight
Before kickoff
- Inventory routes by rendering model: which are truly dynamic per request, which are mostly static.
- Confirm that data fetching can move to build time (or ISR) without losing freshness SLAs.
- Audit current canonical and metadata generation — verify they work in static context.
- Snapshot Search Console "Page indexing" report as the migration baseline.
- Plan ISR for routes that are mostly static but need refresh windows shorter than rebuild cadence.
If things break
Rollback plan
- Vercel Instant Rollback to previous deployment is the fastest revert path.
- If routing logic was changed alongside, prepare a feature flag that toggles back to SSR per-template instead of full-site revert.
- Keep the SSR codebase deployable for 30 days post-migration in case a deeper issue surfaces.
Steps
Sequenced execution
Step 1
Migrate top 5 templates to generateStaticParams
Start with the highest-traffic, lowest-volatility route templates. Convert one template at a time, verify static output matches SSR output for a sample of URLs.
Step 2
Wire ISR fallback for high-volume templates
For category or product pages with 10k+ URLs, use ISR with an appropriate TTL (typically 60-3600 seconds) instead of forcing build-time generation.
Step 3
Verify canonical and structured-data parity
Run curl against 50+ representative URLs in both SSR (current) and SSG (target) modes. Diff the canonical, OG tags, and JSON-LD output. They must match.
Step 4
Update sitemap generation to read from static manifest
If sitemap was generated dynamically from the SSR origin, port it to read from generateStaticParams output. Verify all post-migration URLs are present.
Step 5
Stage on a preview deployment
Deploy SSG version to a Vercel preview or staging subdomain. Submit a small subset to Search Console URL Inspection. Confirm crawler-facing HTML matches SSR baseline.
Step 6
Cutover with monitoring
Deploy to production. Monitor first 24-48 hours for Search Console errors, crawl-rate changes, and 404 spikes from any URL drift.
Expected metrics
Concrete expectations
- Expected downtime
- < 5 min (instant rollback)
- Typical rollback time
- < 2 min
- Time to first verified indexation
- 7-14 days
- Typical TTFB improvement
- 200-800 ms → 30-100 ms
After cutover
Monitoring discipline
- Search Console Page indexing report — daily for 14 days, weekly for 60 days after.
- Crawl-rate trend in Search Console settings — flag any 30%+ drop within a week.
- Sitemap submission status — confirm new sitemap is being read.
- Server logs (or CDN edge logs) for unexpected 404 spikes on previously-SSR URLs.
- Core Web Vitals field data via CrUX — expect LCP improvement, watch for any regression.
FAQ
Common questions
Will I lose indexation during the SSR → SSG cutover?
Not if canonical URLs, sitemap structure, and metadata stay identical between the SSR and SSG output. Diff the rendered HTML for 50+ representative URLs before cutover. Most teams see a temporary 5-10% drop in "Page indexing" counts within the first 7 days, recovering within 14-21 days.
What about routes that need fresh data?
Use ISR (Incremental Static Regeneration) with a TTL appropriate to the content (60-3600 seconds typical). ISR keeps the static-CDN delivery profile while allowing per-route revalidation without full rebuild.
How does this affect crawl budget?
Positively. CDN-served HTML responds in 30-100 ms vs SSR's 200-1500 ms. Googlebot adapts crawl rate to origin response time — sustained sub-100 ms responses usually increase crawl-rate ceiling within 30 days.
Can I migrate route-by-route or only all-at-once?
Route-by-route is strongly preferred. Convert one template at a time, verify static parity, then move to the next. All-at-once migrations have higher rollback complexity and concentrate risk into a single deploy.
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
SPA to prerendered architecture
Add a prerendering layer to a client-rendered SPA without rewriting it. The compromise that buys crawler reach without an SSR rebuild.
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.