Most quotes give you one number. Here is what sits inside it.

You ask three people what it costs to move your WordPress site to Next.js and you get three figures with nothing behind them. One says two thousand. One says nine. Neither explains the gap, so you end up picking on gut feel or on price alone.

I quote fixed prices per project, which means I have to break the work down before I can put a number on it. This is that breakdown.

What drives the number

People assume the price tracks page count. It mostly does not.

A blog with six hundred posts that all share one layout is a cheap migration. You build one template, write one loop, and the six hundredth post costs nothing more than the second. A forty page brochure site where every page was laid out by hand in a page builder is expensive, because forty pages means forty layout decisions somebody has to rebuild and check.

Five things actually move the figure:

  1. 01Distinct templates. How many genuinely different page layouts exist. This is the single biggest driver.
  2. 02Custom post types and fields. Each one needs mapping, querying and rendering. Advanced Custom Fields sprawl is where estimates go wrong.
  3. 03Indexed URL count. Not page count. How many URLs Google currently knows about, because every one of them needs a destination.
  4. 04Integrations. Forms, search, comments, memberships, payment, newsletter, analytics. Each is a small job that adds up fast.
  5. 05Plugin dependencies. Anything doing real work rather than styling has to be replaced with code.

Before anyone quotes you, get those five numbers. You can pull most of them yourself in ten minutes.

terminalbash
# How many published items, by post type. This tells you scale.wp post list --post_status=publish --format=count --post_type=postwp post list --post_status=publish --format=count --post_type=page # Every registered post type, including the custom ones a plugin addedwp post-type list --fields=name,label,public # Active plugins. The list you hand to a developer.wp plugin list --status=active --fields=name,version # How many distinct page templates the theme actually offersls -1 wp-content/themes/$(wp theme list --status=active --field=name)/*.php | wc -l

No WP-CLI access? The sitemap gives you the URL count, which is the number that matters most for the routing work.

terminalbash
# Total URLs across every sitemap, which is what the redirect map has to covercurl -s https://example.com/wp-sitemap.xml \  | grep -oE '<loc>[^<]+</loc>' \  | sed 's/<[^>]*>//g' \  | while read -r map; do curl -s "$map" | grep -c '<loc>'; done \  | paste -sd+ - | bc

The nine line items

Every migration I have run breaks into the same nine pieces. The proportions shift. The list does not.

1. URL audit and inventory

Pull every indexed URL from the sitemap, Search Console and the server logs, then reconcile the three lists. Server logs catch the URLs that still earn traffic but fell out of your sitemap years ago, which is exactly the set people forget.

Small job, and skipping it is how migrations lose traffic.

2. Redirect map

Old path to new path, for every URL from step one, then an automated pass that confirms each one lands on a 200 rather than a 404 or a chain. This is the work that protects your rankings, and it scales with URL count rather than template count.

3. Template build

The largest single item. One React component per distinct layout, matching the existing design unless you are redesigning at the same time, which I would advise against doing in the same project.

4. Content migration

Getting the posts, pages, media and taxonomies across. Cheap if you are running WordPress headless, because the content stays where it is and Next.js reads it over the API. Expensive if you are exporting into a different CMS, because WordPress HTML carries shortcodes, block comments and inline styles that all need cleaning.

5. Metadata and schema

Titles, descriptions, canonicals, robots rules, Open Graph images and the JSON-LD your SEO plugin was emitting. This one gets dropped from quotes constantly and then costs you rankings quietly over the following weeks.

6. Integrations

Contact forms, site search, analytics, newsletter signup, comments. Each looks trivial and each takes half a day once you include testing that the submission actually arrives.

7. Performance pass

Image handling, font loading, layout stability and the render strategy per route. Doing it during the build is much cheaper than bolting it on after launch.

8. Testing and QA

Redirect verification, metadata diffing against the live site, cross browser checks, and a real pass on a mid range phone rather than a desktop pretending to be one.

9. Deploy, documentation and handover

Environment variables, the deploy pipeline, a readme that gets a new developer running, and a recorded walkthrough. Small line, and the one that decides whether you are stuck with whoever built it.

Where the effort goes

20%15%13%11%10%9%8%10%Template build20%Content migration15%Routing and redirects13%Metadata and schema11%Integrations10%Performance pass9%Testing and QA8%Contingency10%Deploy and handover4%
How I split effort on a typical content site migration. These are my own working proportions for scoping, not an industry measurement, and they move with the site. A headless build shifts weight off content migration. A site with many layouts pushes template build well past twenty percent.

Two things worth pulling out of that. Routing and metadata together come to twenty four percent, and they are the two items with no visible output. Nobody looks at a finished site and sees the redirect map. Cut them and the site still launches, still looks right, and quietly bleeds traffic for a quarter.

The contingency line is real work, not padding. Something always turns up: a plugin doing something undocumented, a content pattern nobody mentioned, a redirect loop from an old migration. Quotes with no contingency become change requests later.

Three worked examples

Same nine items, three different sites. The shape of the work changes more than the total.

Brochure siteContent siteHeadless content site
Indexed URLsAround 30Around 400Around 400
Distinct templates6 to 85 to 65 to 6
Heaviest line itemTemplate buildRedirect mapTemplate build
Content migrationManual, quickScripted exportNone, stays in WordPress
Editor workflowUsually droppedUsually droppedUnchanged
Extra workNoneNoneWebhook, preview mode, CMS lockdown
Typical span1 to 2 weeks2 to 5 weeks3 to 6 weeks
The headless column costs more than the middle column and removes the retraining problem, because your team keeps the WordPress admin. That trade is worth it when people publish weekly. It is not worth it when they publish twice a year.

Notice the brochure site has more templates than the content site despite having a fraction of the pages. That is the template point again, and it is why a small site can quote higher than a big one.

What inflates a quote

Four things reliably push the number up. Three of them are worth knowing before you ask.

  • WooCommerce. Headless commerce is a different project with a different budget. Cart, checkout, payment, tax, stock and order history all have to work perfectly on day one. Often the honest answer is to leave the shop on WordPress.
  • Page builders. Elementor and Divi store layout as theme specific markup. None of it travels. Every page laid out in a builder is a page somebody rebuilds by hand, which turns page count back into the main cost driver.
  • Custom field sprawl. Forty Advanced Custom Fields groups across twelve post types is a mapping exercise before it is a build.
  • No agreed design. If the migration is also a redesign, you are paying for two projects and the review cycles multiply. Migrate first, redesign after.

What you can safely cut

If the quote is over budget, some of it is genuinely optional.

Thin archive pages usually are. Tag archives, author pages and date archives that Yoast already marked noindex do not need rebuilding. Delete them and redirect the handful with links pointing at them.

Old content is another. If four hundred posts include a hundred and fifty that have had no traffic in two years, migrating them costs money and earns nothing. Redirect them to the closest relevant page and cut the scope.

Comments, if nobody has left one since 2021. Site search, if your analytics say almost nobody uses it.

What I would not cut, at any budget:

  • The redirect map. This is the whole reason a migration is risky.
  • Metadata and schema. Invisible until your rankings move.
  • Testing on a real phone. Most of your traffic is on one.
  • Documentation and handover. Cutting it saves days and costs you your independence.

Quotes that should worry you

Whoever you hire, including me, apply the same test. A quote should tell you what you are buying.

  1. 01One number and no line items. If nobody will break it down, nobody has thought it through, and the change requests are coming.
  2. 02No mention of redirects. The most important item in the project. Its absence tells you the quote is about building a website, not moving one.
  3. 03A number given before anyone looked at the site. Reasonable to give a range on a call. Not reasonable to commit to a fixed price without an audit.
  4. 04No contingency and no change process. Both of you will need one. Better to agree it now than to argue in week four.
  5. 05Nobody asks who owns the repository. Ask early. The answer should be you.
Related readingHow long a WordPress to Next.js migration actually takes

Cost and schedule move together, because most of the price is somebody's time. If the quote and the timeline do not agree with each other, one of them is wrong.

Before you commission anything, run the checks. They will tell you whether the person quoting knows what the job involves.

Related readingA WordPress to Next.js migration checklist you can hand to a developer

I do this work. Send me the URL and you will get the line items and a fixed number back, or an honest recommendation to stay on WordPress and make it faster instead, which happens more often than you might expect. The migration page covers how it runs, and the contact form is the fastest way to start.

Resources