Reduce it to two questions
This comparison usually gets fought on benchmarks — Lighthouse scores, bundle sizes, hydration timings. Those matter at the margin. Two things matter much more, and both are answerable in an afternoon.
One: what does Googlebot receive in the first HTTP response? Not eventually. In the first response, before any JavaScript runs.
Two: how many developer hours does your marketer need to publish one page? Including the title, the meta description, the internal links and the schema.
Answer those two and the platform choice makes itself. Everything else is a preference about tooling, and preferences about tooling do not show up in Search Console.
What Googlebot receives on the first response
Google crawls in two passes. The crawler fetches the raw HTML and indexes what's there. Anything that only appears after JavaScript executes goes into a render queue, gets processed by a headless Chromium, and comes back for a second pass. Google says that queue is usually fast. Usually is doing a lot of work in that sentence, and you don't control it.
WordPress renders on the server. PHP assembles the page, the response contains the headline, the body, the links and the metadata. There is no second pass to wait for. That's the whole of WordPress's rendering advantage, and it's a real one.
Next.js can do exactly the same thing — better, in fact. App Router components are server components by default, and static generation produces HTML files that are already complete when the request arrives. A properly built Next.js site and a WordPress site are indistinguishable to a crawler.
Next.js gets into trouble when a team reaches for 'use client' everywhere, fetches the page's main content in a useEffect, and ships a shell containing a nav, a footer and a loading spinner. That page will still probably get indexed. It will get indexed late, its internal links won't be discovered on the first pass, and every crawler that doesn't execute JavaScript sees nothing.
How to check what Google actually gets — three ways, ten minutes
Don't take a developer's word for it, and don't take ours. Test it.
- `curl` the URL and read the response.
curl -s https://yoursite.com/page | grep -i "<h1". If your headline and body copy aren't in there, they aren't in the first response. This is the fastest and least arguable test there is. - Search Console URL Inspection. Run a live test, then open the HTML tab. That shows you what Google's renderer produced. Compare it against the
curloutput — the gap between the two is exactly what depends on JavaScript. - Disable JavaScript in Chrome DevTools and reload the page. Not a perfect simulation of Googlebot, but if the page is blank you have your answer in five seconds and you can stop reading.
Metadata, sitemaps and schema in each stack
This is where the effort difference shows up, and it's larger than most developers estimate.
| The job | WordPress | Next.js (App Router) |
|---|---|---|
| Title and meta description | A field under the editor. The person writing the page fills it in. | generateMetadata() in code, or a CMS field you built and wired up first. |
| Canonical tags | Handled by the SEO plugin, including paginated and parameterised URLs. | You set alternates.canonical yourself. Nobody catches the ones you miss. |
| XML sitemap | Generated and updated automatically on publish. | app/sitemap.ts — one file, fine to write, easy to forget to extend when a new route family appears. |
| Schema markup | Article, breadcrumb, FAQ and product schema out of the box from the plugin. | JSON-LD you write and maintain per template. More control, more surface to get wrong. |
| Redirects | A plugin with a UI. Marketing can add one. | next.config.js or middleware. A code change and a deploy. |
| Publishing a new page | Log in, write, publish. Live in minutes. | Branch, code or CMS entry, review, build, deploy — unless a CMS with revalidation is already in place. |
| Typical failure mode | Slow host, thirty plugins, a TTFB nobody measured. | A client-rendered template and a marketing team that can't change a title without a sprint. |
The developer dependency your marketing team inherits
Here's the uncomfortable part, and it's the reason most Next.js SEO programmes stall.
SEO is a high-frequency, low-ceremony activity. You rewrite a title because impressions are up and clicks aren't. You add four internal links because a cluster page is orphaned. You fix a canonical. You publish a page because a competitor published one. Individually these take four minutes.
On WordPress, four minutes is what they take. On a hand-rolled Next.js site with content in the repo, each one becomes a ticket, a branch, a review, a build and a deploy — and it queues behind the product roadmap, because it always does. The task didn't get harder. It got scheduled.
The compounding effect is what kills you. A content programme that ships four pages a month and fifty small fixes turns into one that ships four pages a month and no fixes, because nobody wants to file a ticket to change a meta description. Two quarters later the site is technically fast, architecturally clean, and rotting quietly — and it's a far more common way to lose than any rendering bug.
If your marketing team can't ship a page alone, the platform is wrong for SEO regardless of how good its Lighthouse score is.
When a headless CMS resolves both
You don't have to choose. The pattern that fixes both problems is Next.js for rendering with a real CMS behind it — Sanity, Payload, Contentful, or WordPress itself running headless and serving content over its REST or GraphQL API.
Content lives in an editor a marketer can use. Pages render on the server or get statically generated. On-demand revalidation republishes the affected route the moment something is saved, so publishing takes seconds and doesn't involve a deploy. That's genuinely better than either default.
It isn't free. Someone has to build the metadata fields, the sitemap generation, the schema templates, the redirect handling and the preview environment before a single page ships. Budget a real engineering block for that, not a weekend. And keep headless WordPress in the running — the editing experience your team already knows, with the rendering layer replaced, is often the shortest path to the same outcome.
This site runs on Next.js, which is exactly why we're specific about the tax: everything above is a bill we pay ourselves. If you want the rendering audited before you commit either way, that's technical SEO work, and it's cheaper than the replatform you're considering.
The short version, by situation
- Content-led site, no developer on the marketing team. WordPress. Server-rendered, publishable by a human, and every SEO job is a field rather than a ticket.
- Product-led site with an engineering team already shipping in React. Next.js, server-rendered, with a headless CMS wired in before the first content page goes live — not after.
- Existing Next.js site with a rendering problem. Fix the rendering, don't migrate. Moving the main content to server components is days of work; a replatform is months and carries its own traffic risk.
- Existing WordPress site that's slow. It's the host and the plugins, not WordPress. Fix those first — see Core Web Vitals for what you're actually aiming at.
- Nobody has checked what the raw HTML contains. Do that before you argue about anything else. Half these debates end the moment somebody runs
curl.