Headless WordPress SEO: What You Have to Rebuild
Going headless removes everything your SEO plugin was doing on the front end. Here is the full list of what the frontend now has to render itself.

There's a persistent belief that headless WordPress is either great for SEO or terrible for it. Neither is true. What's true is that a WordPress theme was doing a lot of SEO work invisibly, and none of it survives the move.
This is the checklist of what has to be rebuilt, which is also the honest scope of the SEO work in a headless project.
The core problem in one sentence
Your SEO plugin is a data-entry interface and an output layer. Going headless keeps the first and discards the second.
Editors can still write titles and descriptions in the familiar interface, and that's worth keeping. But the plugin renders into a theme that no longer exists, so nothing it produces reaches a visitor unless your frontend fetches that data and renders it itself.
So the first task is exposing the plugin's fields through the API, and the rest is rendering them correctly.
Per-page metadata
- Title tag, from the SEO plugin's field with a sensible fallback to the post title.
- Meta description, likewise.
- Meta robots, including any per-page noindex or nofollow the plugin stores. This one is easy to miss and expensive to get wrong.
- A self-referencing canonical on every page, and the plugin's override where one is set.
- The language attribute on the html element.
- Open Graph: type, title, description, url, image with dimensions, and site name.
- Twitter card tags, including the card type.
- Each of these has to be rendered server-side, not added by client-side JavaScript. Social scrapers in particular don't execute JavaScript at all.
Structured data
Whatever schema your SEO plugin was emitting — Organization, WebSite, BreadcrumbList, Article, FAQPage — is gone, and the frontend has to produce it.
Build it from the same data the page renders, rather than hand-writing it into a template. Generated markup can't contradict the page; hand-written markup eventually will.
Emit it as JSON-LD in a script tag, server-rendered. And remember the rule that applies everywhere: only mark up what's visibly on the page.
Sitemaps and robots.txt
WordPress generates a sitemap of its own URLs, which are now on the CMS hostname — the wrong domain entirely. Submitting it would tell search engines to index your CMS.
The frontend has to generate its own sitemap from the same content, using the frontend's URLs, containing only canonical indexable pages. Split it by type if it's large, and regenerate on publish rather than on a schedule.
Same for robots.txt: the frontend serves its own, pointing at the frontend's sitemap.
And the CMS itself must be noindexed and ideally behind authentication, so it never competes with the real site.
Redirects
Any redirect rules living in a WordPress redirect plugin are rules WordPress applies to requests WordPress receives. Your frontend receives the public requests now, so those rules do nothing.
Either replicate them in the frontend's configuration, or have the frontend fetch them from WordPress so editors can still manage them in the admin. The second is more work and much better operationally, because otherwise every redirect needs a developer.
This matters most during the migration itself, when every old URL needs a rule.
Status codes
A path that doesn't exist must return a real 404, not a 200 with a 'not found' message. Soft 404s confuse search engines, hide broken links from your reports, and let non-existent pages accumulate in the index.
Check this specifically, because several frontend frameworks make it easy to render a not-found component while still returning 200.
The same applies to redirects: a moved page should return 301, not render the new content at the old URL.
Rendering and crawlability
- Content must be in the server-rendered HTML. Static generation or server rendering, not client-side fetching — Google can render JavaScript but it's a second, slower pass, and other crawlers and social scrapers don't.
- Internal links must be real anchor elements with href attributes. A div with a click handler is not a link and is not crawled.
- Pagination must produce crawlable links, not an infinite scroll with no URLs.
- Check the rendered HTML with a text-only view or Search Console's URL Inspection, not the browser's element inspector, which shows the post-JavaScript DOM.
The things that come back to bite
- Images: alt text lives in WordPress's media metadata and is easy to drop in the API layer. Carry it through, along with dimensions so the layout doesn't shift.
- Trailing slashes: pick a convention and enforce it, or you have two URLs for every page.
- Query parameters from filters and tracking, which need canonicals pointing at the clean URL.
- Author and category archives, which have to be rebuilt as frontend routes or deliberately dropped.
- RSS feeds, if anything consumes them.
- Analytics and Search Console verification, which need setting up for the frontend's domain.
- hreflang, if the site is multilingual.
Migrating an existing site to headless
If you're moving a live site, this is a migration with all the usual risks, plus the rebuild above.
- Export the full URL list and the twelve-month Search Console baseline before you start.
- Match every existing URL exactly in the new frontend, or map it to a 301.
- Compare the old and new rendered HTML for a sample of pages, checking titles, descriptions, canonicals and schema against each other.
- Verify the frontend's domain in Search Console and submit the new sitemap.
- Watch the Pages report closely for the first weeks, and judge the outcome at six to eight weeks rather than three days.
So is headless bad for SEO?
No — and it isn't good for it either. A well-built headless site can be faster, which helps marginally, and there's nothing inherent in the architecture that hurts.
What hurts is doing half of this list. A headless site missing canonicals, structured data and a working sitemap will underperform the WordPress theme it replaced, and the cause will look mysterious until someone views the source.
So scope the SEO work explicitly, as its own line item, rather than assuming it comes free with the frontend. It's a couple of weeks of work on a typical project, and it's the difference between headless being neutral and headless being a regression.
Frequently asked questions
Is headless WordPress bad for SEO?
Not inherently. What hurts is that everything your SEO plugin used to output — titles, canonicals, Open Graph tags, schema, sitemaps, redirects — has to be rebuilt in the frontend, and projects routinely do half of it. Done fully, headless is neutral to slightly positive because the site is faster.
Do I still need an SEO plugin on headless WordPress?
Yes, as an editing interface — editors need somewhere to write titles, descriptions and canonicals, and the plugin stores that data well. It just can't output anything any more. Expose its fields through the API and render the tags in the frontend yourself.
Can search engines index a JavaScript frontend?
Google can render JavaScript, but it's a second and slower pass, and other crawlers and social scrapers don't do it at all. Server-render or statically generate your content so it's in the initial HTML. Check with a text-only view, not the browser inspector, which shows the post-JavaScript DOM.
How do sitemaps work with headless WordPress?
WordPress's own sitemap lists CMS URLs on the wrong domain, so it's useless and must never be submitted. Generate a sitemap from the frontend using the frontend's URLs, containing only canonical indexable pages, and regenerate it on publish. Serve your own robots.txt from the frontend too.
What happens to my redirect plugin when I go headless?
Its rules stop applying, because WordPress no longer receives the public requests. Either replicate the rules in the frontend's configuration, or have the frontend fetch them from WordPress so editors can still manage redirects in the admin — the second is more work and much better operationally.
Topics
- headless WordPress SEO
- headless SEO checklist
- Next.js SEO
- decoupled WordPress SEO