Guide Nuxt SEO
Nuxt ships rendu côté serveur by par défaut, but that's a per-route setting, pas a guarantee — complet HTML to robots d’exploration seulement on routes que garder it. Rendering modes, useSeoMeta(), the @nuxtjs/seo toolkit, hydration and Nitro caveats, Core Web Vitals, and the mistakes que quietly cost vous.
Langues
1 indice probant sur cette page
- Outil en ligne associéCore Web Vitals History & Competitor Comparison
Nuxt server-renders pages by par défaut, so a route que garde que par défaut donne robots d’exploration a complet HTML document au lieu de the vide shell a plain Vue SPA ships — but it's a per-route setting: routeRules or a global ssr:faux peut flip quelconque route to CSR, so vérifier the réel route plutôt que assuming from the framework nom. The foundational decision is rendering mode per route — SSR (par défaut), SSG via nuxt generate, or hybrid route rules — parce que meta tags, schema, and sitemaps tout come après que. Utiliser useSeoMeta() pour meta, treat Harlan Wilton's @nuxtjs/seo bundle as an optional third-party toolkit (pas Nuxt core) pour robots/sitemap/OG/schema/canonical, jamais reach pour dynamic rendering (Google deprecated it), vérifier hydration/payload and Nitro deployment-preset/cache behavior independently of server HTML, and remember que AI-crawler rendering contracts vary by provider — SSR/SSG puts content in raw HTML and maximizes coverage.
TL;DR — Nuxt is the framework construit on top of Vue, and it’s bon pour le SEO pour un principal raison: on a route que garde the par défaut, it builds pages on the server, so moteur de recherches obtenir a finished HTML page au lieu de a blank un they’d have to fill in themselves. That’s a per-route setting, pas a site-wide guarantee —
routeRulesor a globalssr: falsepeut turn quelconque donné route back into a plain-Vue-style vide shell. Vérifier the réel route, pas simplement the project nom. The la plupart important choice you’ll faire is how chaque route obtient rendered; everything sinon (meta tags, sitemaps) comes après que.
Pourquoi Nuxt is bon pour le SEO — on the routes que garder the par défaut
Vue, on its propre, builds a single-page app: le serveur sends an almost-empty HTML shell, and JavaScript fills in le contenu une fois it runs in le navigateur. That’s tricky pour search, parce que lune page semble vide jusqu’à the JavaScript executes.
Nuxt is Vue’s “meta-framework” — a fuller toolkit construit autour Vue — and its
par défaut fixes que problem. Nuxt renders votre pages on le serveur premier
(rendu côté serveur, or SSR), so quand Google or a visitor demande pour une page
on a route que hasn’t been switched off SSR, ils obtenir the complet HTML correct
away. Evidence for this claim Nuxt universal rendering returns server-rendered HTML to the browser by default. Scope: Nuxt default universal rendering. Confidence: high · Verified: Nuxt: Rendering modes Aucun waiting pour JavaScript. That’s the unique
biggest raison a Nuxt site peut be easier to obtenir indexé que a plain Vue app —
but it’s a route-by-route outcome, pas something the framework nom guarantees.
A route with ssr: false, or un que leans on <ClientOnly> pour its principal
content, donne up que advantage and ships the même empty-shell problem plain
Vue has.
The un decision que matters la plupart: rendering, per route
Quand someone demande pour a spécifique page, où fait its HTML obtenir construit? That’s a
routeRules-level question, pas a project-wide un — a Nuxt app peut mix modes
à travers routes. Nuxt donne vous a few options:
- Rendu côté serveur (SSR) — the par défaut. Le serveur builds the complet page on every requête. Great pour le SEO.
- Static generation (SSG) — run
nuxt generateand Nuxt builds tout votre pages into plain HTML fichiers ahead of temps. Aussi great pour le SEO, and perfect pour blogs and docs que don’t modifier every minute. - SPA mode — lune page is construit in le navigateur, comme plain Vue. Éviter ce pour anything vous vouloir trouvé in search.
The bon news is the defaults are déjà pointed the correct façon. Vous mostly have to éviter switching les off.
Ajout titles and meta tags
In Nuxt vous définir votre page title and meta description with a built-in function appelé
useSeoMeta(). Evidence for this claim Nuxt provides useSeoMeta for defining SEO and social metadata. Scope: Current Nuxt composable. Confidence: high · Verified: Nuxt: useSeoMeta Vous drop it into une page and réussir in votre title, description, and
social-share image:
useSeoMeta({
title: 'My Page Title',
description: 'A concise, page-specific summary with the key information first',
})That’s the modern, recommended façon. (There’s an older function appelé useHead()
que encore fonctionne and is utilisé pour autre choses in lune page’s <head>, but pour le SEO
meta tags reach pour useSeoMeta().) Google has aucun fixed meta-description character
limite; snippets are query-dependent and truncated to fit the device, so preview
pages importantes in leur intended language and script au lieu de coding to a quota.
The optional add-on: the Nuxt SEO modules
Nuxt core doesn’t generate a robots.txt, an XML sitemap, social-share images,
données structurées, or URL canoniques — ceux are jobs pour separate, optional
packages, pas something nuxt.config.ts donne vous by par défaut. A developer named
Harlan Wilton maintains a free, community bundle of ceux packages — installed as
@nuxtjs/seo — que covers tout of les at une fois. It’s a third-party toolkit, pas
partie of Nuxt itself, so installing it doesn’t automatically faire quelconque of que
output correct; vous encore confirmer le sitemap, robots rules, and schema it
generates match ce que vous en réalité vouloir.
The chose personnes obtenir incorrect
Personnes assume “Vue/Nuxt can’t be in Google.” Que was sort of vrai pour plain Vue apps années ago — it isn’t vrai pour Nuxt with its server rendering. The réel mistakes are choses comme turning SSR off by accident, or blocking votre JavaScript fichiers so Google can’t construire lune page.
Vouloir the deeper version — the complet menu of rendering modes, the module ecosystem in detail, Core Web Vitals, and the Erreurs fréquentes with fixes? Switch to the Avancé tab.
TL;DR — Nuxt’s par défaut is rendu côté serveur, so a route que garde que par défaut obtient a complet DOM au lieu de the vide shell a plain Vue SPA ships — but that’s a per-route outcome:
ssr: falseor arouteRulesoverride peut turn quelconque route into CSR or hybrid, so tester the réel route, pas the project nom. Rendering strategy is the foundational decision — SSR (par défaut), SSG (nuxt generate), or hybridrouteRules— parce que meta, schema, and sitemaps tout come après it. UtiliseruseSeoMeta()pour meta tags (useHead()pour the rest of the head, server-only variants quand vous don’t besoin reactivity), and treat Harlan Wilton’s@nuxtjs/seobundle as an optional third-party toolkit pour robots/sitemap/OG/schema/canonical — pas partie of Nuxt core, and pas proof its output is correct jusqu’à vous vérifier it. Jamais utiliser dynamic rendering (Google deprecated it). AI-crawler rendering varies by provider — SSR/SSG maximizes raw-HTML coverage. Au-delà the initial HTML, vérifier hydration/payload, Nitro deployment presets and mise en cache, and direct HTTP status independently — server HTML alone doesn’t prove quelconque of ceux. The usual JS-SEO rules encore appliquer: réel<a href>liens, don’t block JS/CSS, watch rendered vs. raw HTML.
Nuxt is Vue’s réponse to the SPA problem
Vue, by itself, ships a application monopage: an HTML shell plus JavaScript que builds the DOM in le navigateur. Nuxt is the meta-framework on top of Vue (running on the Nitro server engine in Nuxt 3, with Nuxt 4 suivant in 2025), and its whole raison pour existing — from an SEO standpoint — is que it renders on le serveur by par défaut. Every page arrives as a fully-formed HTML document, qui is exactly ce que Googlebot veut to lire sans having to execute JavaScript premier. Plain Vue SEO is its propre topic with its propre échec modes; ici I’m assuming you’ve picked Nuxt precisely so vous don’t have to fight the SPA problem.
Ce is the même point I faire à propos de JavaScript généralement: “quelconque kind of SSR, static rendering, and prerendering setup is going to be fine pour moteur de recherches. Gatsby, Suivant, Nuxt, etc., are tout great.” Nuxt’s defaults are pointed the correct façon. La plupart Nuxt SEO problems are personnes turning ceux defaults off, or layering mistakes on top of les.
Rendering strategy is the foundation — decided per route, pas per project
Avant meta tags, avant schema, avant sitemaps, the question que decides
everything is how fait the HTML obtenir produced pour ce spécifique route? Nuxt
documents universal (server) rendering as the app-wide par défaut, but que par défaut
isn’t a route-level guarantee: a global ssr: false switches the whole app to
client rendering, and routeRules peut assign a différent mode to quelconque URL
pattern. “This is a Nuxt app” indique vous nothing à propos de how un particulier page
renders — vous have to vérifier the route. Nuxt donne vous five strategies:
| Mode | How vous définir it | SEO impact | Meilleur pour |
|---|---|---|---|
| Universal / SSR | Par défaut (ssr: true) | Excellent — complet HTML every requête | Dynamic, personalized content |
| Static / SSG | nuxt generate | Excellent — HTML construit at deploy temps | Blogs, docs, marketing |
| Hybrid | routeRules per route | Excellent — mix per route | Grand mixed-content sites |
| SPA / CSR | ssr: false | Poor pour indexé content | Dashboards, admin panels |
| Edge-side | Deployment target | Excellent — low TTFB | Global performances |
The official Nuxt docs are blunt à propos de pourquoi rendu côté client is the incorrect choice
pour content: “Indexation and updating le contenu delivered via rendu côté client
takes plus temps”, whereas with server (universal) rendering “web robots d’exploration peut
directement index lune page’s content.” Evidence for this claim Nuxt documents that universal rendering delivers HTML content immediately and allows crawlers to index it directly. Scope: Nuxt rendering; no indexing guarantee. Confidence: high · Verified: Nuxt: Rendering modes
(Nuxt rendering docs.) CSR
(ssr: false) is positioned pour back-office, dashboards, and games — pas anything
vous vouloir indexé.
Hybrid rendering is the power déplacer pour grand sites. Route rules in
nuxt.config.ts let vous définir the rendering and mise en cache mode per URL pattern:
routeRules: {
'/blog/**': { prerender: true }, // SSG for the blog
'/product/**': { swr: 3600 }, // ISR-style: regenerate hourly
'/admin/**': { ssr: false }, // SPA for the admin area
'/checkout/**': { ssr: true }, // always-fresh SSR
}swr (stale-while-revalidate) and isr (incremental static regeneration) generate
une page statically alors refresh it in the background — ideal pour élevé page-count
e-commerce or news où a complet rebuild on every modifier isn’t practical. Nuxt
Islands (<NuxtIsland>) render components sans shipping client-side JavaScript,
cutting hydration cost and helping INP — the Core Web Vital that’s la plupart souvent the
problem on Nuxt apps.
How to vérifier ce que vous en réalité shipped: View Source montre the raw HTML the server sent; si votre content is là, you’re server-rendering. DevTools’ Elements panel montre the rendered DOM. And GSC’s Inspection d’URL outil montre ce que Google en réalité récupéré and rendered — the source of truth. Don’t trust “it semble fine in my navigateur.”
How Googlebot handles a Nuxt app
Google processes quelconque JavaScript app in three phases — explorer, render, index — and the catch is timing: rendering se produit in a queue, pas instantly. As I put it in my JavaScript SEO guide, the renderer is patient — “là is aucun fixed timeout pour the renderer… It’s really patient, and vous ne doit pas be concerned.” But patient isn’t the même as fast pour fresh content. Si vous ship a client-rendered page, votre content doesn’t exist pour Google jusqu’à que render wave runs; SSR and SSG fermer que gap parce que the HTML is complet on the premier récupérer.
Two plus choses matter at scale. Rendering JavaScript is expensive — from my 2019
JavaScript SEO talk (Ungagged), explorer costs go up by roughly 20× une fois Google has to render
(directional, but the order of magnitude encore holds). And Google takes the la plupart
restrictive directive à travers raw and rendered HTML — so a noindex injected by
JavaScript va win over an index in the raw HTML, and vice versa. A canonical
injected via JavaScript is respected seulement si there’s aucun canonical in the raw HTML
déjà. Garder votre robots and canonical signals in le serveur-rendered HTML, qui
Nuxt fait pour vous quand SSR is on.
The AI-crawler reality
Ce is the 2026 wrinkle. AI robots d’exploration — GPTBot, ClaudeBot, PerplexityBot, and the rest — généralement don’t execute JavaScript at tout. Ils index the raw HTML and nothing sinon. So a client-rendered Nuxt page is effectively invisible to AI réponse engines. SSR or SSG isn’t simplement meilleur pour Google ici; it’s the price of entry pour réponse engine optimization aussi. Si vous vouloir votre content cited by ChatGPT, Perplexity, or Claude, it has to be in the HTML on premier récupérer.
Au-delà the initial HTML: payload, hydration, and code d’états
Getting server HTML with votre content in it is necessary but pas sufficient — several choses peut encore go incorrect downstream of que premier réponse, and “I vérifié View Source” doesn’t cover les:
- Payload and hydration. Universal rendering sends the HTML and a serialized données payload the client uses to hydrate — attach event listeners and pick up où le serveur left off — sans re-fetching. Server HTML looking correct doesn’t prove hydration succeeded, que client navigation reproduces the même content, or que the payload isn’t stale. Si une page feels fine on premier charger but breaks après a client-side route modifier, that’s a hydration/payload problem, pas a rendering-mode problem.
<ClientOnly>and browser-only content. Wrapping something in<ClientOnly>— courant pour browser-API-dependent widgets — signifie it’s absent from le serveur réponse même on an otherwise-universal route. Si votre principal content, a clé lien, or votre meta tags fin up à l’intérieur a client-only boundary, robots d’exploration and AI bots que seulement lire the raw HTML miss it, regardless of votre rendering mode setting. Inspect the réel réponse, pas simplement the rendering mode config.- Code d’états and redirections aren’t self-certifying. A Nuxt error page
rendering in le navigateur, or a
navigateTo()/composable-driven redirection, doesn’t by itself prove ce que HTTP status the direct server réponse sent. Google’s guidance is explicit que meaningful code d’états matter pour exploration and indexation — confirmer the réel header withcurl -I, pas ce que the client-rendered error page displays.
None of ce is an argument contre universal rendering — it’s the reminder que “the HTML is server-rendered” is the premier vérifier, pas the dernier un.
Nitro, deployment presets, and cache boundaries
Nuxt’s server output is construit by Nitro, and Nitro compiles differently selon the deployment preset vous target (Node server, Cloudflare, Vercel, Netlify, static, and others). Que matters pour le SEO parce que presets and adapters peut differ in runtime APIs disponible, mise en cache behavior, streaming prise en charge, regional deployment, and filesystem accès — a route rule or server handler que fonctionne sous un preset isn’t guaranteed to behave identically sous un autre. Two consequences worth testing explicitly plutôt que assuming:
- Cache keys and invalidation are route-specific, pas automatic.
swrandisrroute rules cache and regenerate output, but a incorrect cache clé, manquant invalidation, or a mise en cache header définir by votre deployment platform peut serve stale, personalized, or inconsistent HTML to robots d’exploration. Vérifier the réel réponse age and quelconqueCache-Control/Ageheaders on a live URL, pas simplement therouteRulesconfig. - Production parity isn’t guaranteed by staging behavior. A route rendering correctement in local dev or a preview deployment doesn’t confirmer the production preset produces the même output — server routes, redirections, and error handling live in Nitro’s server couche, and que couche is the partie la plupart probable to differ by target. Tester the production URL directement après quelconque deployment modifier, the même façon you’d vérifier rendering mode.
Meta tags: useSeoMeta() and useHead()
Nuxt’s head management runs on Unhead, and it donne vous two composables pour différent jobs.
useSeoMeta() is the un to reach pour pour le SEO and social meta tags. It’s a flat,
type-safe API with typed parameters. Evidence for this claim useSeoMeta is a typed Nuxt API for SEO and social meta tags. Scope: Current Nuxt composable. Confidence: high · Verified: Nuxt: useSeoMeta It helps éviter the classic Ouvrir Graph
bug of en utilisant name où vous nécessaire property:
useSeoMeta({
title: 'My Page Title',
ogTitle: 'My Page Title',
description: 'Concise page-specific description with the key information first',
ogDescription: 'Concise social description tailored to this page',
ogImage: 'https://mysite.com/og-image.png', // must be an absolute URL
twitterCard: 'summary_large_image',
})useHead() is the general-purpose head outil pour everything sinon — scripts, lien
tags, corps attributes, and title templates:
useHead({
titleTemplate: '%s · My Site Name',
htmlAttrs: { lang: 'en' },
})The reliable layering pattern is: static defaults (charset, viewport, favicon) in
nuxt.config.ts → site-wide title template and global OG defaults in app.vue →
page-specific overrides via useSeoMeta() in lune page component. A courant bug is
putting useSeoMeta() in a layout au lieu de lune page, qui overwrites spécifique
page tags with generic ones. And since moteur de recherches lire the initial charger, SEO meta
généralement doesn’t besoin to be reactive — useServerHead() skips the client-side
re-execution.
Qui API, and ce que it en réalité proves:
| API | Scope | Reactive? | Ce que it proves à propos de output |
|---|---|---|---|
useSeoMeta() | Flat, typed SEO/social meta seulement | Yes (par défaut) | Sets typed properties correctement — pas que the route is unique, canonical, or indexable; vous encore propre que logic |
useHead() | Anything in <head> — scripts, liens, attrs, title template | Yes (par défaut) | General head contrôler; même caveat — API utiliser isn’t proof of a correct server réponse |
useServerHead() / server-only calls | Même as ci-dessus | Aucun — server seulement, skips client re-execution | Confirms the tag ships une fois in server HTML; doesn’t confirmer client navigation re-sets it si vous rely on it là |
Appel un of ces composables indique vous the API ran — it doesn’t by itself tell
vous ce que a direct server réponse or a client-side route modifier en réalité emits.
Confirmer with View Source or curl, pas simplement “I called useSeoMeta().”
The @nuxtjs/seo module ecosystem (Harlan Wilton) — optional, pas core
Nuxt core doesn’t ship a sitemap, a robots.txt, OG image generation, or
Schema.org out of the box — ceux are outside Nuxt’s propre primitives (useHead,
useSeoMeta, route rules, rendering modes). The community fills que gap with
Harlan Wilton’s @nuxtjs/seo — a separately-installed, third-party umbrella
package (nuxtseo.com, currently at v5.x, actively maintained, targeting Nuxt
3,16+ and Nuxt 4) que bundles six modules. Installing it donne vous sitemap,
robots, OG-image, and schema generation — it doesn’t by itself guarantee the
output is correct pour votre routes; vérifier ce que it produces the même façon you’d
vérifier anything sinon:
| Module | Ce que it fait |
|---|---|
@nuxtjs/robots | robots.txt + meta robots + X-Robots-Tag headers |
@nuxtjs/sitemap | Auto XML sitemaps from pages + dynamic routes |
nuxt-og-image | Dynamic OG images (a Vue template → an image) |
nuxt-schema-org | Schema.org JSON-LD données structurées |
nuxt-seo-utils | URL canoniques, breadcrumbs, defaults |
nuxt-link-checker | Build-time broken-link detection |
Install the whole bundle with npx nuxt module add seo, or grab individual modules
(npx nuxt module add sitemap robots). A few behaviors worth knowing:
@nuxtjs/sitemapauto-generates from votrepages/directory plus dynamic routes, splits into a sitemap index automatically past 50 000 URLs, supports i18n multi-language sitemaps, and has built-in IndexNow prise en charge. Un chose to obtenir correct: Google ignoreschangefreqandpriority; seulement an accuratelastmodmatters, and seulement quand content genuinely changements.@nuxtjs/robotsgeneratesrobots.txt, the robots meta tag, and theX-Robots-Tagheader — and by par défaut it disallows tout robots d’exploration on non-production environments, qui is exactly the staging-indexation footgun que bites headless builds. It aussi donne vous per-bot rules, so vous pouvez block GPTBot specifically pendant que leaving everyone sinon alone (be intentional — block an AI robot d’exploration and it won’t cite vous).nuxt-seo-utilshandles URL canoniques and, usefully, strips tracking parameters (utm_*,fbclid,gclid) from canonicals automatically.
nuxt/image and Core Web Vitals
@nuxt/image is the image module: automatic responsive srcset, modern formats
(WebP/AVIF), built-in optimization via CDN providers, and lazy chargement. Two
rules carry la plupart of the SEO valeur:
- Jamais lazy-load the LCP image. Votre hero image devrait charger eagerly; lazy-loading it delays votre Plus grand affichage de contenu.
- Toujours définir
widthandheightso le navigateur reserves space and vous don’t prendre a Décalage cumulatif de mise en page hit.
<NuxtImg
src="/hero.jpg"
width="1200"
height="630"
alt="Descriptive alt text"
:loading="isHeroImage ? 'eager' : 'lazy'"
format="webp"
/>The 2026 targets to aim pour (p75): LCP ≤ 2,5s, INP ≤ 200ms, CLS ≤ 0,1. On Nuxt apps,
INP is the un que tends to suffer parce que hydration creates input lag — qui is
exactly ce que Nuxt Islands and <NuxtIsland> are pour.
Nuxt Content + SEO
Si you’re en utilisant @nuxt/content (the markdown/MDX content module), the integration
with @nuxtjs/seo is straightforward but has un ordering gotcha: charger @nuxtjs/seo
avant @nuxt/content in votre modules array. Vous pouvez alors définir SEO in content
frontmatter (title, description, robots, ogImage, schemaOrg) and pull it
into votre [slug].vue template with useSeoMeta() après fetching le contenu. Ce
is the Nuxt-native version of the headless-CMS pattern, and the même “rebuild ce que the
plugin did” discipline s’applique.
Courant Nuxt SEO mistakes
- En utilisant SPA mode (
ssr: false) pour content vous vouloir indexé. The la plupart expensive mistake — and the un que rend vous invisible to AI robots d’exploration. - Relative URLs pour OG images.
ogImagedoit be an absolute URL or social previews break. useSeoMeta()in a layout au lieu de lune page — generic tags overwrite page-specific ones.- Pas verifying rendered HTML — View Source ≠ DevTools ≠ ce que Google rendered. Utiliser Inspection d’URL.
- Blocking JS/CSS in
robots.txt— Google won’t render from blocked fichiers. - Leaving the staging
noindex/disallow in placer après launch (or, conversely, forgetting@nuxtjs/robotsblocks non-prod by par défaut and wondering pourquoi prod is fine but a custom env isn’t). - Lazy-loading the LCP image — tanks votre LCP.
- Manquant
width/heighton images — CLS. changefreq/priorityin sitemaps — Google ignores les; seulementlastmodcounts.- Reaching pour dynamic rendering. Google deprecated it — “dynamic rendering is a workaround and not a long-term solution” — and it seulement sert the engines vous configurer it pour, manquant Bing and every AI robot d’exploration. With Nuxt vous jamais besoin it: SSR and SSG déjà give robots d’exploration complet HTML.
llms.txt and AEO
llms.txt is a plain-text fichier — robots.txt’s cousin — que helps AI outils navigate
votre content. The nuxt-llms module auto-generates /llms.txt and /llms-full.txt
from Nuxt Content. As of late 2025 its principal consumers are MCP servers and AI coding
outils (Cursor, Claude Code) plutôt que ChatGPT or Perplexity directement, and it’s la plupart
utile pour documentation sites and technical blogs — moins so pour e-commerce or news.
Worth ajout si you’re a docs/dev site; pas a priority sinon.
Où ce fits
Nuxt SEO is really a concrete application of JavaScript SEO via Nuxt’s propre conventions — and it overlaps heavily with the SEO pour a CMS headless topic quand votre Nuxt frontend pulls from a headless backend. The principles don’t modifier; Nuxt simplement donne vous bon defaults and a strong module ecosystem to implement les with.
AI summary
A condensed prendre on the Avancé version:
- Nuxt is Vue’s meta-framework, and its SEO advantage is un par défaut:
rendu côté serveur. A route que garde que par défaut ships complet HTML,
pas the vide shell a plain Vue SPA ships — but it’s a per-route outcome, pas a
project-wide guarantee.
ssr: falseor arouteRulesoverride peut flip quelconque route to CSR or hybrid, so vérifier the réel route. - Rendering strategy is the foundation, decided per route — it decides
everything avant meta, schema, or sitemaps. Modes: SSR (par défaut), SSG
(
nuxt generate), hybrid (routeRules), SPA (ssr: false, éviter pour indexé content), edge. - Hybrid
routeRulesmix modes per URL;swr/isrregenerate in the background; Nuxt Islands cut hydration cost and aider INP. - Googlebot crawls → renders (queued, pas instant) → indexes; takes the la plupart restrictive directive à travers raw vs. rendered HTML. Rendering is ~20× explorer cost. SSR/SSG fermer the timing gap.
- AI-crawler rendering is provider-specific — CSR dépend on client execution que n’est pas covered by un shared contract, so SSR/SSG maximizes AI visibility.
- Au-delà first-load HTML: vérifier hydration/payload independently (server HTML
≠ proof of successful hydration or client-nav parity), watch pour
<ClientOnly>hiding content from robots d’exploration même on universal routes, and confirmer direct HTTP status/redirections withcurl -Iplutôt que trusting a client-rendered error page. - Nitro and deployment presets (Node, Cloudflare, Vercel, Netlify, static) peut differ in runtime APIs, mise en cache, streaming, and regions — tester cache headers and production parity per route, don’t assume presets behave identically.
- Meta tags:
useSeoMeta()pour le SEO/social (type-safe),useHead()pour the rest of the head, server-only variants quand reactivity isn’t nécessaire. Couche:nuxt.config.ts→app.vue→ page. Don’t putuseSeoMeta()in a layout. OG images besoin absolute URLs. Appel an API proves the API ran, pas ce que a direct réponse emits — confirmer with View Source/curl. @nuxtjs/seo(Harlan Wilton) is an optional third-party toolkit (v5.x, actively maintained, Nuxt 3,16+/4.x) — pas partie of Nuxt core. It bundles robots, sitemap, OG image, Schema.org, canonical, and link-checker, but installing it doesn’t itself prove correct output. Sitemap: seulementlastmodmatters. Robots: blocks non-prod by par défaut; per-bot AI rules.@nuxt/image+ CWV: jamais lazy-load the LCP image; toujours définirwidth/height(CLS). Targets: LCP ≤ 2,5s, INP ≤ 200ms, CLS ≤ 0,1.- Don’t utiliser dynamic rendering — Google deprecated it; Nuxt’s SSR/SSG déjà serve complet HTML.
Documentation officielle
Primary-source documentation from Nuxt and the moteur de recherches.
Nuxt
- Nuxt — Rendering Concepts — universal, client-side, and hybrid (
routeRules) rendering, and pourquoi robots d’exploration préférer server-rendered routes. - Nuxt — SEO and Meta (getting commencé) —
useSeoMeta(),useHead(), and head management. - Nuxt —
useSeoMetacomposable — the type-safe meta API référence, notamment server-only usage. - Nuxt — Server Engine (Nitro) — deployment presets, cross-platform output, and où runtime/mise en cache behavior peut diverge.
- Nuxt — Nuxt Lifecycle — server render, payload transfer, and hydration as distinct stages.
- Nuxt Image —
<NuxtImg>, responsive formats, and provider config pour Core Web Vitals. @nuxtjs/seoon Nuxt Modules — the module catalog entry: current version, downloads, and que it’s a separately-installed package.
- Comprendre the JavaScript SEO basics — the explorer → render → index pipeline and crawlable liens (framework-agnostic; Google’s docs don’t mention Nuxt by nom).
- Dynamic Rendering (deprecated workaround) — pourquoi Google deprecated it and ce que to utiliser à la place (SSR, static rendering, hydration).
Quotes from the source
On-the-record statements from Nuxt, Google, and my propre writing. Chaque search-engine / Nuxt lien is a deep lien que jumps to the quoted passage on the source page.
Nuxt — rendering pour le SEO
- “Indexing and updating the content delivered via client-side rendering takes more time.” — Nuxt rendering docs. Jump to quote
- “Web crawlers can directly index the page’s content, which makes Universal rendering a great choice for any content that you want to index quickly.” — Nuxt rendering docs. Jump to quote
Google — JavaScript processing & dynamic rendering
- “Google processes JavaScript web apps in three main phases: 1. Crawling 2. Rendering 3. Indexing.” — Recherche Google Central docs. Jump to quote
- “Dynamic rendering is a workaround and not a long-term solution for problems with JavaScript-generated content in search engines. Instead, we recommend that you use server-side rendering, static rendering, or hydration as a solution.” — Recherche Google Central docs. Jump to quote
Patrick Stox (my propre fonctionner — JavaScript SEO: A Definitive Guide)
- “Any kind of SSR, static rendering, and prerendering setup is going to be fine for search engines. Gatsby, Next, Nuxt, etc., are all great.”
- “There is no fixed timeout for the renderer… It’s really patient, and you should not be concerned.”
- “JavaScript is not bad for SEO, and it’s not evil. It’s just different from what many SEOs are used to.”
Nuxt SEO checklist
A rapide réussir to confirmer a Nuxt site is définir up pour search and AI robots d’exploration:
- Content vous vouloir indexé is rendered on le serveur or at construire temps (SSR or
SSG) — pas SPA mode (
ssr: false). - Confirmed via View Source que important content is in the raw HTML, and via Inspection d’URL que Google renders it.
-
useSeoMeta()is in page components, pas a shared layout overwriting page tags. -
ogImageuses an absolute URL (pas relative). - A title template is définir une fois in
app.vue; per-page titles/descriptions are unique. -
@nuxtjs/sitemapis generating an XML sitemap;lastmodis accurate and you’re pas relying onchangefreq/priority. -
@nuxtjs/robotsis configuré; the non-prod auto-disallow isn’t accidentally applying to production. -
robots.txtfait pas block votre JS/CSS. - Canonicals are absolute and per-page (
nuxt-seo-utils). - LCP image loads eagerly (pas lazy); tout images have
width/height(CLS). - Réel
<a href>liens /<NuxtLink>pour navigation — aucun<div @click>routing. - Si en utilisant
@nuxt/content,@nuxtjs/seois chargé avant it in the modules array. - Dynamic rendering is pas in utiliser anywhere.
The mental models
1. Rendering strategy comes premier. Meta tags, schema, and sitemaps are downstream of un decision: how the HTML obtient produced. Réponse “is ce content server-rendered, statically generated, or client-rendered?” avant debugging anything sinon.
2. SSR is the par défaut — votre job is mostly pas to break it.
Nuxt points the defaults the correct façon. La plupart Nuxt SEO échecs are someone setting
ssr: false, blocking JS/CSS, or injecting signals via JavaScript que conflict with
the raw HTML.
3. Pick the rendering mode by content type.
- Mostly-static (blog, docs, marketing) → SSG (
prerender: true). - Always-fresh / dynamic → SSR.
- Hourly/daily content wanting static speed →
swr/isr. - Behind a login, non indexée → SPA (
ssr: false) is fine. - Public content vous vouloir ranked or cited by AI → jamais SPA.
4. HTML-first, JS-second pour every signal. Content, meta, canonical, robots directives, and liens tout belong in the server-rendered HTML. Google takes the la plupart restrictive directive à travers raw vs. rendered; AI robots d’exploration voir seulement the raw. JS-injected SEO is a fallback, pas the plan.
5. Utiliser the modules, but comprendre ce que ils do.
@nuxtjs/seo saves fonctionner, but the non-prod robots auto-disallow, the lastmod-seulement
sitemap reality, and absolute-URL canonicals are encore yours to obtenir correct.
Nuxt SEO — cheat sheet
Rendering modes
| Mode | Config | SEO | Meilleur pour |
|---|---|---|---|
| Universal / SSR | ssr: true (par défaut) | ✅ Meilleur | Dynamic / personalized |
| Static / SSG | nuxt generate | ✅ Meilleur | Blogs, docs, marketing |
| Hybrid | routeRules | ✅ Meilleur | Grand mixed-content sites |
| SPA / CSR | ssr: false | ⚠️ Poor pour indexation | Dashboards, admin |
| Edge-side | Deploy target | ✅ Low TTFB | Global performances |
Composables
| Utiliser | Reach pour |
|---|---|
| SEO + social meta tags | useSeoMeta() (type-safe) |
| Title templates, scripts, lien tags, html attrs | useHead() |
| Skip client re-execution pour static meta | useServerHead() |
@nuxtjs/seo modules
| Module | Job |
|---|---|
@nuxtjs/robots | robots.txt + meta robots + X-Robots-Tag (blocks non-prod by par défaut) |
@nuxtjs/sitemap | XML sitemap (seulement lastmod matters; auto index past 50k URLs) |
nuxt-og-image | Dynamic OG images |
nuxt-schema-org | JSON-LD données structurées |
nuxt-seo-utils | URL canoniques (strips utm_*/fbclid/gclid), breadcrumbs |
nuxt-link-checker | Build-time broken liens |
Fast rules
- Install everything:
npx nuxt module add seo. - OG images: absolute URLs seulement.
- LCP image:
loading="eager"; tout images besoinwidth/height(CLS). - CWV targets: LCP ≤ 2,5s, INP ≤ 200ms, CLS ≤ 0,1.
- Jamais block JS/CSS in robots.txt.
- Dynamic rendering: deprecated — Nuxt’s SSR/SSG replace it.
- AI robots d’exploration: aucun JavaScript → SPA content is invisible to les.
Voir ce que a Nuxt page en réalité ships
The whole Nuxt SEO question reduces to un vérifier: is votre content in the raw HTML the server sends, or seulement après JavaScript runs? Si it’s in the raw HTML, you’re server-rendering and robots d’exploration (and AI bots) peut lire it.
Récupérer the raw HTML and regarder pour votre content
macOS / Linux:
# Raw HTML as the server sends it — before any client JS runs
curl -sL -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" \
https://example.com/page/ -o raw.html
# Is your headline actually in the server HTML? (empty = client-rendered)
grep -o "Your headline text" raw.htmlWindows (PowerShell):
$ua = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
Invoke-WebRequest -Uri "https://example.com/page/" -UserAgent $ua -OutFile raw.html
Select-String -Path raw.html -Pattern "Your headline text"Si votre text montre in le navigateur but is manquant from raw.html, lune page is
client-rendered — flip the route to SSR or prerender it. (A plain curl can’t run JS;
pour the rendered DOM utiliser Inspection d’URL or a headless-Chrome robot d’exploration.)
Confirmer vous aren’t blocking JS/CSS
macOS / Linux:
curl -sL https://example.com/robots.txt | grep -iE "disallow.*\.(js|css)|Disallow:\s*/(_nuxt|_ipx|assets)"A Disallow matching /_nuxt/ (Nuxt’s construire output) or /_ipx/ (the @nuxt/image
optimizer) va break rendering — almost toujours a mistake.
Static config snippet (nuxt.config.ts)
export default defineNuxtConfig({
modules: ['@nuxtjs/seo'], // robots, sitemap, og-image, schema-org, utils
site: { url: 'https://mysite.com' }, // required for absolute canonicals + sitemap
routeRules: {
'/blog/**': { prerender: true }, // SSG for content
'/admin/**': { ssr: false }, // SPA for the dashboard (won't be indexed)
},
}) Outils pour Nuxt SEO
- Inspection d’URL (Recherche Google Console) — the source of truth. Run a live tester and vérifier the rendered HTML, screenshot, and page resources to confirmer votre Nuxt content en réalité rendered and nothing’s blocked.
@nuxtjs/seo/ nuxtseo.com — Harlan Wilton’s module bundle; the dev outils panel montre votre generated robots, sitemap, schema, and OG images in development.- Nuxt DevTools — inspect head tags, route rules, and qui rendering mode chaque route is en utilisant.
- Résultats enrichis Tester — confirmer
nuxt-schema-orgJSON-LD is présent in the rendered output après quelconque rendering modifier. - Ahrefs Site Audit / Screaming Frog (JS-rendering mode) — explorer with JS rendering on vs. off to diff raw vs. rendered HTML à travers the whole Nuxt app and catch CSR gaps.
- Lighthouse / PageSpeed Insights — Core Web Vitals (LCP, INP, CLS) pour the
@nuxt/imageand Nuxt Islands fonctionner. - Bing Webmaster Outils — Bing’s explorer/index view and où IndexNow submissions montrer up.
Nuxt SEO mistakes to éviter
Concrete mistakes que montrer up repeatedly on réel Nuxt sites — prevent ces avant ils ship, plutôt que diagnosing les après trafic drops.
Flipping ssr: false on content vous vouloir indexé
The unique la plupart expensive Nuxt SEO mistake. SPA mode ships the même empty-shell problem plain Vue has — moteur de recherches have to wait pour a render queue to fill in the content. AI-crawler rendering contracts vary by provider, so a robot d’exploration que récupère seulement the initial HTML va miss lune page content.
Pourquoi it’s incorrect: you’re voluntarily giving up the un par défaut (SSR) que rend Nuxt easier to index que plain Vue.
Que faire à la place: leave ssr: true (the par défaut) pour anything public and
indexable. Reserve ssr: false pour genuinely non-indexed surfaces — logged-in
dashboards, admin panels — via routeRules, pas a global config flip.
Putting useSeoMeta() in a shared layout
Setting title/description à l’intérieur a layout component feels efficient — un placer,
s’applique everywhere — but it signifie every page que uses que layout obtient the même
generic tags, and page-level useSeoMeta() calls peut obtenir overwritten selon
render order.
Pourquoi it’s incorrect: unique, page-specific titles and descriptions are basic relevance signals; a layout-level par défaut collapses les tout to un string.
Que faire à la place: définir global fallbacks une fois in app.vue (title template, OG
defaults), alors appel useSeoMeta() à l’intérieur chaque page component with que page’s
réel title and description.
Shipping a relative ogImage URL
ogImage: '/social.png' semble fine in le navigateur and complètement fails quand
Facebook, LinkedIn, or X essayer to récupérer it, parce que social robots d’exploration don’t resolve
relative paths contre votre site.
Pourquoi it’s incorrect: social platforms besoin an absolute URL to récupérer the image; a relative chemin resolves to nothing from leur side.
Que faire à la place: toujours réussir a complet https:// URL, and définir site.url in
nuxt.config.ts so @nuxtjs/seo’s modules peut construire absolute URLs pour vous
automatically.
Reaching pour dynamic rendering
Serving a prerendered snapshot to connu bots and the SPA to everyone sinon was a legitimate workaround années ago. Google has since appelé it out directement: “dynamic rendering is a workaround and pas a long-term solution.”
Pourquoi it’s incorrect: it seulement sert the bots vous configurer, misses everything sinon (Bing, la plupart AI robots d’exploration), and adds réel infrastructure to maintain — pour a problem Nuxt’s propre SSR/SSG déjà solves.
Que faire à la place: utiliser SSR or nuxt generate and skip dynamic rendering
entirely. There’s aucun scenario où a Nuxt site nécessite it.
Blocking /_nuxt/ or /_ipx/ in robots.txt
A blanket Disallow: /assets/ or an overzealous robots rule peut accidentally catch
Nuxt’s construire output directory (/_nuxt/) or the @nuxt/image optimizer chemin
(/_ipx/).
Pourquoi it’s incorrect: si Googlebot can’t récupérer the JS/CSS que builds lune page, it can’t confirmer votre SSR output is ce que it semble comme — and quelconque client-side enhancements silently arrêter rendering pour it.
Que faire à la place: jamais disallow build-output or image-optimizer paths. Vérifier
robots.txt après every deploy que touches routing or module config, pas simplement une fois
at launch.
Leaving the non-production robots block active après launch
@nuxtjs/robots disallows tout robots d’exploration on non-production environments by par défaut —
a bon safety net pour staging, but it reads environment variables to decide, and a
misconfigured NODE_ENV or preview-deploy setting peut faire it fire in production
aussi.
Pourquoi it’s incorrect: le site semble complètement fine in a navigateur pendant que robots.txt
quietly disallows everything, and nothing obtient indexé jusqu’à someone notices.
Que faire à la place: après quelconque deploy or environment modifier, récupérer
https://yoursite.com/robots.txt directement and confirmer it’s pas a blanket
Disallow: /.
Standing KPIs pour Nuxt SEO
The ongoing numbers to track une fois votre rendering setup is correct — pas one-time checks, but recurring signals que catch regressions as the app changements.
Core Web Vitals (LCP, INP, CLS)
Ce que it indique vous: si réel visitors are getting a fast, stable page — directement affected by Nuxt Islands/hydration cost (INP) and image-loading choices (LCP, CLS).
How to pull it: field données from the Chrome UX Report via /outils/crux-tracker/ or /outils/cwv-checker/; lab données from Lighthouse pour pre-release checks.
Benchmark / realistic range: Google’s publié “good” thresholds are LCP ≤ 2,5s, INP ≤ 200ms, CLS ≤ 0,1 at the 75th percentile — ceux are the réussir/échouer lines CrUX itself uses, pas a number I’m inventing. Où vous land dans “good” dépend heavily on votre image weight and how beaucoup vous hydrate.
Cadence: CrUX field données updates on a rolling 28-day window — vérifier monthly, and immédiatement après quelconque modifier to images, fonts, or hydration.
Rendered-vs-raw HTML parity
Ce que it indique vous: si le contenu moteur de recherches and AI robots d’exploration peut
en réalité voir (the raw HTML) matches ce que a visitor sees in le navigateur (the rendered
DOM) — the core Nuxt SEO risk si ssr obtient flipped or a route regresses to CSR.
How to pull it: /outils/render-gap/ diffs raw vs. rendered HTML pour une URL; pour the authoritative Google-side view, utiliser GSC’s Inspection d’URL → “View Crawled Page.”
Benchmark / realistic range: ce is a binary vérifier, pas a range — votre clé content (headline, corps copy, lien internes) devrait be présent in the raw HTML, complet arrêter. Quelconque gap on une page vous vouloir indexé or cited is a regression to fix, pas a number to tolerate.
Cadence: après every deploy que touches routeRules, layouts, or the ssr
config; spot-check clé templates monthly sinon.
Index coverage (Page Indexation report)
Ce que it indique vous: how nombreux of votre submitted URLs Google has en réalité indexé, and pourquoi the rest were excluded (duplicate, crawled-not-indexed, blocked, etc.) — the downstream signal que rendering problems eventually surface as.
How to pull it: Search Console → Page Indexation report, filtered to votre Nuxt site’s URL patterns.
Benchmark / realistic range: there’s aucun universal sain percentage — it dépend on how nombreux near-duplicate or thin URLs votre route structure generates. Watch the trend and the exclusion raisons, pas a target number.
Cadence: weekly during and après a rendering-mode migration; monthly sinon.
AI robot d’exploration accès
Ce que it indique vous: si GPTBot, ClaudeBot, PerplexityBot, and similaire AI
robots d’exploration peut en réalité récupérer votre pages — separate from Google, since ces bots
généralement don’t execute JavaScript and lire seulement the raw HTML votre robots.txt
lets les reach.
How to pull it: /outils/ai-crawler-checker/ to confirmer aucun AI user-agent is disallowed; server logs to confirmer the bots are en réalité requesting pages, pas simplement permitted to.
Benchmark / realistic range: there’s aucun citation-rate benchmark I peut give vous honestly — how souvent an AI réponse engine cites vous dépend on the requête space and competition, pas something Nuxt configuration contrôle directement. Track accès (allowed vs. blocked), pas a made-up citation percentage.
Cadence: après every robots.txt or @nuxtjs/robots config modifier; monthly log
spot-check sinon.
Testez vos connaissances: Nuxt SEO
Five rapide questions on optimizing a Nuxt site pour search. Pick an réponse pour chaque, alors vérifier.
Ressources utiles
My connexe writing
- JavaScript SEO: A Definitive Guide — my complet guide to rendering, DOM parity, the most-restrictive-directive rule, and pourquoi SSR/static/prerender (Nuxt inclus) are tout fine pour search.
- The Beginner’s Guide to SEO technique — où rendering and exploration fit in the bigger picture.
My speaking
- JavaScript SEO — Ungagged 2019 (SlideShare) — Googlebot’s evergreen Chromium, the ~20× explorer cost of rendering, History API over hash routing, and how Google handles JS-injected canonicals. (Standing disclaimer: the dynamic-rendering advice in que deck is now outdated — Google deprecated it.)
From autour the industry
- Nuxt — Rendering Concepts (official) — universal vs. rendu côté client and pourquoi robots d’exploration préférer SSR.
- Nuxt — SEO and Meta (official) —
useSeoMeta()anduseHead(), the getting-started référence. - Apprendre SEO with Nuxt (Harlan Wilton / nuxtseo.com) — the la plupart comprehensive developer-focused Nuxt SEO guide, kept current.
- harlan-zw/nuxt-seo (GitHub) — the source pour the
@nuxtjs/seomodule bundle. - Nuxt Image (official) —
<NuxtImg>and Core Web Vitals optimization. - Optimize Nuxt Performances (DebugBear) — a practitioner walkthrough of Nuxt Core Web Vitals fixes.
- Nuxt 3 Rendering Modes (RisingStack) — a technical comparison of SSR, SSG, and hybrid rendering.
- r/TechSEO — the community pour rendering/indexation debugging.
Videos
- Recherche Google Central (YouTube) — Martin Splitt’s JavaScript SEO series is the meilleur official walkthrough of how Google crawls, renders, and indexes JS apps; it’s framework-agnostic but s’applique directement to Nuxt. Channel
Journal des modifications
Mis à jour le 27 juil. 2026.
Résumé éditorial et détails enregistrés des changements.Détails des changements
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
Comparaison complète indisponible — aucun instantané antérieur n’a été archivé pour cette révision.
Mis à jour le 18 juil. 2026.
Résumé éditorial et détails enregistrés des changements.Détails des changements
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
Comparaison complète indisponible — aucun instantané antérieur n’a été archivé pour cette révision.