Strapi SEO
Strapi is a headless CMS with no frontend, so your SEO is decided by how the frontend renders — plus content modeling, the SEO plugin, sitemaps, drafts, and preview hygiene.
Strapi is an open-source headless CMS with no rendering layer, so it's SEO-neutral — every outcome is decided by the frontend (Next.js, Nuxt, Astro) that consumes its API. Render in HTML at build or request time (SSG/SSR), not in the browser (CSR). Model SEO fields in your content types (use the community SEO plugin), keep drafts and preview/staging deployments out of the index, block the /admin panel and raw /api JSON, and build sitemap.xml and robots.txt at the frontend. Get rendering right and a Strapi site can beat a traditional CMS on Core Web Vitals.
TL;DR — Strapi is a “headless” CMS — it stores your content and hands it out through an API, but it has no website attached. That means Strapi itself doesn’t decide your SEO; the frontend that turns Strapi’s content into pages does. The big rule is the same as for any headless setup: build your HTML on a server or at build time (SSR or SSG), not entirely in the visitor’s browser. And all the SEO stuff WordPress + Yoast did for you — titles, sitemaps, robots.txt — you now set up yourself.
What Strapi actually is
Strapi is an open-source, Node.js-based headless CMS. “Headless” means it’s just the back half of a website — the place you write and store content — with no front half (no theme, no pages, no rendering). You get your content out through a REST or GraphQL API. You can run Strapi on your own server or use Strapi Cloud to have them host it.
Evidence for this claim Strapi is a headless CMS that exposes content through APIs and leaves presentation to a separate frontend. Scope: Current Strapi architecture. Confidence: high · Verified: Strapi documentationBecause there’s no built-in website, Strapi pairs with a separate frontend framework — Next.js, Nuxt, Astro, or Gatsby are the common ones — that fetches content from Strapi and builds the actual pages people (and Googlebot) see.
The one thing to understand
Strapi is neutral for SEO. It’s not good or bad on its own. What matters is how the frontend builds the page. There are two safe ways and one risky way:
- At build time (SSG) — pages are pre-built into plain HTML files. Fast and search-friendly.
- On a server, per request (SSR) — the server builds the full page and sends it. Also search-friendly.
- In the visitor’s browser (CSR) — the server sends a near-empty shell and JavaScript fills it in later. This is the risky one.
Google can eventually read browser-rendered pages, but it’s slower and less reliable. AI crawler rendering behavior varies by vendor — there’s no single shared standard — but a crawler that fetches only the initial HTML (several of the bots behind ChatGPT and Perplexity currently work this way) sees exactly what CSR ships: an empty shell. Build your HTML on the server or at build time so the content is in the raw HTML no matter who’s fetching it.
Evidence for this claim Google renders JavaScript after crawling, so browser-only content depends on the rendering stage. Scope: Google Search only; no claim about all AI crawlers is sourced here. Confidence: high · Verified: Google: JavaScript SEO basicsThe “where did my SEO settings go?” problem
Switching from WordPress + Yoast to Strapi, people are shocked that titles, meta descriptions, sitemaps, and canonical tags don’t appear by themselves. There’s no plugin layer doing it quietly in the background. With Strapi you have to:
- Add SEO fields (title, description, canonical, social image) to your content types — there’s an official-ish community SEO plugin that adds these for you.
- Wire those fields into the page’s HTML in the frontend.
- Build a sitemap and a robots.txt.
None of this is hard; it just won’t happen on its own.
A few things that quietly break
- Drafts getting indexed. Strapi has a draft/publish workflow. Keep unpublished content out of search — don’t expose it through the public API.
- Preview sites getting indexed. Teams spin up preview/staging URLs to review drafts. If Google finds one, it can index a whole duplicate copy. Block them.
- The admin panel and raw API. Your
/adminlogin and the/api/...JSON feed shouldn’t show up in search.
Want the full version — the four rendering modes, the SEO plugin, sitemaps, draft and preview hygiene, Strapi Cloud vs. self-hosted, and migrations? Switch to the Advanced tab.
TL;DR — Strapi is a backend-only headless CMS (REST + GraphQL, self-hosted or Strapi Cloud) with no rendering layer, so it is SEO-neutral — the frontend’s rendering mode decides everything. SSG/SSR ship fully-rendered HTML and are safe; CSR is risky (a crawler that fetches only the initial HTML sees an empty shell — that’s how several major AI crawlers currently behave); ISR has the stale-on-first-request trap. Model SEO fields in your content types (the community
@strapi/plugin-seostores and previews them but does not output HTML, sitemaps, or robots.txt — that’s the frontend’s job). Keep drafts out via the publish workflow (never pass auth tokens in public requests), noindex preview/staging at the host level, keep/adminand raw/api/*JSON out of search, and buildsitemap.xml+ robots.txt at the frontend. Strapi is neutral; your architecture is the product.
Strapi is not the SEO decision — the frontend is
The single most important concept in Strapi SEO: Strapi has no rendering layer. It is content storage, a content model, an editing UI, and an API. Every SEO outcome — indexability, metadata, speed, structured data — is determined by the frontend framework consuming Strapi’s API. Strapi’s job is purely to store and serve the right fields.
Evidence for this claim Strapi provides REST and GraphQL content APIs rather than rendering a public website. Scope: GraphQL requires Strapi's GraphQL plugin; REST is available for content types. Confidence: high · Verified: Strapi: REST APIThat makes “Strapi is bad for SEO” the wrong frame. Strapi is neutral. As Strapi’s own team puts it, “headless architectures require developers to take ownership of SEO aspects that traditional content management systems handle automatically.” A Strapi + Next.js site rendering on SSG, with a disciplined metadata layer, will outperform a neglected WordPress install. A Strapi site fronted by a client-rendered React SPA with no metadata wiring will quietly fall apart. Same backend, opposite outcomes — because the rendering decisions differ. This is the same point I make about JavaScript SEO generally: the question to start with is always how is the frontend rendering this content?
The four rendering modes (the most critical decision)
- SSG — Static Site Generation. HTML built at build time, served as static files. Best-case SEO: fully-rendered HTML on first fetch, fast TTFB and Core Web Vitals. Tradeoff: new/changed content needs a rebuild. Gatsby and Astro are SSG-first; Next.js does it per route.
- SSR — Server-Side Rendering. HTML rendered per request on a server or edge. Always-fresh, fully-rendered HTML. Tradeoff: Strapi API latency lands directly in your TTFB on every request. Next.js, Nuxt, SvelteKit, Remix.
- ISR — Incremental Static Regeneration. Static pages regenerated in the background after a revalidation window. A good middle ground with one trap (below).
- CSR — Client-Side Rendering. A near-empty shell ships and the browser fetches from Strapi and builds the DOM. Worst SEO option: Google must queue the page for a later render wave — “Googlebot queues all pages with a 200 HTTP status code for rendering, unless a robots meta tag or header tells Google not to index the page” — so your content doesn’t exist until that wave runs. AI crawlers and Bing handle this far worse than Google. Acceptable only for logged-in dashboards you don’t want indexed anyway. A raw React/Vue SPA over Strapi lands here by default — avoid it for public content.
The ISR trap: when the revalidation window expires, the next request — which could be Googlebot — still gets the stale cached page; the fresh one serves only on the following request. For volatile data (prices, stock), prefer SSR. ISR is ideal for content that changes on the order of hours or days.
Content modeling for SEO in Strapi
Strapi gives the frontend nothing to render unless you put the fields in the content model. For every public content type, add an SEO component with at minimum:
metaTitle,metaDescriptioncanonicalURLogImage(and Open Graph / Twitter fields)- a robots directive — e.g. a
preventIndexingBoolean for per-entry noindex control
Use Strapi’s UID field for slugs — it auto-generates from the title and enforces
uniqueness. For multilingual sites, enable Strapi’s built-in i18n per content
type, localize the slug and SEO fields per locale, then output
<link rel="alternate" hreflang="..."> in the frontend using the localizations
relationship each entry exposes. As SALT.agency notes, the title “can either be
populated with the Strapi SEO Plugin or by creating a text field where the title tag
will be stored, with conditions added such as not being shorter than or not
exceeding a set amount of characters.”
The frontend then reads those fields from the API and populates the <head> —
Next.js generateMetadata, Nuxt useSeoMeta, Astro’s layout <head>. The
reliability rule is the same as all headless SEO: HTML-level metadata beats
JS-injected metadata, because Google sees it on the first fetch.
The Strapi SEO plugin — what it does and doesn’t do
The community SEO plugin (@strapi/plugin-seo, formerly @strapi-community/plugin-seo,
listed on the Strapi Market) is the standard tool. It “embeds a side panel in every
Content-Type edit view where you can set meta titles, descriptions, canonical URLs,
and social share images,” adds a SERP preview, and runs in-content analysis — green,
orange, or red indicators for readability, keyword distribution, and schema
compliance.
What it does not do, and this is the most common misconception:
- It does not generate the
<head>HTML — the frontend renders the fields. - It does not generate a sitemap — that’s a separate plugin (on Strapi 5, the
Webtools sitemap add-on or
strapi-5-sitemap-plugin). - It does not write robots.txt or implement structured data — frontend’s job.
In other words, the plugin gives editors a good authoring UX and stores clean fields. The frontend still has to do the actual SEO output.
Drafts, preview, /admin, and /api — keeping the wrong things out of the index
This is where Strapi has more failure modes than a hosted platform like Shopify.
- Draft/Publish. Strapi marks drafts with
publishedAt: null; the API returns only published entries to unauthenticated requests. The critical discipline: never pass an authenticated API token in public frontend requests, or all draft content becomes fetchable. The sitemap plugin/add-on respects publish state and only includes published URLs. - Preview / staging environments. Vercel branch deploys, Netlify deploy
previews, and dedicated preview hosts consuming Strapi drafts are usually
publicly reachable. Block them with a layered approach: an
X-Robots-Tag: noindexheader at the host level (not just a meta tag a CSR page injects late),Disallow: /in robots.txt, anoindexmeta tag on every page, and HTTP authentication where possible. Watch Search Console for unexpected hostnames — that’s your early warning. - The
/adminpanel. Strapi’s admin is a React SPA; confirm it carries<meta name="robots" content="noindex">(Strapi v4+ does), keep it off public links, and password-protect it — an unprotected/adminis discoverable via Google dorking. - The raw
/api/*JSON. It won’t rank as a page, but it wastes crawl budget and can leak data. Most production setups put the API on its own subdomain (cms.example.com/api.example.com); block that subdomain entirely in robots.txt and keep it off the sitemap. If API and frontend share a domain,Disallow: /api/.
Sitemaps and robots.txt — built at the frontend
There’s no Yoast, so both are explicit. Two sitemap routes:
- A sitemap plugin inside Strapi — generates XML and only includes published
entries. On Strapi 5 the maintained option is the Webtools sitemap
add-on (
strapi-plugin-webtools+webtools-addon-sitemap) for larger, multilingual sites, orstrapi-5-sitemap-pluginfor simpler ones. The older standalonestrapi-plugin-sitemap(pluginpal) tops out at Strapi 4 — its own docs point v5 users to Webtools instead, so don’t install it on a v5 project. Quoting the plugin docs: when draft/publish is on, “this setting will make sure that all draft pages are excluded from the sitemap.” - Frontend-generated — Next.js
sitemap.ts, Astro@astrojs/sitemap, Nuxt sitemap modules, fetching published URLs from the Strapi API. More control over canonical URLs,lastmod, andchangefreq.
robots.txt is served from the frontend (Next.js robots.ts, Astro public/robots.txt).
Include a Sitemap: directive, block preview hosts with Disallow: /, and — as with
any headless stack — never disallow .js or .css (it blocks rendering).
The high-value pattern is the webhook workflow: Strapi fires a webhook on publish → triggers a Vercel/Netlify rebuild or on-demand revalidation → regenerates the sitemap → pings Google Search Console and IndexNow. Because headless content updates flow through an API rather than a plugin that pings search engines, IndexNow (Bing, Yandex, and others) is especially valuable wired to that publish webhook.
Strapi Cloud vs. self-hosted — the SEO implications
Strapi’s hosting affects API response time, which matters differently by rendering mode:
- SSG/ISR: Strapi API speed matters at build time, not runtime — pages are pre-built, so API latency doesn’t touch the user’s TTFB.
- SSR: Strapi API latency adds directly to TTFB on every request → affects LCP → a real ranking input. This is the case to optimize.
Strapi Cloud is managed infrastructure with an asset CDN — good for teams without DevOps. Self-hosted gives you full control of caching (Redis), database indexing, and geographic proximity to the frontend. Either way: cache Strapi API responses at the CDN layer, or use ISR with short revalidation, to decouple frontend runtime from Strapi latency. One caveat worth stating plainly — Strapi Cloud’s CDN serves the Strapi API and assets, not your frontend website; your Core Web Vitals are measured against the frontend, which is hosted separately (Vercel, Netlify, Cloudflare Pages).
Migrating to or from Strapi
WordPress → Strapi is the common path, and migrations are where headless SEO actually goes wrong:
- Map every existing slug exactly onto Strapi’s UID field; any slug change needs a
301 redirect (use
strapi-plugin-redirect-urlsor Smart Redirect Manager, read by the frontend/middleware). - Migrate meta titles, descriptions, and
og:imagefromwp_postmetainto the SEO component fields, and image alt text into the Media LibraryalternativeTextfield. - Inventory every URL — not just posts: tag pages, paginated archives, parameter URLs — and build the redirect map before go-live.
- Migrate canonicals explicitly; don’t assume the frontend auto-generates them right.
- Post-launch: run a Screaming Frog crawl comparison, re-verify structured data with the Rich Results Test, resubmit sitemaps to GSC and Bing, and stand up IndexNow.
Strapi SEO is really a specialized application of JavaScript SEO and rendering — the sibling headless CMS SEO write-up covers the platform-agnostic version of all of this.
AI summary
A condensed take on the Advanced version:
- Strapi is SEO-neutral. It’s a backend-only headless CMS (REST + GraphQL, self-hosted or Strapi Cloud) with no rendering layer — the frontend decides everything. “Strapi is bad for SEO” is a myth.
- Rendering mode is the product: SSG/SSR ship fully-rendered HTML and are safe; CSR is risky (content only exists after a later render wave, and AI crawlers/Bing handle it poorly); ISR is a good middle ground with a stale-on-first-request trap — use SSR for volatile data.
- Model SEO fields in content types:
metaTitle,metaDescription,canonicalURL,ogImage, apreventIndexingBoolean; UID field for slugs; i18n +localizationsfor hreflang. - The SEO plugin stores and previews fields but does not output
<head>HTML, sitemaps, or robots.txt — that’s the frontend’s job. The sitemap is a separate plugin — on Strapi 5 that’s the Webtools sitemap add-on orstrapi-5-sitemap-plugin; the older standalonestrapi-plugin-sitemapis Strapi-4-only. - Keep the wrong things out of the index: drafts (publish workflow; never pass
auth tokens publicly), preview/staging (host-level
noindex+ robotsDisallow: /- auth),
/admin(noindex + password), and raw/api/*JSON (block, ideally on its own subdomain).
- auth),
- Build sitemap.xml and robots.txt at the frontend; never block
.js/.css; wire a publish webhook → rebuild → sitemap → GSC + IndexNow. - Hosting: in SSR, Strapi API latency hits TTFB/LCP directly — cache it or use ISR. Strapi Cloud’s CDN is for the API/assets, not your frontend’s Core Web Vitals.
- Migrations fail on broken 301s, lost metadata, and accidental CSR — full URL inventory + redirect map before go-live.
Official documentation
Primary-source documentation from the search engines (Strapi is rendering-agnostic, so the SEO-relevant docs are the JavaScript/rendering ones).
- Understand JavaScript SEO Basics — the crawl → render → index pipeline that governs how a Strapi frontend’s content gets indexed.
- Dynamic Rendering (deprecated workaround) — why Google deprecated it; use SSR, static rendering, or hydration instead of prerendering a CSR Strapi frontend.
- Rendering for Content-Driven Web Apps — SSR vs. SSG vs. CSR tradeoffs for content sites like Strapi-powered editorial.
- Fix Search-Related JavaScript Problems — diagnosing rendered-DOM gaps in a JS frontend.
- Block Search indexing with noindex — the meta tag /
X-Robots-Tagheader used to keep drafts, preview hosts, and/adminout of the index. - Introduction to robots.txt — what robots.txt does and doesn’t do (relevant for blocking the API subdomain and preview hosts).
Bing / Microsoft
- The new evergreen Bingbot (Microsoft Edge) — Bingbot renders JS, but less consistently than Google — another reason SSR/SSG matters on Strapi.
- IndexNow / indexnow.org — the push protocol to wire to your Strapi publish webhook.
Quotes from the source
On-the-record statements on JavaScript rendering (Google), plus the Strapi team and practitioners on headless SEO. Each link is a deep link that jumps to the quoted passage where the source supports it.
Google — how JavaScript pages are processed
- “Googlebot queues all pages with a 200 HTTP status code for rendering, unless a robots meta tag or header tells Google not to index the page.” — Google Search Central docs. Jump to quote
Google — dynamic rendering is deprecated
- “Dynamic rendering was a workaround and not a long-term solution for problems with JavaScript-generated content in search engines.” — Google Search Central docs. Recommended instead: “server-side rendering, static rendering, or hydration.” Jump to quote
Strapi — headless shifts SEO ownership to developers
- “SEO in headless CMS architectures is a more technical challenge that requires careful implementation, as headless architectures require developers to take ownership of SEO aspects that traditional content management systems handle automatically.” — Strapi Blog, Headless CMS & Strapi SEO best practices. Read the post
- “When using the draft/publish functionality in Strapi, this setting will make sure that all draft pages are excluded from the sitemap. This ensures that only published content appears in search engine sitemaps.” — Strapi Blog, Strapi SEO Plugins: Complete Guide for Strapi 5. Read the post
- “The official SEO plugin embeds a side panel in every Content-Type edit view where you can set meta titles, descriptions, canonical URLs, and social share images.” — Strapi Blog, Strapi SEO Plugins: Complete Guide for Strapi 5. Read the post
Practitioners — headless removes the defaults
- “Headless CMS platforms remove a lot of the defaults that traditional CMS platforms handle automatically — meta tags, canonical URLs, structured data, sitemaps, none of these come out of the box in a headless setup.” — Successive Digital, Headless CMS SEO: Avoid These Common Pitfalls. Read the post
- “The title can either be populated with the Strapi SEO Plugin or by creating a text field where the title tag will be stored, with conditions added such as not being shorter than or not exceeding a set amount of characters.” — SALT.agency, The SEO guide to Strapi. Read the post
Two checklists: Strapi SEO health + migration
Strapi SEO health check
- The frontend renders content in HTML on first request (SSR or SSG), not only after client-side JavaScript runs.
- No public content type relies on CSR for its main content (many AI crawlers fetch only the initial HTML and never execute JavaScript).
- An SEO component (metaTitle, metaDescription, canonicalURL, ogImage,
preventIndexing) exists on every public content type and is mapped into the<head>. - Slugs use the UID field; canonicals are absolute URLs built from one
SITE_URL, set at the rendering layer. - The frontend never sends an authenticated API token in public requests (or drafts leak).
- Preview/staging hosts return a host-level
X-Robots-Tag: noindexplusDisallow: /in robots.txt (and HTTP auth where possible). -
/adminis noindexed and password-protected; not linked publicly. - The raw
/api/*JSON is blocked in robots.txt (ideally on its own subdomain, kept off the sitemap). -
sitemap.xmlis generated (sitemap plugin or frontend) and lists only published, canonical URLs. - robots.txt exists, includes a
Sitemap:directive, and does not block.js/.css. - A publish webhook triggers a rebuild/revalidate → sitemap regen → GSC + IndexNow ping.
Migration checklist (WordPress → Strapi)
- Full URL inventory — posts, pages, tag/category pages, paginated archives, parameter URLs.
- Slugs mapped exactly onto Strapi UID fields; 301 redirect map built
before go-live (
strapi-plugin-redirect-urls/ Smart Redirect Manager). - Meta titles, descriptions,
og:imagemigrated into the SEO component. - Image alt text migrated into the Media Library
alternativeTextfield. - Canonicals verified on the new frontend (not assumed).
- Rendering mode confirmed as SSR/SSG (not an accidental CSR default).
- Structured data re-verified with the Rich Results Test.
- Sitemaps resubmitted to Google Search Console and Bing Webmaster Tools; IndexNow stood up.
The mental models
1. Strapi is not the SEO decision — the frontend is. Strapi has no rendering layer. Before debugging anything, answer one question: how is the frontend rendering this content? Almost every Strapi SEO problem resolves to that.
2. The rendering-mode decision rule. Pick by how often the content changes:
- Mostly static (blogs, docs, marketing) → SSG.
- Always-fresh / volatile (prices, stock) → SSR.
- Hourly/daily, want static speed → ISR (mind the stale-first-request trap).
- Logged-in, not meant to be indexed → CSR is acceptable.
- Public content you want ranked or cited by AI → never CSR.
3. “Rebuild what the plugin did.”
Every automatic Yoast behavior is now a deliberate step in Strapi + frontend:
SEO fields in the content model → mapped to <head> → sitemap → robots.txt →
canonicals → structured data. If something’s “missing,” a plugin behavior was never
re-implemented.
4. The plugin stores; the frontend renders. The SEO plugin gives editors fields and previews — it does not emit HTML, sitemaps, or robots.txt. Keep those two responsibilities separate in your head and you won’t expect the plugin to do the frontend’s job.
5. Four things must never reach the index.
Drafts, preview/staging deployments, /admin, and the raw /api/* JSON. Each has a
different control (publish workflow, host-level noindex, password + noindex, robots
block on its own subdomain). Audit all four explicitly.
Strapi SEO — cheat sheet
Rendering modes at a glance
| Mode | Where HTML is built | SEO | Best for | Watch out for |
|---|---|---|---|---|
| SSG | Build time → static files | ✅ Best | Mostly-static content | Stale until rebuild; slow builds at scale |
| SSR | Server, per request | ✅ Best | Always-fresh content | Strapi API latency lands in TTFB |
| ISR | Static + timed background regen | ✅ Good | Hourly/daily content | First request post-revalidation gets stale page |
| CSR | In the browser | ⚠️ Risky | Logged-in dashboards | Empty shell to HTML-only fetchers (many AI crawlers); render-wave delay |
What Strapi/plugins do vs. what the frontend does
| Strapi + SEO plugin | The frontend |
|---|---|
| Stores SEO fields (title, desc, canonical, OG) | Renders those fields into <head> |
| SERP preview + in-content analysis in admin | Builds sitemap.xml |
| Sitemap plugin generates XML (published only) | Writes robots.txt |
| Draft/publish gates the public API | Implements JSON-LD structured data |
Keep out of the index — four controls
| Thing | Control |
|---|---|
| Drafts | Publish workflow; never use auth tokens in public requests |
| Preview/staging | Host-level X-Robots-Tag: noindex + robots Disallow: / + auth |
/admin panel | noindex (default v4+) + password; no public links |
Raw /api/* JSON | Block in robots.txt; ideally its own subdomain, off the sitemap |
Fast rules
- Strapi is SEO-neutral — the rendering mode is the product.
- Use the UID field for slugs; canonicals = absolute URLs from one
SITE_URL. - The SEO plugin stores fields; it does not output HTML/sitemap/robots.
- Never disallow
.js/.cssin robots.txt. - Wire a publish webhook → rebuild → sitemap → GSC + IndexNow.
- In SSR, cache the Strapi API (or use ISR) so latency doesn’t tank LCP.
How should a Strapi page render?
Choose the delivery model
Incident playbook: published Strapi pages disappear from search
- Confirm the public response. Check status, redirects, raw HTML, canonical, and robots directives. Fix a fetch or indexability failure before content analysis.
- Trace publication. Match the Strapi publish event to webhook, build/revalidation, and cache logs. If the live page is stale, repair that chain.
- Check template scope. Compare affected and healthy content types. If one template fails, inspect its frontend field mapping and route generation.
- Check exposure. Ensure drafts, preview hosts,
/admin, and raw API routes are excluded while public HTML routes remain crawlable. - Validate recovery. Confirm complete source HTML and a clean canonical/indexability state, then monitor normal recrawl rather than repeatedly resubmitting unchanged pages.
Strapi SEO mistakes
- Treating an SEO plugin as a rendering layer. It creates fields; the frontend must output and validate them.
- Fetching essential content only in the browser. Use SSG, regeneration, or SSR for pages that need to rank.
- Exposing drafts and preview deployments. Require access and send server-visible
noindexsignals. - Putting raw API URLs in sitemaps. Sitemaps should list canonical public HTML routes, not
/apiresources. - Blocking all API access without checking the architecture. Protect private endpoints, but do not break server builds or rendering that legitimately depends on Strapi.
Content is published in Strapi but the page stays stale
Likely cause: webhook, build, revalidation, or cache failure. Fix: trace the content ID through each step and purge the affected route. Confirm: raw production HTML contains the published revision.
SEO fields are filled but tags are absent
Likely cause: the frontend query omits the SEO component or the head template does not map it. Fix: include the fields and render them during SSG/SSR. Confirm: curl returns the expected title, canonical, and robots tags.
Draft or preview content is indexable
Likely cause: a public preview host or client-only noindex logic. Fix: add authentication and server-level exclusion. Confirm: unauthenticated requests cannot access an indexable response.
A content type is missing from the sitemap
Likely cause: the frontend sitemap query, publication filter, locale relation, or route mapping excludes it. Fix: correct the query and include canonical published routes only. Confirm: sitemap entries resolve to indexable 200 pages.
Compare Strapi API data with production HTML
curl -fsS 'https://cms.example.com/api/articles/SLUG' > strapi.json
curl -fsSL 'https://www.example.com/SLUG/' > page.html
grep -Eio '<title>[^<]+|<link[^>]+rel="canonical"[^>]*|<meta[^>]+name="robots"[^>]*' page.htmlUse the API response only from an authorized environment and do not print tokens into logs. The comparison checks delivery; it does not prove Google’s indexing decision.
Inspect rendered head values
Run in DevTools Console:
({title: document.title, canonical: document.querySelector('link[rel="canonical"]')?.href, robots: document.querySelector('meta[name="robots" i]')?.content}); Prove a Strapi SEO change
Content-delivery test
Test to run: publish a controlled revision and trace Strapi, webhook, build/revalidation, cache, and live source. Expected result: one canonical production route serves the same published revision. Failure interpretation: delivery or invalidation is stale. Monitoring window: the normal publishing SLA. Rollback trigger: mixed content and metadata versions reach production.
Source-rendering test
Test to run: compare raw and rendered HTML on representative content types. Expected result: primary content, links, metadata, and canonicals are present and agree. Failure interpretation: essential output depends on browser JavaScript. Monitoring window: every frontend release. Rollback trigger: a key template loses source content or indexability signals.
Exposure test
Test to run: request preview, draft, admin, API, and public routes without credentials. Expected result: sensitive routes are protected or excluded while canonical public pages remain crawlable. Failure interpretation: access and SEO controls are over- or under-scoped. Monitoring window: every routing or security change. Rollback trigger: drafts become public or public pages become blocked.
Patrick's relevant free tools
- Raw vs. Rendered HTML Checker — See what's in your page's initial HTML versus after JavaScript runs — headless-Chrome rendering only when the page actually needs it, a rendering-strategy verdict (SSR / prerendered / CSR / hybrid), ~15 calibrated JavaScript-SEO checks (noindex, canonicals, robots.txt blocking, links, soft 404s), a side-by-side raw-vs-rendered diff, and shareable reports.
- Staging vs. Production SEO Diff — Compare matched release URLs across redirects, canonicals, robots directives, hreflang, selected headers, schema eligibility, and raw or optionally rendered content with honest not-evaluated states.
- Google Index Checker — Check one URL’s observable indexability blockers, or reconcile sitemap, crawl, and supplied Search Console evidence across a URL set before verifying Google’s actual state in URL Inspection.
Tools for Strapi SEO
@strapi/plugin-seo(community SEO plugin) — adds the SEO component, SERP preview, and in-content analysis to the Strapi admin. Install viayarn add @strapi/plugin-seo. Stores fields; doesn’t render them.- Webtools sitemap add-on (
strapi-plugin-webtools+webtools-addon-sitemap, pluginpal) — the maintained Strapi 5 sitemap option; generatessitemap.xmlfrom published content and auto-splits into a sitemap index at scale.strapi-5-sitemap-pluginis a lighter alternative for simpler sites. Pluginpal’s older standalonestrapi-plugin-sitemaponly supports Strapi 4 — its README redirects v5 users to Webtools. strapi-plugin-redirect-urls/ Smart Redirect Manager — manage 301/302 redirects in the admin for migrations and slug changes.- URL Inspection (Google Search Console) — see how a single frontend URL was crawled and rendered; the rendered HTML tells you whether CSR left content out.
- Rich Results Test — confirm JSON-LD is present in the rendered output after any rendering change.
- Screaming Frog SEO Spider — crawl with JS rendering on/off to compare raw vs. rendered HTML; build the pre/post crawl comparison for migrations; surface accidentally-indexable preview/admin/API URLs.
- Ahrefs Site Audit — surfaces broken canonicals, missing metadata, redirect chains, and indexability issues across the whole frontend.
- Bing Webmaster Tools — Bing’s rendering/indexing view and where IndexNow submissions show up.
Test yourself: Strapi SEO
Five quick questions on how SEO works on a Strapi-powered site. Pick an answer for each, then check.
Resources worth your time
My related writing
- JavaScript SEO Issues & Best Practices — my primary reference on rendering; the core of how a Strapi frontend gets crawled and indexed.
- The Beginner’s Guide to Technical SEO — where rendering and crawling fit in the bigger picture.
My speaking
- JavaScript SEO — Ungagged 2019 (SlideShare) — my walkthrough of how headless/decoupled CMSes split frontend from backend, plus Googlebot’s stateless rendering. (Standing disclaimer: the dynamic-rendering recommendation in that deck is now outdated — Google deprecated it.)
On this site
- SEO for a Headless CMS — the platform-agnostic version of everything here.
- JavaScript SEO — the rendering pillar Strapi SEO sits on top of.
From around the industry
- React SEO: Best Practices (Sam Underwood, Ahrefs) — React is the most common frontend paired with Strapi and directly applicable; authored by Patrick’s Ahrefs colleague rather than Patrick.
- Headless CMS & Strapi SEO best practices (Strapi Blog) — Strapi’s own overview of where SEO ownership shifts in a headless setup.
- Strapi SEO Plugins: Complete Guide for Strapi 5 (Strapi Blog) — what the SEO and sitemap plugins do, including the draft/publish-in-sitemap behavior.
- The SEO guide to Strapi (SALT.agency) — an independent technical-SEO-agency walkthrough of modeling SEO fields in Strapi.
- Strapi SEO Tips and Tricks (Notum Tech) — from the team behind the original SEO plugin.
- Headless CMS SEO: Avoid These Common Pitfalls (Successive Digital) — the duplicate-environment and missing-defaults problems that hit Strapi stacks.
- Webtools Sitemap add-on (docs) — the maintained Strapi 5 sitemap solution; the older strapi-plugin-sitemap (GitHub) only supports Strapi 4.
- @strapi/plugin-seo (npm) — the SEO plugin package and component reference.
Stats worth citing
- Strapi is open-source and dual-deploy. It’s a Node.js headless CMS with REST + GraphQL APIs, runnable self-hosted or on Strapi Cloud — the deployment choice affects API latency, which only touches Core Web Vitals in SSR (not SSG/ISR). Source
- The sitemap add-on auto-splits past 50,000 URLs into a sitemap index and excludes drafts when draft/publish is enabled — the practical scale limit for a Strapi-generated sitemap. For Strapi 5, that’s the Webtools sitemap add-on, not the older standalone plugin (below). Source
- Rendering behavior isn’t uniform across AI crawlers, but the safe assumption is HTML-only. There’s no single shared spec — some fetchers execute JavaScript, most today don’t — so a crawler that reads only the initial HTML response sees an empty shell on a CSR page. SSR/SSG puts the content in the raw HTML and removes the guesswork, which is why it’s the safer default for AI visibility as well as Google/Bing. Context
- Google deprecated dynamic rendering. Prerendering a CSR Strapi frontend is no longer the recommended workaround — Google now points to SSR, static rendering, or hydration. Source
Strapi SEO
Strapi SEO is the practice of making content stored in Strapi — an open-source headless CMS — discoverable and rankable. Because Strapi has no built-in frontend, every SEO outcome is decided by the frontend framework that renders its API, not by Strapi itself.
Related: Headless CMS SEO, JavaScript SEO
Strapi SEO
Strapi SEO is what it takes to get search engines and AI crawlers to find, render, and rank content that lives in Strapi, an open-source, Node.js-based headless CMS that exposes content over REST and GraphQL APIs. Strapi can be self-hosted or run on Strapi Cloud, but it ships with no rendering layer — so on its own it neither helps nor hurts your SEO.
That’s the whole mental model: Strapi stores and serves the right content fields; the frontend framework consuming its API (Next.js, Nuxt, Astro, Gatsby, SvelteKit, Remix) is what actually renders the HTML search engines see. The rendering mode that frontend uses — SSG, SSR, ISR, or CSR — decides everything. SSG and SSR ship fully-rendered HTML and are the safe choices; CSR is the risky one because content only appears after JavaScript runs in the browser — and many AI crawlers fetch only the initial HTML, so they never see it.
Strapi’s actual SEO surface area is narrow but important:
- Content modeling — adding an SEO component (meta title, description, canonical, Open Graph, robots directive) to each public content type so the frontend has fields to render.
- The draft/publish workflow — keeping unpublished entries out of the index (the API only returns published content to unauthenticated requests).
- Plugins — the community SEO plugin populates and previews meta fields; a separate sitemap plugin generates XML.
- Environment hygiene — keeping
/admin, the raw/api/*JSON, and preview/staging deployments out of search engines.
Done well, a Strapi + Next.js site can outperform a traditional CMS on Core Web Vitals and technical SEO. Done with a client-rendered SPA and no metadata layer, it quietly falls apart — which is the source of the “Strapi is bad for SEO” myth.
Related: Headless CMS SEO, JavaScript SEO
Build-time retrieval analysis plus live signals for this exact article. The automatic chunk report includes a deterministic readiness score and is ready without a model download.
Search Console
sampleGA4 traffic (28d)
sampleCloudflare traffic (7d)
sampledCrUX field data (28d, phone)
sampleGoogle NLP entities
localChangelog
Updated Jul 21, 2026.
Editorial summary and recorded change details.Summary
Separated an Ahrefs article by another author from Patrick's own writing in the resources lens.
Change details
-
Moved the React SEO best-practices guide (Sam Underwood, Ahrefs) from 'My related writing' to 'From around the industry', since a colleague authored it rather than Patrick.
Full comparison unavailable — no prior snapshot was archived for this revision.
Updated Jul 19, 2026.
Editorial summary and recorded change details.Summary
Corrected an overstated claim that AI crawlers don't run JavaScript at all, and fixed stale Strapi 5 plugin guidance (the sitemap plugin cited throughout is Strapi-4-only).
Change details
- Before
most AI crawlers (the bots behind ChatGPT and Perplexity) don't run JavaScript at allAfterAI crawler rendering behavior varies by vendor with no single shared standard, but a crawler that fetches only the initial HTML (which several major AI crawlers currently do) sees an empty CSR shell — corrected in the beginner lens, cheat sheet, quiz, and stats lens, all of which repeated the overstated version. -
Replaced every reference to the standalone `strapi-plugin-sitemap` (pluginpal) with the maintained Strapi 5 sitemap options — the Webtools sitemap add-on (`strapi-plugin-webtools` + `webtools-addon-sitemap`) or `strapi-5-sitemap-plugin` — after confirming via the plugin's own README that it tops out at Strapi 4 and directs v5 users to Webtools.
-
Fixed a Google Search Central quote that no longer matches the live page text (the '200 HTTP status code queued for rendering' quote and its #:~:text= deep link) and corrected the GitHub link mislabeled as @strapi/plugin-seo's source repo.
-
Applied the same AI-crawler correction to the strapi-seo glossary entry and set its updated date.
Full comparison unavailable — no prior snapshot was archived for this revision.