6 September 2026
WordPress to Next.js Migration SEO: Keep Your Rankings

I have moved several live Belizean business sites off WordPress and onto Next.js, and the part clients worry about most is never the code. It is the traffic. WordPress to Next.js migration SEO is mostly an exercise in bookkeeping: every URL Google already knows about has to keep working, or resolve cleanly to something better. Get that wrong and you lose positions you spent years earning. Get it right and you keep the rankings and gain the speed.
This is the process I follow, written from real migrations for vehicle rental and real-estate businesses, not from theory.
Why do sites lose rankings when they leave WordPress?
Almost always for one of four reasons.
- URLs changed and nothing redirects the old ones. Google finds 404s where it used to find pages.
- Redirects were set as 302 (temporary) instead of 301 (permanent), so ranking signals never consolidate.
- Images, PDFs and other indexed assets were left behind when the media library was abandoned.
- Titles, meta descriptions, canonical tags and structured data were not carried across, because the old SEO plugin was doing that work invisibly.
None of these are hard problems. They are just easy to skip when the deadline is Friday and the new design looks good on a laptop.
Step one: crawl the old site before you change anything
Before I write a line of Next.js, I crawl the WordPress site and export a complete list of URLs. Not the ones in the menu. All of them: posts, pages, category archives, tag archives, author archives, paginated listings, attachment pages, feeds, uploaded files.
A WordPress site that looks like twenty pages in the admin will routinely expose several hundred addressable URLs once you count archives and pagination. Those are the ones that quietly hold links and impressions.
I cross-check the crawl against two other sources:
- Search Console, for pages that are actually indexed and receiving impressions.
- Server or analytics logs, for URLs that still get real traffic even if they are not linked anywhere.
The union of those three lists is the migration scope. Nothing outside it needs a redirect. Nothing inside it gets dropped.
Step two: map every URL to a destination
I keep the map as a plain spreadsheet, then a data file the app can read. Two columns to start: old path, new path. A third column for notes, because you will need it.
Rules I apply while mapping:
- One to one wherever possible. The closest equivalent page, not the home page.
- Never redirect everything to the root. That is treated as a soft 404 and it throws away the value of the page.
- Consolidate genuinely duplicate archives rather than recreating clutter in the new build.
- Decide deliberately about tag and author archives. If you keep them, redirect them. If you drop them, redirect them to the nearest useful listing.
- Leave a column for "no equivalent" pages and handle them consciously with a 410 or a redirect to a parent listing.
The map is the deliverable that protects the rankings. Everything else is implementation.
301 or 302, and does it matter?
It matters. A 301 tells search engines the move is permanent and that ranking signals should pass to the new address. A 302 says the old URL is coming back, so the original stays indexed and the new one struggles.
In a replatform, almost every redirect should be a 301. In Next.js I set them in next.config with permanent: true, or handle them in middleware when the logic needs to be dynamic. I test a sample with curl -I and read the status code myself rather than trusting the browser, because browsers cache redirects aggressively and will happily lie to you for the rest of the afternoon.
Step three: match URL conventions instead of inventing new ones
The cheapest way to preserve SEO in a WordPress to Next.js migration is to keep the URL structure you already have. If the old permalinks were /blog/post-title/, I build the new routes as /blog/post-title/, trailing slash and all. Trailing slash behaviour is configurable in Next.js and it is worth setting explicitly, because /about and /about/ are different URLs to a crawler.
Where the old structure was genuinely poor, I change it, but only with a redirect in place from day one. Improving a URL is fine. Improving it silently is not.
Step four: keep the indexed assets alive
WordPress serves uploads from /wp-content/uploads/. Those image paths sit in Google Image search, in social previews, and in third-party articles linking back to the site. When the CMS goes away, the paths often go with it.
I either preserve the same paths on the new host, or redirect them to the new asset locations. Same for any PDFs, price lists or brochures that were linked from elsewhere. This is the step most often forgotten, and it is the one that quietly costs image traffic.
Step five: rebuild metadata and structured data properly
An SEO plugin was doing a lot of work you cannot see. In Next.js I rebuild it explicitly:
- Titles and meta descriptions per route, generated from real content, not templated placeholders.
- Canonical tags on every page, absolute URLs, one per page.
- Open Graph and Twitter card data so shared links keep rendering correctly.
- JSON-LD structured data matching the business:
LocalBusinessdetails,ProductorOfferfor rental inventory,RealEstateListingor equivalent for property pages,BreadcrumbListfor navigation,Articlefor posts.
I then validate the output with the Rich Results Test before launch, not after. Structured data errors are cheap to fix in staging and irritating to fix in production.
Step six: sitemaps, robots and the staging trap
I generate the XML sitemap from the same source of truth as the routes, so it cannot drift. Only canonical, indexable URLs go in it. Redirected old URLs do not.
The staging trap catches people constantly: a noindex header or a blocking robots.txt used on the preview environment gets deployed to production. I check the live headers and robots.txt as the first action after the DNS switch, before anything else.
Step seven: verify in Search Console
After launch I watch Search Console for a few weeks rather than declaring victory on launch day.
- Submit the new sitemap and keep the old one available briefly so Google recrawls the old URLs and sees the 301s.
- Watch the Pages report for a rise in 404s. Every one is a gap in the redirect map.
- Use URL Inspection on the ten most valuable pages and confirm the canonical Google chose matches the one you declared.
- Compare Core Web Vitals before and after. This is usually where the good news is.
A short dip in impressions during recrawl is normal. A sustained drop means something in the map is wrong, and the map is where I look first.
Performance is part of the ranking story
The reason to move at all is usually speed and control. Static generation or incremental regeneration removes the plugin stack, the database round trip and the theme overhead. Pages render fast on the modest mobile connections that most of my clients' customers in Belize are actually using. That improves Core Web Vitals, and it improves conversions independently of rankings.
But speed does not rescue a broken redirect map. Do the boring part first.
Practical takeaway
If you remember five things:
- Crawl the old site and combine that list with Search Console and log data before you build.
- Map every URL to a specific destination, never a blanket redirect to the home page.
- Use 301, verify the status code yourself, and keep uploaded assets reachable.
- Rebuild titles, canonicals and structured data explicitly, because the plugin will not follow you.
- Verify in Search Console for several weeks and treat every new 404 as a bug.
I build and migrate this kind of site from Belmopan, mostly for businesses that need the site to keep earning while it changes underneath. If the rebuild is also the moment the business starts taking card payments online, plan that integration alongside the migration rather than after it. If you are planning a move off WordPress and want a second opinion on the redirect map before you commit, get in touch and I will take a look.