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.

First published: Jun 27, 2026 · Last updated: Jul 21, 2026 · Advanced
demand #4 in Headless CMS#40 in Platform SEO#243 in Technical SEO#330 on the site

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 backend-only headless CMSA headless CMS decouples content storage and editing (the backend) from how that content is rendered and delivered (the frontend), serving content over an API instead of a built-in templated 'head'. Its SEO outcomes come almost entirely from how the separate frontend renders pages. (REST + GraphQL, self-hosted or Strapi Cloud) with no renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. layer, so it is SEO-neutral — the frontend’s renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. mode decides everything. SSG/SSR ship fully-rendered HTML and are safe; CSR is risky (a crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. that fetches only the initial HTML sees an empty shell — that’s how several major AI crawlersAI crawlers are bots from AI companies that fetch web pages to train language models, build AI-search indexes, or answer live user questions. They come in three categories, each with its own user-agent tokens and its own robots.txt controls. currently behave); ISR has the stale-on-first-request trap. Model SEO fields in your content types (the community @strapi/plugin-seo stores and previews them but does not output HTML, sitemapsA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing., or robots.txtA plain-text file at the root of a host that tells crawlers which URLs they may and may not request. It controls crawling, not indexing — a blocked URL can still be indexed if it's linked from elsewhere. — that’s the frontend’s job). Keep drafts out via the publish workflow (never pass auth tokensA token is the smallest unit of text (or image/audio/video) an LLM processes — roughly 4 characters, or about ¾ of an English word. A context window is the maximum number of tokens (input plus output) a model can hold at once, like its short-term memory. in public requests), noindexNoindex is a directive that tells search engines to keep a page out of their index, so it won't appear in search results. It works only on pages a crawler can actually fetch — a page blocked in robots.txt can never be noindexed. preview/staging at the host level, keep /admin and raw /api/* JSON out of search, and build sitemap.xml + robots.txtA plain-text file at the root of a host that tells crawlers which URLs they may and may not request. It controls crawling, not indexing — a blocked URL can still be indexed if it's linked from elsewhere. 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 SEOStrapi 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.: 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 dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding. — 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 API

That 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 TTFBTime to First Byte — the time from the start of a request to when the first byte of the response arrives. It's a diagnostic metric (not a Core Web Vital) and a major input to FCP and LCP; ≤0.8 s is good. 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 — GooglebotGooglebot is Google's web crawler — the software that fetches pages so Google can index and rank them. It comes in two variants, Googlebot Smartphone (primary, under mobile-first indexing) and Googlebot Desktop, and runs an evergreen Chromium renderer. queues all pages with a 200 HTTP status codeAn HTTP status code is the three-digit number a server returns with every response to tell a browser or crawler what happened to its request — success, redirect, client error, or server error. For SEO the code matters as much as the content: it tells Google and Bing whether to index a page, follow a redirect, retry later, or drop the URL from the index. for rendering, unless a robots meta tagThe robots meta tag is an HTML element in a page's head — <meta name=\"robots\" content=\"noindex\"> — that tells search engines how to index and serve that page. It's crawl-then-obey: a page blocked in robots.txt is never fetched, so the tag is never seen. or header tells Google not to index the page” — so your content doesn’t exist until that wave runs. AI crawlersAI crawlers are bots from AI companies that fetch web pages to train language models, build AI-search indexes, or answer live user questions. They come in three categories, each with its own user-agent tokens and its own robots.txt controls. 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.
Evidence for this claim Google sends pages with successful HTTP responses to a rendering queue and recommends server-side or pre-rendering for reliable content delivery. Scope: Google Search JavaScript processing; rendering is not an assurance of indexing. Confidence: high · Verified: Google: JavaScript SEO basics

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, metaDescription
  • canonicalURL
  • ogImage (and Open GraphOpen Graph (OG) tags are `<meta>` elements in a page's head, defined by the Open Graph protocol (ogp.me, created by Facebook), that describe a page as a shareable object — its title, description, image, URL, and type. They control how a link preview card looks when the page is shared on Facebook, LinkedIn, Slack, Discord, WhatsApp, and iMessage. They are not a direct Google ranking factor, though Google reads og:title, og:image, and og:site_name as inputs to how a result appears. / Twitter fields)
  • a robots directive — e.g. a preventIndexing Boolean for per-entry noindexNoindex is a directive that tells search engines to keep a page out of their index, so it won't appear in search results. It works only on pages a crawler can actually fetch — a page blocked in robots.txt can never be noindexed. 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 tagThe title tag is the HTML title element in a page's head that specifies the document's title. It's the primary source for the SERP title link and a confirmed light ranking factor — but since August 2021 Google doesn't always show it verbatim. 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 sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. — 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: noindex header at the host level (not just a meta tag a CSR page injects late), Disallow: / in robots.txt, a noindex meta tag on every page, and HTTP authentication where possible. Watch Search ConsoleGoogle's free tool for monitoring crawling, indexing, and search performance. for unexpected hostnames — that’s your early warning.
  • The /admin panel. 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 /admin is discoverable via Google dorking.
  • The raw /api/* JSON. It won’t rank as a page, but it wastes crawl budgetThe number of URLs an engine will crawl in a timeframe. 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:

  1. 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, or strapi-5-sitemap-plugin for simpler ones. The older standalone strapi-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.”
  2. 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, and changefreq.

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 ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. and IndexNowIndexNow is an open push protocol that lets you instantly tell participating search engines (Bing, Yandex, Naver, Seznam, and Yep) which URLs you've added, changed, or removed via a simple HTTP request — and one submission is shared across all of them. Google does not use it.. 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 LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. → 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 indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed., 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 VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. 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 redirectA 301 redirect is the HTTP status code for a permanent move: it tells browsers and search engines a URL has moved for good, and it's the strongest signal for consolidating a page's ranking signals onto the new URL. Google says permanent redirects don't cause a loss in PageRank. (use strapi-plugin-redirect-urls or Smart RedirectA redirect sends browsers and crawlers from a requested URL to a different one. An HTTP redirect specifically is a 3xx status code paired with a Location header; meta refresh and JavaScript redirects achieve a similar navigation without being a 3xx response themselves. Permanent redirects (301/308) are Google's signal the target should be canonical; temporary ones (302/303/307) aren't. Manager, read by the frontend/middleware).
  • Migrate meta titles, descriptions, and og:image from wp_postmeta into the SEO component fields, and image alt textAlt text is the value of the `alt` attribute on an HTML `<img>` element — a short text substitute chosen for the image's purpose and context, not a literal description of what it shows. It makes images accessible to screen-reader users and helps search engines understand images, mainly for image search. into the Media Library alternativeText field.
  • 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 ResultsRich results (formerly 'rich snippets') are enhanced search listings — stars, images, prices, breadcrumbs, video thumbnails, and more — that Google and Bing build from structured data. They're a display feature, not a ranking factor, and eligibility never guarantees they'll show. 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 SEOA headless CMS decouples content storage and editing (the backend) from how that content is rendered and delivered (the frontend), serving content over an API instead of a built-in templated 'head'. Its SEO outcomes come almost entirely from how the separate frontend renders pages. write-up covers the platform-agnostic version of all of this.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.