Next.js migrations fail in small, expensive ways: old slugs redirect badly, dynamic routes return empty states, metadata goes missing, or client-side navigation breaks after the first render. A migration QA pass should test the site like a user and like a search crawler.
Redirect map smoke test
A simple redirect map check catches many migration mistakes before a crawler ever runs.
const redirects = [
["/old-pricing", "/pricing"],
["/blog/legacy-post", "/blog/new-post"]
];
for (const [from, expected] of redirects) {
const res = await fetch("https://example.com" + from, { redirect: "manual" });
const location = res.headers.get("location");
console.log(from, res.status, location === expected ? "ok" : `expected ${expected}`);
}Migration QA Evidence
Before launch
- export the old URL set from analytics, sitemap, CMS, or crawl data
- map old URLs to new destinations and decide which should be gone
- check canonicals, robots, sitemap output, and noindex rules
- crawl staging with JavaScript rendering if important routes hydrate after load
During QA
Treat soft 404s as their own class. A migrated page that returns 200 but renders a missing-content shell can be more confusing than a clean 404 because it slips through status-only checks.
For app-like Next.js surfaces, also inspect API failures and client-side navigation failures because those often explain pages that look fine at first response.
After launch
- re-run the crawl against production
- compare broken-page counts against the staging run
- inspect Search Console for indexing and redirect surprises
- schedule a follow-up scan after the first content update