DEV Community

Cover image for WordPress to Next.js Migration: A Practical Checklist for Agencies
TheBitForge
TheBitForge

Posted on

WordPress to Next.js Migration: A Practical Checklist for Agencies

Somewhere around plugin number fourteen, every WordPress site starts to feel the same. Page builder shortcodes stacked on top of a theme that's stacked on top of a child theme nobody remembers creating. Load times creeping up every quarter. A client who wants "the site to feel modern, like [competitor]'s site" without quite being able to articulate what "modern" actually means. And at some point, someone on the team says the word "headless," and suddenly you're being asked whether it's worth migrating to Next.js.

Here's the thing most guides skip: the actual framework swap is the easy part. Copying a hero section from WordPress into a React component takes an afternoon. What actually sinks these migrations, and what turns a "quick refresh" into a three-month fire drill, is everything sitting underneath the visible page: URLs, SEO signals, editorial workflow, and content that was never structured cleanly in the first place. This is the checklist that actually matters, in the order it actually matters.

Step one: decide what WordPress's role even is going forward

Before touching a single line of code, answer one question honestly: is WordPress staying as the CMS, or is it getting replaced entirely?

There are genuinely three valid paths here, and picking the wrong one for your client's situation is the single most common reason these projects go sideways.

Keep WordPress as a headless CMS. Editors keep using the Gutenberg editor they already know, content still lives in WordPress, but the frontend rendering gets replaced entirely by Next.js pulling data through the REST API or WPGraphQL. This is the lowest-risk path when your client's team already knows WordPress and doesn't want to relearn a new content interface. It's also the fastest to ship, because you're not migrating content anywhere, just changing how it gets rendered.

Replace WordPress with a dedicated headless CMS. Sanity, Payload, Contentful, Strapi, pick based on content complexity and team skills rather than whichever one has the flashiest marketing site. This path makes sense when WordPress itself is the bottleneck, not just the theme, usually because the content model has outgrown what posts-and-pages can reasonably express.

Run both in parallel during transition, then retire WordPress. Sometimes the safest real-world path is standing up Next.js against WordPress's existing API first, proving it out on a handful of pages, and only fully cutting over once you trust the new system in production.

Whichever path you pick, write it down and get the client to sign off on it explicitly. Half the scope creep in these projects comes from someone assuming WordPress is "just going away" when actually the plan was to keep it as a CMS the whole time.

Step two: inventory everything, not just the obvious pages

This is the step agencies skip and then pay for later. It's tempting to treat "migrate the content" as "export posts and pages," but real WordPress sites hide a surprising amount of commercially important content in places that don't show up in a basic export: custom post types, ACF fields, widget areas, menu structures, and content buried inside page builder shortcodes that don't translate cleanly into anything.

Before you write a single component, actually go through:

  • Every custom post type, not just the default posts and pages. Portfolios, testimonials, team members, whatever the client's theme or a plugin quietly registered along the way.
  • Custom fields, especially anything built with ACF or similar plugins, since those often carry structured data the visible page depends on.
  • Media library assets, exported separately from content, since WordPress's default export tool (Tools > Export, generating a WXR file) covers posts, pages, categories, tags, and authors, but media files need their own handling.
  • Menu structures and widget areas, which often carry navigation logic that isn't obvious from looking at the rendered site.
  • Shortcode-based content, which is the single biggest headache in these migrations. Page builder content doesn't export cleanly, and there's rarely a clean automated path from "Elementor shortcode soup" to structured content blocks. Budget real time for manually rebuilding these pages rather than assuming a script will handle it.

If you skip this step and start building based on what you can see on the live site, you will find missing content halfway through, and it's always at the worst possible time.

Step three: map every URL before you touch SEO

This is the part that determines whether the migration protects the client's search rankings or quietly torches years of SEO work in a single launch weekend. It happens more often than anyone wants to admit, and it's almost always avoidable.

Every single WordPress URL needs a mapped destination in the new site, and every one of those mappings needs a permanent (301) redirect. Not "most of them." Every one, including the obscure blog post from four years ago that still ranks for some long-tail keyword nobody on the current team even knows about.

Before launch:

  1. Pull a full URL list from Search Console, your sitemap, and a proper crawl (don't rely on just one source, they'll disagree in ways that matter).
  2. Establish crawl and rendering baselines so you have something to compare against after launch if traffic drops.
  3. Map old URL to new URL, explicitly, even when the URL structure is staying identical, because "staying identical" is exactly the kind of assumption that breaks on trailing slashes or query parameters nobody thought to check.
  4. Rebuild metadata from actual page requirements, not from whatever your old SEO plugin auto-generated. Yoast and similar plugins handled a lot of this invisibly in WordPress. In a headless setup, you own every meta tag, and there's no plugin quietly filling gaps for you anymore.
  5. Rebuild schema markup deliberately, since structured data doesn't survive a framework swap automatically, and losing it silently degrades how the site shows up in search results without throwing any obvious error.

One technical detail that trips up a lot of Next.js migrations specifically: Google can render JavaScript, but it does so in a deferred rendering queue, and for SEO-critical pages that delay costs you time you don't have during a fragile post-launch window. Static generation or incremental static regeneration is the safer default for anything that needs to rank, blog posts, landing pages, product pages, reserving client-side rendering for authenticated or highly dynamic sections that don't need to be indexed at all.

Step four: don't forget preview, because editors will notice immediately

This is the detail that gets cut when timelines get tight, and it's the one that causes the most friction with the client's actual content team after launch.

In WordPress, editors are used to hitting "preview" and seeing exactly what a post will look like before publishing. In a headless setup, that experience doesn't exist by default, you have to build it, usually through a draft mode that lets the Next.js frontend render unpublished content from the CMS. Skip this and your client's marketing team ends up publishing directly to production just to see how something looks, which is exactly the kind of workflow regression that makes a technically successful migration feel like a downgrade to the people who actually use the site daily.

Treat preview as part of the migration's core scope, not a nice-to-have you'll get to if there's time left. There usually isn't.

Step five: launch with monitoring, not hope

The migration isn't done when the new site goes live, it's done a few weeks later, once you've confirmed the things that were supposed to survive the transition actually did.

  • Watch Search Console daily for the first couple of weeks, specifically for crawl errors and sudden indexing drops, which show up faster there than in traffic numbers.
  • Compare rendered HTML against your pre-migration baseline for the pages that matter most commercially, to catch cases where content technically migrated but isn't rendering the way you expect.
  • Keep a rollback plan ready, genuinely ready, not theoretical, for at least the first couple of weeks post-launch. If something's badly broken, the client needs to know you can revert quickly, not that you'll "look into it."
  • Submit a fresh sitemap to Search Console immediately after launch and verify every priority page is actually included, rather than assuming the sitemap generation caught everything on its own.

The part nobody wants to hear

None of this is glamorous. None of it is the part of the migration that gets screenshotted for a portfolio. But this is the actual difference between a WordPress to Next.js migration that makes a client's site meaningfully faster and more maintainable, and one that quietly loses two years of organic search rankings while everyone's celebrating how much nicer the new hero animation looks.

The framework is genuinely the easy part. Treat it that way, and put the real planning time where it actually belongs: the content inventory, the URL mapping, and the editorial workflow the client's team depends on every single day.


If you've run one of these migrations, what actually broke that you didn't expect going in? The redirect mapping and the shortcode content always seem to be where the real time goes, curious if others are seeing the same pattern.

Read More

What Is Digital Marketing? A Complete Beginner's Guide — TopBlogs

A plain-English breakdown of what digital marketing actually is, the channels that make it up, and where to start if you're completely new to the field.

favicon topblogs.online

Top comments (0)