Moving a WordPress site to Next.js without losing a URL
We rebuilt zylpe.com from an Elementor page builder into a Next.js application with every public address intact. The method is a pipeline, not a copy-and-paste, and most of the work is in deciding what the old site actually contained.
By AMTEX Consulting · Editorial
A WordPress site built with a page builder is not a set of pages. It is a database of builder sections, a theme, a dozen plugins and years of accumulated URLs, some of which the owner has forgotten exist. Migrating it to a modern framework while preserving search rankings means preserving all of that, deliberately. Here is the sequence we used for zylpe.com, which we think generalises.
Start from the sitemaps, then crawl anyway
The XML sitemaps are the index search engines actually hold, so they define the URL set you must preserve. They also expose the surprises: on this site, dozens of theme demo URLs for products and projects had been indexed for years. Crawl every URL with browser-like headers (shared hosts frequently refuse plain scripts), store the HTML, and record title, meta description and canonical for each. That table is your acceptance test.
Classify sections into a typed content model
Page builders emit a section, column and widget hierarchy with predictable widget types: heading, text, image, image box, icon list, counter, button, form. Write a classifier that turns each builder section into one of a small set of typed sections you intend to render, carrying headings, paragraphs, lists, images, labels and calls to action. The output is a content file. From that point the migration is a rendering problem, and the later redesign is a rendering change.
Read the CSS, not just the HTML
Backgrounds, overlays and image widths live in the builder's generated per-page CSS, keyed by widget id. Two things bit us. Caching plugins replace image sources with a blank placeholder and keep the real file in a data attribute, so a naive scrape downloads nothing. And a 500-pixel icon shown at a quarter of its column width looks right on the live site only because of a width rule; render it at natural size and it fills the column. Join widget id to image to width rule and carry the width into the content.
Decide the fate of every URL
- Real pages: same path, same trailing slash policy, same title format.
- Media that is linked (PDFs): keep working at a documents path with a permanent redirect from the old uploads path.
- Theme demo URLs: permanent redirect to the home page, or a 410 if you prefer to tell search engines they are gone. Make it a decision, not an accident.
- Legacy sitemaps and feeds: redirect to the new sitemap or home.
Verify parity mechanically
Run the acceptance table against the new site: every URL returns 200, every title matches, redirects return 308 to the intended target, the sitemap lists the same URLs, and no page references the old host for any asset. Looking at pages is useful; it is not verification.
Cut over the web records only
The domain's DNS zone also carries the organisation's email: MX, SPF, DKIM and DMARC records. The cutover changes exactly two records, the apex address and the www alias, and the plan names the records that must not be touched. Export the zone first. Keep the old host for thirty days as the rollback. If the nameservers themselves live at the old host, move DNS to a neutral provider before cancelling anything.
- nextjs
- wordpress
- migration
- seo