Nuxt SEO
Nuxt ships server-side rendering by default, but that's a per-route setting, not a guarantee — full HTML to crawlers only on routes that keep it. Rendering modes, useSeoMeta(), the @nuxtjs/seo toolkit, hydration and Nitro caveats, Core Web Vitals, and the mistakes that quietly cost you.
1 evidence signal on this page
- Related live toolCore Web Vitals History & Competitor Comparison
Nuxt server-renders pages by default, so a route that keeps that default gives crawlers a complete HTML document instead of the empty shell a plain Vue SPA ships — but it's a per-route setting: routeRules or a global ssr:false can flip any route to CSR, so verify the actual route rather than assuming from the framework name. The foundational decision is rendering mode per route — SSR (default), SSG via nuxt generate, or hybrid route rules — because meta tags, schema, and sitemaps all come after that. Use useSeoMeta() for meta, treat Harlan Wilton's @nuxtjs/seo bundle as an optional third-party toolkit (not Nuxt core) for robots/sitemap/OG/schema/canonical, never reach for dynamic rendering (Google deprecated it), verify hydration/payload and Nitro deployment-preset/cache behavior independently of server HTML, and remember that AI-crawler rendering contracts vary by provider — SSR/SSG puts content in raw HTML and maximizes coverage.
TL;DR — Nuxt is the framework built on top of Vue, and it’s good for SEO for one main reason: on a route that keeps the default, it builds pages on the server, so search engines get a finished HTML page instead of a blank one they’d have to fill in themselves. That’s a per-route setting, not a site-wide guarantee —
routeRulesor a globalssr: falsecan turn any given route back into a plain-Vue-style empty shell. Check the actual route, not just the project name. The most important choice you’ll make is how each route gets rendered; everything else (meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored., 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.) comes after that.
Why Nuxt is good for SEO — on the routes that keep the default
Vue, on its own, builds a single-page app: the server sends an almost-empty HTML shell, and JavaScript fills in the content once it runs in the browser. That’s tricky for search, because the page looks empty until the JavaScript executes.
Nuxt is Vue’s “meta-framework” — a fuller toolkit built around Vue — and its
default fixes that problem. Nuxt renders your pages on the server first
(server-side renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM., or SSR), so when Google or a visitor asks for a page
on a route that hasn’t been switched off SSR, they get the complete HTML right
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 No waiting for JavaScript. That’s the single
biggest reason a Nuxt site can be easier to get indexedStoring 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. than a plain Vue app —
but it’s a route-by-route outcome, not something the framework name guarantees.
A route with ssr: false, or one that leans on <ClientOnly> for its main
content, gives up that advantage and ships the same empty-shell problem plain
Vue has.
The one decision that matters most: rendering, per route
When someone asks for a specific page, where does its HTML get built? That’s a
routeRules-level question, not a project-wide one — a Nuxt app can mix modes
across routes. Nuxt gives you a few options:
- Server-side renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. (SSR) — the default. The server builds the full page on every request. Great for SEO.
- Static generation (SSG) — run
nuxt generateand Nuxt builds all your pages into plain HTML files ahead of time. Also great for SEO, and perfect for blogs and docs that don’t change every minute. - SPA mode — the page is built in the browser, like plain Vue. Avoid this for anything you want foundA 302 (\"Found\") is a temporary redirect: it forwards users to a new URL while telling search engines the original URL should stay in the index. It's a weak canonicalization signal, not the zero-equity dead end of SEO folklore. in search.
The good news is the defaults are already pointed the right way. You mostly have to avoid switching them off.
Adding titles and meta tags
In Nuxt you set your page titleThe 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. and meta descriptionThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through. with a built-in function called
useSeoMeta(). Evidence for this claim Nuxt provides useSeoMeta for defining SEO and social metadata. Scope: Current Nuxt composable. Confidence: high · Verified: Nuxt: useSeoMeta You drop it into a page and pass in your title, description, and
social-share image:
useSeoMeta({
title: 'My Page Title',
description: 'A short summary under about 160 characters',
})That’s the modern, recommended way. (There’s an older function called useHead()
that still works and is used for other things in the page’s <head>, but for SEO
meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored. reach for useSeoMeta().)
The optional add-on: the Nuxt SEO modules
Nuxt core doesn’t generate a robots.txt, an XML sitemapAn XML sitemap is a UTF-8 file listing the canonical URLs on your site (with optional lastmod) so search engines can discover and prioritize them. It's a discovery and diagnostic aid, not a guarantee of indexing — and Google ignores its priority and changefreq tags., social-share images,
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., or canonical URLs — those are jobs for separate, optional
packages, not something nuxt.config.ts gives you by default. A developer named
Harlan Wilton maintains a free, community bundle of those packages — installed as
@nuxtjs/seo — that covers all of them at once. It’s a third-party toolkit, not
part of Nuxt itself, so installing it doesn’t automatically make any of that
output correct; you still confirm the 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., robots rules, and schema it
generates match what you actually want.
The thing people get wrong
People assume “Vue/Nuxt can’t be in Google.” That was sort of true for plain Vue apps years ago — it isn’t true for Nuxt with its server rendering. The real mistakes are things like turning SSR off by accident, or blocking your JavaScript files so Google can’t build the page.
Want the deeper version — the full menu of rendering modes, the module ecosystem in detail, 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., and the common mistakes with fixes? Switch to the Advanced tab.
TL;DR — Nuxt’s default is server-side renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM., so a route that keeps that default gets a complete DOM instead of the empty shell a plain Vue SPA ships — but that’s a per-route outcome:
ssr: falseor arouteRulesoverride can turn any route into CSR or hybrid, so test the actual route, not the project name. RenderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. strategy is the foundational decision — SSR (default), SSG (nuxt generate), or hybridrouteRules— because meta, schema, and 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. all come after it. UseuseSeoMeta()for meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored. (useHead()for the rest of the head, server-only variants when you don’t need reactivity), and treat Harlan Wilton’s@nuxtjs/seobundle as an optional third-party toolkit for robots/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./OG/schema/canonical — not part of Nuxt core, and not proof its output is correct until you check it. Never use dynamic rendering (Google deprecated it). AI-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. rendering varies by provider — SSR/SSG maximizes raw-HTML coverage. Beyond the initial HTML, verify hydrationActivating server-rendered HTML in the browser by attaching JavaScript handlers./payload, Nitro deployment presets and cachingCaching stores a copy of a page or resource — in a browser, a CDN edge node, or a search crawler's own cache — so it can be served again without regenerating or re-downloading it. It isn't a direct ranking factor, but it feeds page speed and crawl efficiency., and direct HTTP status independently — server HTML alone doesn’t prove any of those. The usual JS-SEO rules still apply: real<a href>links, don’t block JS/CSS, watch rendered vs. raw HTML.
Nuxt is Vue’s answer to the SPA problem
Vue, by itself, ships a single-page application: an HTML shell plus JavaScript that builds the DOM in the browser. Nuxt is the meta-framework on top of Vue (running on the Nitro server engine in Nuxt 3, with Nuxt 4 following in 2025), and its whole reason for existing — from an SEO standpoint — is that it renders on the server by default. Every page arrives as a fully-formed HTML document, which is exactly what 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. wants to read without having to execute JavaScript first. Plain Vue SEO is its own topic with its own failure modes; here I’m assuming you’ve picked Nuxt precisely so you don’t have to fight the SPA problem.
This is the same point I make about JavaScript generally: “any kind of SSR, static rendering, and prerendering setup is going to be fine for search engines. Gatsby, Next, Nuxt, etc., are all great.” Nuxt’s defaults are pointed the right way. Most Nuxt SEONuxt SEO is the practice of optimizing Nuxt.js (Vue's meta-framework) apps so search engines and AI crawlers can crawl, render, and index them. Nuxt's big advantage is that it ships server-side rendering by default, so pages arrive as fully-formed HTML instead of an empty Vue SPA shell. problems are people turning those defaults off, or layering mistakes on top of them.
Rendering strategy is the foundation — decided per route, not per project
Before meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored., before schema, before sitemaps, the question that decides
everything is how does the HTML get produced for this specific route? Nuxt
documents universal (server) rendering as the app-wide default, but that default
isn’t a route-level guarantee: a global ssr: false switches the whole app to
client rendering, and routeRules can assign a different mode to any URL
pattern. “This is a Nuxt app” tells you nothing about how one particular page
renders — you have to check the route. Nuxt gives you five strategies:
| Mode | How you set it | SEO impact | Best for |
|---|---|---|---|
| Universal / SSR | Default (ssr: true) | Excellent — full HTML every request | Dynamic, personalized content |
| Static / SSG | nuxt generate | Excellent — HTML built at deploy time | Blogs, docs, marketing |
| Hybrid | routeRules per route | Excellent — mix per route | Large mixed-content sites |
| SPA / CSR | ssr: false | Poor for indexedStoring 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. content | Dashboards, admin panels |
| Edge-side | Deployment target | Excellent — low 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. | Global performance |
The official Nuxt docs are blunt about why client-side rendering is the wrong choice
for content: “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 updating the content delivered via client-side rendering
takes more time”, whereas with server (universal) rendering “web crawlersA 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. can
directly index the 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 for back-office, dashboards, and games — not anything
you want indexed.
Hybrid rendering is the power move for large sites. Route rules in
nuxt.config.ts let you set the rendering and caching 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
a page statically then refresh it in the background — ideal for high page-count
e-commerce or news where a full rebuild on every change isn’t practical. Nuxt
Islands (<NuxtIsland>) render components without shipping client-side JavaScript,
cutting hydration cost and helping INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. — the Core Web Vital that’s most often the
problem on Nuxt apps.
How to verify what you actually shipped: View Source shows the raw HTML the server sent; if your content is there, you’re server-rendering. DevTools’ Elements panel shows the rendered DOM. And GSC’s URL Inspection toolA Google Search Console feature that reports how Google sees one specific URL on a property you own. By default it shows the last-indexed snapshot; a separate \"Test live URL\" mode fetches the current version. shows what Google actually fetched and rendered — the source of truth. Don’t trust “it looks fine in my browser.”
How Googlebot handles a Nuxt app
Google processes any JavaScript app in three phases — crawl, render, index — and the catch is timing: rendering happens in a queue, not instantly. As I put it in my JavaScript SEO guide, the renderer is patient — “there is no fixed timeout for the renderer… It’s really patient, and you should not be concerned.” But patient isn’t the same as fast for fresh content. If you ship a client-rendered page, your content doesn’t exist for Google until that render wave runs; SSR and SSG close that gap because the HTML is complete on the first fetch.
Two more things matter at scale. Rendering JavaScript is expensive — from my 2019
JavaScript SEO talk (Ungagged), crawl costs go up by roughly 20× once Google has to render
(directional, but the order of magnitude still holds). And Google takes the most
restrictive directive across raw and rendered HTML — so a noindex injected by
JavaScript will win over an index in the raw HTML, and vice versa. A canonical
injected via JavaScript is respected only if there’s no canonical in the raw HTML
already. Keep your robots and canonical signals in the server-rendered HTML, which
Nuxt does for you when SSR is on.
The AI-crawler reality
This is the 2026 wrinkle. 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. — GPTBot, ClaudeBot, PerplexityBot, and the rest — generally don’t execute JavaScript at all. They index the raw HTML and nothing else. So a client-rendered Nuxt page is effectively invisible to AI answer engines. SSR or SSG isn’t just better for Google here; it’s the price of entry for answer engine optimization too. If you want your content cited by ChatGPT, Perplexity, or Claude, it has to be in the HTML on first fetch.
Beyond the initial HTML: payload, hydration, and status codes
Getting server HTML with your content in it is necessary but not sufficient — several things can still go wrong downstream of that first response, and “I checked View Source” doesn’t cover them:
- Payload and hydration. Universal rendering sends the HTML and a serialized data payload the client uses to hydrate — attach event listeners and pick up where the server left off — without re-fetching. Server HTML looking right doesn’t prove hydration succeeded, that client navigation reproduces the same content, or that the payload isn’t stale. If a page feels fine on first load but breaks after a client-side route change, that’s a hydration/payload problem, not a rendering-mode problem.
<ClientOnly>and browser-only content. Wrapping something in<ClientOnly>— common for browser-API-dependent widgets — means it’s absent from the server response even on an otherwise-universal route. If your main content, a key link, or your meta tags end up inside a client-only boundary, crawlers and AI bots that only read the raw HTML miss it, regardless of your rendering mode setting. Inspect the actual response, not just the rendering mode config.- Status codes and redirectsA 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. aren’t self-certifying. A Nuxt error page
rendering in the browser, or a
navigateTo()/composable-driven redirect, doesn’t by itself prove what HTTP status the direct server response sent. Google’s guidance is explicit that meaningful status codes matter for crawlingCrawling is how search engines use automated bots (like Googlebot and Bingbot) to discover URLs and download pages. A page has to be crawlable to be indexed, but crawling on its own isn't a ranking factor. and indexing — confirm the actual header withcurl -I, not what the client-rendered error page displays.
None of this is an argument against universal rendering — it’s the reminder that “the HTML is server-rendered” is the first check, not the last one.
Nitro, deployment presets, and cache boundaries
Nuxt’s server output is built by Nitro, and Nitro compiles differently depending on the deployment preset you target (Node server, Cloudflare, Vercel, Netlify, static, and others). That matters for SEO because presets and adapters can differ in runtime APIs available, caching behavior, streaming support, regional deployment, and filesystem access — a route rule or server handler that works under one preset isn’t guaranteed to behave identically under another. Two consequences worth testing explicitly rather than assuming:
- Cache keys and invalidation are route-specific, not automatic.
swrandisrroute rules cache and regenerate output, but a wrong cache key, missing invalidation, or a caching header set by your deployment platform can serve stale, personalized, or inconsistent HTML to crawlers. Check the actual response age and anyCache-Control/Ageheaders on a live URL, not just therouteRulesconfig. - Production parity isn’t guaranteed by staging behavior. A route rendering correctly in local dev or a preview deployment doesn’t confirm the production preset produces the same output — server routes, redirects, and error handling live in Nitro’s server layer, and that layer is the part most likely to differ by target. Test the production URL directly after any deployment change, the same way you’d verify rendering mode.
Meta tags: useSeoMeta() and useHead()
Nuxt’s head management runs on Unhead, and it gives you two composables for different jobs.
useSeoMeta() is the one to reach for for 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 avoid the classic 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.
bug of using name where you needed property:
useSeoMeta({
title: 'My Page Title',
ogTitle: 'My Page Title',
description: 'Page description under ~160 chars',
ogDescription: 'Page description under ~160 chars',
ogImage: 'https://mysite.com/og-image.png', // must be an absolute URL
twitterCard: 'summary_large_image',
})useHead() is the general-purpose head tool for everything else — scripts, link
tags, body attributes, and title templates:
useHead({
titleTemplate: '%s · My Site Name',
htmlAttrs: { lang: 'en' },
})The reliable layering pattern is: static defaults (charset, viewport, faviconA favicon (\"favorite icon\") is the small square image that represents a website — shown in browser tabs, bookmarks, and history, and (when the requirements are met) next to a site's listing in Google and Bing search results. It's declared with an HTML <link rel=\"icon\"> tag in the <head>. It is not a ranking factor, but it affects brand recognition and click-through rate.) in
nuxt.config.ts → site-wide title template and global OG defaults in app.vue →
page-specific overrides via useSeoMeta() in the page component. A common bug is
putting useSeoMeta() in a layout instead of the page, which overwrites specific
page tags with generic ones. And since search engines read the initial load, SEO meta
generally doesn’t need to be reactive — useServerHead() skips the client-side
re-execution.
Which API, and what it actually proves:
| API | Scope | Reactive? | What it proves about output |
|---|---|---|---|
useSeoMeta() | Flat, typed SEO/social meta only | Yes (default) | Sets typed properties correctly — not that the route is unique, canonical, or indexable; you still own that logic |
useHead() | Anything in <head> — scripts, links, attrs, title template | Yes (default) | General head control; same caveat — API use isn’t proof of a correct server response |
useServerHead() / server-only calls | Same as above | No — server only, skips client re-execution | Confirms the tag ships once in server HTML; doesn’t confirm client navigation re-sets it if you rely on it there |
Calling one of these composables tells you the API ran — it doesn’t by itself tell
you what a direct server response or a client-side route change actually emits.
Confirm with View Source or curl, not just “I called useSeoMeta().”
The @nuxtjs/seo module ecosystem (Harlan Wilton) — optional, not core
Nuxt core doesn’t ship a sitemap, a robots.txt, OG image generation, or
Schema.org out of the box — those are outside Nuxt’s own primitives (useHead,
useSeoMeta, route rules, rendering modes). The community fills that 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) that bundles six modules. Installing it gives you sitemap,
robots, OG-image, and schema generation — it doesn’t by itself guarantee the
output is correct for your routes; verify what it produces the same way you’d
verify anything else:
| Module | What it does |
|---|---|
@nuxtjs/robots | robots.txt + meta robots + X-Robots-Tag headers |
@nuxtjs/sitemap | Auto XML sitemapsAn XML sitemap is a UTF-8 file listing the canonical URLs on your site (with optional lastmod) so search engines can discover and prioritize them. It's a discovery and diagnostic aid, not a guarantee of indexing — and Google ignores its priority and changefreq tags. from pages + dynamic routes |
nuxt-og-image | Dynamic OG images (a Vue template → an image) |
nuxt-schema-org | Schema.org JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. 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. |
nuxt-seo-utils | Canonical URLs, breadcrumbsBreadcrumbs are a secondary navigation trail (Home > Category > Page) that shows where a page sits in a site's hierarchy. They create internal links that pass PageRank, and when marked up with BreadcrumbList structured data they can drive the path Google shows in desktop search results., 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 yourpages/directory plus dynamic routes, splits into a sitemap indexA sitemap index is a sitemap of sitemaps — a single file that lists your other sitemap files instead of listing URLs directly. It's how large sites stay under the 50,000-URL / 50MB-per-sitemap limit while submitting just one file. automatically past 50,000 URLs, supports i18n multi-language sitemaps, and has built-in 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. support. One thing to get right: Google ignoreschangefreqandpriority; only an accuratelastmodmatters, and only when content genuinely changes.@nuxtjs/robotsgeneratesrobots.txt, the 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., and theX-Robots-Tagheader — and by default it disallows all crawlers on non-production environments, which is exactly the staging-indexation footgun that bites headless builds. It also gives you per-bot rules, so you can block GPTBot specifically while leaving everyone else alone (be intentional — block an AI crawler and it won’t cite you).nuxt-seo-utilshandles canonical URLs 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 through CDN providers, and lazy loadingLazy loading defers loading of off-screen or non-critical resources — usually images and iframes — until they're about to enter the viewport. The native way to do it is the loading=\"lazy\" HTML attribute, which needs no JavaScript.. Two
rules carry most of the SEO value:
- Never lazy-load the 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. image. Your hero image should load eagerly; lazy-loading it delays your Largest Contentful Paint.
- Always set
widthandheightso the browser reserves space and you don’t take a Cumulative Layout Shift hit.
<NuxtImg
src="/hero.jpg"
width="1200"
height="630"
alt="Descriptive alt text"
:loading="isHeroImage ? 'eager' : 'lazy'"
format="webp"
/>The 2026 targets to aim for (p75): LCP ≤ 2.5s, INP ≤ 200ms, CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good. ≤ 0.1. On Nuxt apps,
INP is the one that tends to suffer because hydration creates input lag — which is
exactly what Nuxt Islands and <NuxtIsland> are for.
Nuxt Content + SEO
If you’re using @nuxt/content (the markdown/MDX content module), the integration
with @nuxtjs/seo is straightforward but has one ordering gotcha: load @nuxtjs/seo
before @nuxt/content in your modules array. You can then set SEO in content
frontmatter (title, description, robots, ogImage, schemaOrg) and pull it
into your [slug].vue template with useSeoMeta() after fetching the content. This
is the Nuxt-native version of the headless-CMSA content management system (CMS) is software that lets users create, manage, and publish digital content — like blog posts and pages — without writing raw code. WordPress, Drupal, and Joomla are the most common open-source CMS platforms. pattern, and the same “rebuild what the
plugin did” discipline applies.
Common Nuxt SEO mistakes
- Using SPA mode (
ssr: false) for content you want indexed. The most expensive mistake — and the one that makes you invisible to AI crawlers. - Relative URLs for OG images.
ogImagemust be an absolute URL or social previews break. useSeoMeta()in a layout instead of the page — generic tags overwrite page-specific ones.- Not verifying rendered HTML — View Source ≠ DevTools ≠ what Google rendered. Use URL Inspection.
- Blocking JS/CSS in
robots.txt— Google won’t render from blocked files. - Leaving the staging
noindex/disallow in place after launch (or, conversely, forgetting@nuxtjs/robotsblocks non-prod by default and wondering why prod is fine but a custom env isn’t). - Lazy-loading the LCP image — tanks your LCP.
- Missing
width/heighton images — CLS. changefreq/priorityin sitemaps — Google ignores them; onlylastmodcounts.- Reaching for dynamic rendering. Google deprecated it — “dynamic rendering is a workaround and not a long-term solution” — and it only serves the engines you configure it for, missing Bing and every AI crawler. With Nuxt you never need it: SSR and SSG already give crawlers complete HTML.
llms.txt and AEO
llms.txt is a plain-text file — 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.’s cousin — that helps AI tools navigate
your content. The nuxt-llms module auto-generates /llms.txt and /llms-full.txt
from Nuxt Content. As of late 2025 its primary consumers are MCP servers and AI coding
tools (Cursor, Claude Code) rather than ChatGPT or Perplexity directly, and it’s most
useful for documentation sites and technical blogs — less so for e-commerce or news.
Worth adding if you’re a docs/dev site; not a priority otherwise.
Where this fits
Nuxt SEO is really a concrete application of JavaScript SEOMaking sure search engines can crawl, render, and index content that depends on JavaScript. through Nuxt’s own conventions — and it overlaps heavily with the SEO for a 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. topic when your Nuxt frontend pulls from a headless backend. The principles don’t change; Nuxt just gives you good defaults and a strong module ecosystem to implement them with.
AI summary
A condensed take on the Advanced version:
- Nuxt is Vue’s meta-framework, and its SEO advantage is one default:
server-side renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM.. A route that keeps that default ships complete HTML,
not the empty shell a plain Vue SPA ships — but it’s a per-route outcome, not a
project-wide guarantee.
ssr: falseor arouteRulesoverride can flip any route to CSR or hybrid, so verify the actual route. - RenderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. strategy is the foundation, decided per route — it decides
everything before meta, schema, or 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.. Modes: SSR (default), SSG
(
nuxt generate), hybrid (routeRules), SPA (ssr: false, avoid for indexedStoring 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. content), edge. - Hybrid
routeRulesmix modes per URL;swr/isrregenerate in the background; Nuxt Islands cut hydrationActivating server-rendered HTML in the browser by attaching JavaScript handlers. cost and help INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good.. - 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. crawls → renders (queued, not instant) → indexes; takes the most restrictive directive across raw vs. rendered HTML. Rendering is ~20× crawl cost. SSR/SSG close the timing gap.
- AI-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. rendering is provider-specific — CSR depends on client execution that is not covered by one shared contract, so SSR/SSG maximizes AI visibilityLLM visibility (or AI visibility) is the aggregate measure of how often and how prominently a brand or page shows up in AI-generated answers — across AI Overviews, ChatGPT, Perplexity, Copilot, and Gemini. It's the AI-search analog of organic visibility, but it's driven by different signals..
- Beyond first-load HTML: verify hydration/payload independently (server HTML
≠ proof of successful hydration or client-nav parity), watch for
<ClientOnly>hiding content from crawlersA 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. even on universal routes, and confirm direct HTTP status/redirectsA 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. withcurl -Irather than trusting a client-rendered error page. - Nitro and deployment presets (Node, Cloudflare, Vercel, Netlify, static) can differ in runtime APIs, cachingCaching stores a copy of a page or resource — in a browser, a CDN edge node, or a search crawler's own cache — so it can be served again without regenerating or re-downloading it. It isn't a direct ranking factor, but it feeds page speed and crawl efficiency., streaming, and regions — test cache headers and production parity per route, don’t assume presets behave identically.
- Meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored.:
useSeoMeta()for SEO/social (type-safe),useHead()for the rest of the head, server-only variants when reactivity isn’t needed. Layer:nuxt.config.ts→app.vue→ page. Don’t putuseSeoMeta()in a layout. OG images need absolute URLs. Calling an API proves the API ran, not what a direct response emits — confirm with View Source/curl. @nuxtjs/seo(Harlan Wilton) is an optional third-party toolkit (v5.x, actively maintained, Nuxt 3.16+/4.x) — not part of Nuxt core. It bundles robots, 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., OG image, Schema.org, canonical, and link-checker, but installing it doesn’t itself prove correct output. Sitemap: onlylastmodmatters. Robots: blocks non-prod by default; per-bot AI rules.@nuxt/image+ CWV: never lazy-load the 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. image; always setwidth/height(CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good.). Targets: LCP ≤ 2.5s, INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. ≤ 200ms, CLS ≤ 0.1.- Don’t use dynamic rendering — Google deprecated it; Nuxt’s SSR/SSG already serve full HTML.
Official documentation
Primary-source documentation from Nuxt and the search engines.
Nuxt
- Nuxt — Rendering Concepts — universal, client-side, and hybrid (
routeRules) renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM., and why crawlersA 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. prefer server-rendered routes. - Nuxt — SEO and Meta (getting started) —
useSeoMeta(),useHead(), and head management. - Nuxt —
useSeoMetacomposable — the type-safe meta API reference, including server-only usage. - Nuxt — Server Engine (Nitro) — deployment presets, cross-platform output, and where runtime/cachingCaching stores a copy of a page or resource — in a browser, a CDN edge node, or a search crawler's own cache — so it can be served again without regenerating or re-downloading it. It isn't a direct ranking factor, but it feeds page speed and crawl efficiency. behavior can diverge.
- Nuxt — Nuxt Lifecycle — server render, payload transfer, and hydrationActivating server-rendered HTML in the browser by attaching JavaScript handlers. as distinct stages.
- Nuxt Image —
<NuxtImg>, responsive formats, and provider config for 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.. @nuxtjs/seoon Nuxt Modules — the module catalog entry: current version, downloads, and that it’s a separately-installed package.
- Understand the JavaScript SEO basics — the crawl → render → indexStoring 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. pipeline and crawlable links (framework-agnostic; Google’s docs don’t mention Nuxt by name).
- Dynamic Rendering (deprecated workaround) — why Google deprecated it and what to use instead (SSR, static renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM., hydration).
Quotes from the source
On-the-record statements from Nuxt, Google, and my own writing. Each search-engine / Nuxt link is a deep link that jumps to the quoted passage on the source page.
Nuxt — renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. for SEO
- “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 updating the content delivered via client-side renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. takes more time.” — Nuxt rendering docs. Jump to quote
- “Web crawlersA 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. 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. CrawlingCrawling is how search engines use automated bots (like Googlebot and Bingbot) to discover URLs and download pages. A page has to be crawlable to be indexed, but crawling on its own isn't a ranking factor. 2. Rendering 3. 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..” — Google Search 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 hydrationActivating server-rendered HTML in the browser by attaching JavaScript handlers. as a solution.” — Google Search Central docs. Jump to quote
Patrick Stox (my own work — 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 quick pass to confirm a Nuxt site is set up for search and 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.:
- Content you want indexedStoring 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. is rendered on the server or at build time (SSR or
SSG) — not SPA mode (
ssr: false). - Confirmed via View Source that important content is in the raw HTML, and via URL InspectionA Google Search Console feature that reports how Google sees one specific URL on a property you own. By default it shows the last-indexed snapshot; a separate \"Test live URL\" mode fetches the current version. that Google renders it.
-
useSeoMeta()is in page components, not a shared layout overwriting page tags. -
ogImageuses an absolute URL (not relative). - A title template is set once in
app.vue; per-page titlesThe 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./descriptions are unique. -
@nuxtjs/sitemapis generating an XML sitemapAn XML sitemap is a UTF-8 file listing the canonical URLs on your site (with optional lastmod) so search engines can discover and prioritize them. It's a discovery and diagnostic aid, not a guarantee of indexing — and Google ignores its priority and changefreq tags.;lastmodis accurate and you’re not relying onchangefreq/priority. -
@nuxtjs/robotsis configured; the non-prod auto-disallow isn’t accidentally applying to production. -
robots.txtdoes not block your JS/CSS. - Canonicals are absolute and per-page (
nuxt-seo-utils). - 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. image loads eagerly (not lazy); all images have
width/height(CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good.). - Real
<a href>links /<NuxtLink>for navigation — no<div @click>routing. - If using
@nuxt/content,@nuxtjs/seois loaded before it in the modules array. - Dynamic renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. is not in use anywhere.
The mental models
1. RenderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. strategy comes first. Meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored., schema, and 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. are downstream of one decision: how the HTML gets produced. Answer “is this content server-rendered, statically generated, or client-rendered?” before debugging anything else.
2. SSR is the default — your job is mostly not to break it.
Nuxt points the defaults the right way. Most Nuxt SEONuxt SEO is the practice of optimizing Nuxt.js (Vue's meta-framework) apps so search engines and AI crawlers can crawl, render, and index them. Nuxt's big advantage is that it ships server-side rendering by default, so pages arrive as fully-formed HTML instead of an empty Vue SPA shell. failures are someone setting
ssr: false, blocking JS/CSS, or injecting signals via JavaScript that conflict with
the raw HTML.
3. Pick the renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. 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, not indexedStoring 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. → SPA (
ssr: false) is fine. - Public content you want ranked or cited by AIAn AI citation is the visible source link an AI answer engine shows next to its generated text — the clickable reference that credits the web page it used. A citation's presence is a separate thing from whether the cited page actually supports the statement, and from being retrieved (read behind the scenes) or merely mentioned (named without a link); citation is driven more by brand mentions and being retrievable than by traditional ranking. → never SPA.
4. HTML-first, JS-second for every signal. Content, meta, canonical, robots directives, and links all belong in the server-rendered HTML. Google takes the most restrictive directive across raw vs. rendered; 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. see only the raw. JS-injected SEO is a fallback, not the plan.
5. Use the modules, but understand what they do.
@nuxtjs/seo saves work, but the non-prod robots auto-disallow, the lastmod-only
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. reality, and absolute-URL canonicals are still yours to get right.
Nuxt SEO — cheat sheet
RenderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. modes
| Mode | Config | SEO | Best for |
|---|---|---|---|
| Universal / SSR | ssr: true (default) | ✅ Best | Dynamic / personalized |
| Static / SSG | nuxt generate | ✅ Best | Blogs, docs, marketing |
| Hybrid | routeRules | ✅ Best | Large mixed-content sites |
| SPA / CSR | ssr: false | ⚠️ Poor for 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. | Dashboards, admin |
| Edge-side | Deploy target | ✅ Low 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. | Global performance |
Composables
| Use | Reach for |
|---|---|
| SEO + social meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored. | useSeoMeta() (type-safe) |
| Title templates, scripts, link tags, html attrs | useHead() |
| Skip client re-execution for static meta | useServerHead() |
@nuxtjs/seo modules
| Module | Job |
|---|---|
@nuxtjs/robots | 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. + meta robotsThe 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. + X-Robots-TagThe X-Robots-Tag is an HTTP response header that carries the same indexing and serving directives as the robots meta tag (noindex, nofollow, nosnippet, and the rest). Because it lives in the header rather than the HTML, it's how you control indexing for non-HTML files like PDFs, images, and videos. (blocks non-prod by default) |
@nuxtjs/sitemap | XML sitemapAn XML sitemap is a UTF-8 file listing the canonical URLs on your site (with optional lastmod) so search engines can discover and prioritize them. It's a discovery and diagnostic aid, not a guarantee of indexing — and Google ignores its priority and changefreq tags. (only lastmod matters; auto index past 50k URLs) |
nuxt-og-image | Dynamic OG images |
nuxt-schema-org | JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. 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. |
nuxt-seo-utils | Canonical URLs (strips utm_*/fbclid/gclid), breadcrumbsBreadcrumbs are a secondary navigation trail (Home > Category > Page) that shows where a page sits in a site's hierarchy. They create internal links that pass PageRank, and when marked up with BreadcrumbList structured data they can drive the path Google shows in desktop search results. |
nuxt-link-checker | Build-time broken links |
Fast rules
- Install everything:
npx nuxt module add seo. - OG images: absolute URLs only.
- 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. image:
loading="eager"; all images needwidth/height(CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good.). - CWV targets: LCP ≤ 2.5s, INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. ≤ 200ms, CLS ≤ 0.1.
- Never block JS/CSS in 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..
- Dynamic renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM.: deprecated — Nuxt’s SSR/SSG replace it.
- 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.: no JavaScript → SPA content is invisible to them.
See what a Nuxt page actually ships
The whole Nuxt SEONuxt SEO is the practice of optimizing Nuxt.js (Vue's meta-framework) apps so search engines and AI crawlers can crawl, render, and index them. Nuxt's big advantage is that it ships server-side rendering by default, so pages arrive as fully-formed HTML instead of an empty Vue SPA shell. question reduces to one check: is your content in the raw HTML the server sends, or only after JavaScript runs? If it’s in the raw HTML, you’re server-renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. and crawlersA 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. (and AI botsAI 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.) can read it.
Fetch the raw HTML and look for your 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"If your text shows in the browser but is missing from raw.html, the page is
client-rendered — flip the route to SSR or prerenderThe Speculation Rules API is a Chromium browser API (Chrome/Edge 109+) that lets a site tell the browser which same-site pages to prefetch (download the HTML document) or prerender (fully load and render in an invisible tab) before a visitor clicks — so the next navigation can be near-instant. It's a browser-side performance feature for real users, not a crawling, indexing, or ranking signal. it. (A plain curl can’t run JS;
for the rendered DOM use URL InspectionA Google Search Console feature that reports how Google sees one specific URL on a property you own. By default it shows the last-indexed snapshot; a separate \"Test live URL\" mode fetches the current version. or a headless-Chrome 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..)
Confirm you 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 build output) or /_ipx/ (the @nuxt/image
optimizer) will break renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. — almost always 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)
},
}) 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.
- robots.txt Tester — Test pages against bots with a matcher ported from Google's open-source robots.txt parser — a blocked/allowed matrix with the exact winning rule per cell, file lint, sitemap-conflict detection, a diff mode for proposed changes, and a separate live robots.txt fetch for each entered origin.
- Log File Analyzer — Drop a server access log and see crawl budget by bot and section, status-code waste, an AI-vs-search breakdown, and a spoofer report that names impostors faking a crawler user-agent. Parses nginx, Apache, IIS/W3C, and JSON logs entirely in your browser — nothing is uploaded.
Tools for Nuxt SEO
- URL InspectionA Google Search Console feature that reports how Google sees one specific URL on a property you own. By default it shows the last-indexed snapshot; a separate \"Test live URL\" mode fetches the current version. (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.) — the source of truth. Run a live test and check the rendered HTML, screenshot, and page resources to confirm your Nuxt content actually rendered and nothing’s blocked.
@nuxtjs/seo/ nuxtseo.com — Harlan Wilton’s module bundle; the dev tools panel shows your generated robots, 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., schema, and OG images in development.- Nuxt DevTools — inspect head tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored., route rules, and which renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. mode each route is using.
- 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 — confirm
nuxt-schema-orgJSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. is present in the rendered output after any renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. change. - Ahrefs Site Audit / Screaming Frog (JS-rendering mode) — crawl with JS rendering on vs. off to diff raw vs. rendered HTML across the whole Nuxt app and catch CSR gaps.
- LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. / PageSpeed InsightsPageSpeed Insights (PSI) is a free Google tool at pagespeed.web.dev that reports two kinds of data for a URL: real-user field data from the Chrome UX Report and a single Lighthouse lab run with the 0–100 Performance score. Only the field Core Web Vitals are what Google uses for ranking. — 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. (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., INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good., CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good.) for the
@nuxt/imageand Nuxt Islands work. - Bing Webmaster ToolsMicrosoft's free portal for monitoring and improving how a site appears in Bing search — the peer to Google Search Console, plus IndexNow instant indexing, richer backlink data, and keyword volumes. Because Bing's index also feeds Microsoft Copilot, it doubles as a window into AI-search visibility. — Bing’s crawl/index view and where 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. submissions show up.
Nuxt SEO mistakes to avoid
Concrete mistakes that show up repeatedly on real Nuxt sites — prevent these before they ship, rather than diagnosing them after traffic drops.
Flipping ssr: false on content you want indexed
The single most expensive Nuxt SEONuxt SEO is the practice of optimizing Nuxt.js (Vue's meta-framework) apps so search engines and AI crawlers can crawl, render, and index them. Nuxt's big advantage is that it ships server-side rendering by default, so pages arrive as fully-formed HTML instead of an empty Vue SPA shell. mistake. SPA mode ships the same empty-shell problem plain Vue has — search engines have to wait for a render queue to fill in the content. AI-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. renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. contracts vary by provider, so 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 will miss the page content.
Why it’s wrong: you’re voluntarily giving up the one default (SSR) that makes Nuxt easier to indexStoring 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. than plain Vue.
What to do instead: leave ssr: true (the default) for anything public and
indexable. Reserve ssr: false for genuinely non-indexed surfaces — logged-in
dashboards, admin panels — via routeRules, not a global config flip.
Putting useSeoMeta() in a shared layout
Setting title/description inside a layout component feels efficient — one place,
applies everywhere — but it means every page that uses that layout gets the same
generic tags, and page-level useSeoMeta() calls can get overwritten depending on
render order.
Why it’s wrong: unique, page-specific titles and descriptions are basic relevance signals; a layout-level default collapses them all to one string.
What to do instead: set global fallbacks once in app.vue (title template, OG
defaults), then call useSeoMeta() inside each page component with that page’s
actual title and description.
Shipping a relative ogImage URL
ogImage: '/social.png' looks fine in the browser and completely fails when
Facebook, LinkedIn, or X try to fetch it, because social crawlers don’t resolve
relative paths against your site.
Why it’s wrong: social platforms need an absolute URL to fetch the image; a relative path resolves to nothing from their side.
What to do instead: always pass a full https:// URL, and set site.url in
nuxt.config.ts so @nuxtjs/seo’s modules can build absolute URLs for you
automatically.
Reaching for dynamic rendering
Serving a prerendered snapshot to known bots and the SPA to everyone else was a legitimate workaround years ago. Google has since called it out directly: “dynamic renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. is a workaround and not a long-term solution.”
Why it’s wrong: it only serves the bots you configure, misses everything else (Bing, most 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 adds real infrastructure to maintain — for a problem Nuxt’s own SSR/SSG already solves.
What to do instead: use SSR or nuxt generate and skip dynamic rendering
entirely. There’s no scenario where a Nuxt site needs it.
Blocking /_nuxt/ or /_ipx/ in robots.txt
A blanket Disallow: /assets/ or an overzealous robots rule can accidentally catch
Nuxt’s build output directory (/_nuxt/) or the @nuxt/image optimizer path
(/_ipx/).
Why it’s wrong: if 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. can’t fetch the JS/CSS that builds the page, it can’t confirm your SSR output is what it looks like — and any client-side enhancements silently stop rendering for it.
What to do instead: never disallow build-output or image-optimizer paths. Check
robots.txt after every deploy that touches routing or module config, not just once
at launch.
Leaving the non-production robots block active after launch
@nuxtjs/robots disallows all crawlers on non-production environments by default —
a good safety net for staging, but it reads environment variables to decide, and a
misconfigured NODE_ENV or preview-deploy setting can make it fire in production
too.
Why it’s wrong: the site looks completely fine in a browser while robots.txt
quietly disallows everything, and nothing gets indexed until someone notices.
What to do instead: after any deploy or environment change, fetch
https://yoursite.com/robots.txt directly and confirm it’s not a blanket
Disallow: /.
Standing KPIs for Nuxt SEO
The ongoing numbers to track once your renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. setup is correct — not one-time checks, but recurring signals that catch regressions as the app changes.
Core Web Vitals (LCP, INP, CLS)
What it tells you: whether real visitors are getting a fast, stable page — directly affected by Nuxt Islands/hydrationActivating server-rendered HTML in the browser by attaching JavaScript handlers. cost (INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good.) and image-loading choices (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., CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good.).
How to pull it: field dataPerformance metrics captured from real users, not lab tests. from the Chrome UX ReportChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program. via /tools/crux-tracker/ or /tools/cwv-checker/; lab data from LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. for pre-release checks.
Benchmark / realistic range: Google’s published “good” thresholds are 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. ≤ 2.5s, INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. ≤ 200ms, CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good. ≤ 0.1 at the 75th percentile — those are the pass/fail lines CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program. itself uses, not a number I’m inventing. Where you land within “good” depends heavily on your image weight and how much you hydrate.
Cadence: CrUX field data updates on a rolling 28-day window — check monthly, and immediately after any change to images, fonts, or hydration.
Rendered-vs-raw HTML parity
What it tells you: whether the content search engines and 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. can
actually see (the raw HTML) matches what a visitor sees in the browser (the rendered
DOM) — the core Nuxt SEONuxt SEO is the practice of optimizing Nuxt.js (Vue's meta-framework) apps so search engines and AI crawlers can crawl, render, and index them. Nuxt's big advantage is that it ships server-side rendering by default, so pages arrive as fully-formed HTML instead of an empty Vue SPA shell. risk if ssr gets flipped or a route regresses to CSR.
How to pull it: /tools/render-gap/ diffs raw vs. rendered HTML for a URL; for the authoritative Google-side view, use GSC’s URL Inspection → “View Crawled Page.”
Benchmark / realistic range: this is a binary check, not a range — your key content (headline, body copy, internal linksAn internal link is a hyperlink from one page on a website to another page on the same website. Internal links help search engines discover your pages and pass ranking signals (PageRank and anchor-text context) between them.) should be present in the raw HTML, full stop. Any gap on a page you want indexed or cited is a regression to fix, not a number to tolerate.
Cadence: after every deploy that touches routeRules, layouts, or the ssr
config; spot-check key templates monthly otherwise.
Index coverage (Page Indexing report)
What it tells you: how many of your submitted URLs Google has actually indexed, and why the rest were excluded (duplicate, crawled-not-indexed, blocked, etc.) — the downstream signal that renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. problems eventually surface as.
How to pull it: Search ConsoleGoogle's free tool for monitoring crawling, indexing, and search performance. → Page Indexing reportThe Google Search Console report (formerly Index Coverage) showing how many of your URLs are indexed vs. not indexed, and grouping the not-indexed ones by reason., filtered to your Nuxt site’s URL patterns.
Benchmark / realistic range: there’s no universal healthy percentage — it depends on how many near-duplicate or thin URLs your route structure generates. Watch the trend and the exclusion reasons, not a target number.
Cadence: weekly during and after a rendering-mode migration; monthly otherwise.
AI crawler access
What it tells you: whether GPTBot, ClaudeBot, PerplexityBot, and similar AI
crawlersA 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. can actually fetch your pages — separate from Google, since these bots
generally don’t execute JavaScript and read only the raw HTML your robots.txt
lets them reach.
How to pull it: /tools/ai-crawler-checker/ to confirm no AI user-agent is disallowed; server logs to confirm the bots are actually requesting pages, not just permitted to.
Benchmark / realistic range: there’s no citation-rate benchmark I can give you honestly — how often an AI answer engine cites you depends on the query space and competition, not something Nuxt configuration controls directly. Track access (allowed vs. blocked), not a made-up citation percentage.
Cadence: after every robots.txt or @nuxtjs/robots config change; monthly log
spot-check otherwise.
Test yourself: Nuxt SEO
Five quick questions on optimizing a Nuxt site for search. Pick an answer for each, then check.
Resources worth your time
My related writing
- JavaScript SEO: A Definitive Guide — my full guide to renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM., DOM parityWhether the rendered DOM matches what you expect the raw HTML to become., the most-restrictive-directive rule, and why SSR/static/prerenderThe Speculation Rules API is a Chromium browser API (Chrome/Edge 109+) that lets a site tell the browser which same-site pages to prefetch (download the HTML document) or prerender (fully load and render in an invisible tab) before a visitor clicks — so the next navigation can be near-instant. It's a browser-side performance feature for real users, not a crawling, indexing, or ranking signal. (Nuxt included) are all fine for search.
- The Beginner’s Guide to Technical SEO — where renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. and crawlingCrawling is how search engines use automated bots (like Googlebot and Bingbot) to discover URLs and download pages. A page has to be crawlable to be indexed, but crawling on its own isn't a ranking factor. fit in the bigger picture.
My speaking
- JavaScript SEO — Ungagged 2019 (SlideShare) — 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.’s evergreen Chromium, the ~20× crawl cost of rendering, History API over hash routing, and how Google handles JS-injected canonicals. (Standing disclaimer: the dynamic-rendering advice in that deck is now outdated — Google deprecated it.)
From around the industry
- Nuxt — Rendering Concepts (official) — universal vs. client-side rendering and why crawlersA 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. prefer SSR.
- Nuxt — SEO and Meta (official) —
useSeoMeta()anduseHead(), the getting-started reference. - Learn SEO with Nuxt (Harlan Wilton / nuxtseo.com) — the most comprehensive developer-focused Nuxt SEONuxt SEO is the practice of optimizing Nuxt.js (Vue's meta-framework) apps so search engines and AI crawlers can crawl, render, and index them. Nuxt's big advantage is that it ships server-side rendering by default, so pages arrive as fully-formed HTML instead of an empty Vue SPA shell. guide, kept current.
- harlan-zw/nuxt-seo (GitHub) — the source for the
@nuxtjs/seomodule bundle. - Nuxt Image (official) —
<NuxtImg>and 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. optimization. - Optimize Nuxt Performance (DebugBear) — a practitioner walkthrough of Nuxt 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. fixes.
- Nuxt 3 Rendering Modes (RisingStack) — a technical comparison of SSR, SSG, and hybrid rendering.
- r/TechSEO — the community for rendering/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. debugging.
Videos
- Google Search Central (YouTube) — Martin Splitt’s JavaScript SEOMaking sure search engines can crawl, render, and index content that depends on JavaScript. series is the best official walkthrough of how Google crawls, renders, and indexes JS apps; it’s framework-agnostic but applies directly to Nuxt. Channel
Nuxt SEO
Nuxt SEO is the practice of optimizing Nuxt.js (Vue's meta-framework) apps so search engines and AI crawlers can crawl, render, and index them. Nuxt's big advantage is that it ships server-side rendering by default, so pages arrive as fully-formed HTML instead of an empty Vue SPA shell.
Related: JavaScript SEO, Headless CMS SEO
Nuxt SEO
Nuxt SEO is the practice of optimizing a Nuxt.js application — Nuxt is the meta-framework built on top of Vue.js — so it’s discoverable, crawlable, and rankable. Because Nuxt renders server-side (SSR) by default, a route that keeps that default is delivered as a complete HTML document, which is the single biggest reason a Nuxt site can be friendlier to search engines than a plain Vue single-page app that ships an empty shell and fills it in with JavaScript — but it’s a per-route outcome: a global ssr: false or a routeRules override can turn any given route back into client-side renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM., so check the actual route rather than assuming from the framework name.
The work splits into a few areas. RenderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. strategy is the foundational decision, decided per route: SSR (the default), static generation via nuxt generate (SSG), hybrid per-route rules, SPA mode, or edge-side rendering — each with different SEO tradeoffs. Meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored. are handled with Nuxt’s composables — useSeoMeta() is the preferred, type-safe API for SEO/social tags, with useHead() for everything else in the <head> — though calling either only proves the API ran, not what a direct response emits. 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. control, 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., 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., 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. images are commonly handled by Harlan Wilton’s @nuxtjs/seo package — an optional, separately-installed third-party toolkit (not part of Nuxt core) that bundles robots, 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., OG image, Schema.orgSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor., and canonical handling.
The principles are the same as general JavaScript SEOMaking sure search engines can crawl, render, and index content that depends on JavaScript.: keep content in the rendered HTML, use real <a href> links, don’t block JS/CSS, and skip dynamic rendering (Google deprecated it). Nuxt just applies them through its own conventions. SSR or SSG matters even more for 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., which generally don’t run JavaScript at all.
Related: JavaScript SEO, Headless CMS 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 18, 2026.
Editorial summary and recorded change details.Summary
Reframed rendering and module claims as per-route/optional rather than project-wide defaults, and added coverage of hydration, ClientOnly risk, status codes, and Nitro deployment/cache boundaries.
Change details
-
Rendering-mode framing now leads with 'test the actual route' — routeRules or a global ssr:false can turn any route CSR or hybrid, so the SSR-by-default claim is no longer presented as a site-wide guarantee.
-
Added a new 'Beyond the initial HTML: payload, hydration, and status codes' section covering hydration/payload risk, ClientOnly hiding content from crawlers, and verifying direct HTTP status independently of client-rendered error pages.
-
Added a new 'Nitro, deployment presets, and cache boundaries' section on preset-specific runtime/caching differences and testing cache headers and production parity per route.
-
Reframed the @nuxtjs/seo module section to state explicitly it's an optional third-party toolkit (not Nuxt core), current at v5.x and actively maintained (verified live 2026-07-18), targeting Nuxt 3.16+ and 4.x — installing it doesn't itself prove correct output.
-
Added an API/output matrix (useSeoMeta vs. useHead vs. server-only) clarifying that calling a composable proves the API ran, not what a direct response or client navigation emits.
Full comparison unavailable — no prior snapshot was archived for this revision.