SEO
What every page emits for crawlers and social cards, which module writes it, and the one value the layer cannot guess.
Every page emits a full head, a structured description of itself, a social card and an entry in the sitemap. Most of it is written by Nuxt SEO, which the layer installs as one bundle; the rest is the part that depends on versions and translations, and that is the layer's own. One value has to come from you.
Per page
- Meta — the title with the site name appended, the description, and the
og:/twitter:pair derived from both.og:typeandog:urlare set per page;og:localeand its alternates come from the locales the site serves. - JSON-LD — one graph per page: a
WebSite(and yourOrganization, once set) declared site-wide, plus aTechArticleand aBreadcrumbListbuilt from the same trail the breadcrumb draws. - An Open Graph image, rendered from the layer's own template — on the landing page too. Ship a component of the same name to replace it.
canonicalandrobots, which are the version half — see URLs and versions. The canonical of an old version points at the current one, which is why the layer writes it rather than letting the module's automatic one stand.
The error page is noindex, follow: a 404 that gets indexed competes with the
page the reader was looking for, and the suggestions on it are real pages a
crawler should still reach.
Site-wide
/sitemap.xml lists the pages of the default version, per locale.
A non-default version is excluded because its pages carry noindex anyway, and
an eol version is excluded whether or not it is the default: listing either
asks a crawler to fetch exactly what the page then tells it to drop.
/robots.txt is generated beside it.
duxt.organization is what names the publisher — see
Configuration. Unset, the site still describes itself
as a WebSite; what it loses is the entity behind it, which is what a knowledge
panel or an AI summary reads to credit a source.
What is checked, and what is only reported
pnpm check:seo reads the built pages and fails over a second canonical, a
missing hreflang, an indexable error page, an og:locale in the wrong format,
or a graph that does not parse. It runs in pnpm check after the build, because
these tags exist only in rendered HTML.
The link checker reports rather than fails. A link pointing nowhere already fails the build through the layer's own build checks, which are the ones that understand versions and locale fallbacks; the module's value here is the devtools panel and the live check while writing.
The one value you must state
The origin. hreflang, canonical, the sitemap and the Open Graph images are all
absolute URLs, and a layer cannot know the domain it will be deployed to. Set
i18n.baseUrl or NUXT_PUBLIC_I18N_BASE_URL; the layer copies it to site.url,
where the SEO modules look.
Left unset, each of them degrades to relative output rather than inventing a
domain. That is the deliberate choice: a relative canonical still resolves
correctly, and a guessed one is actively wrong — it would point a crawler at
somebody else's site.
One more variable for a rolling deploy
NUXT_OG_IMAGE_SECRET signs the Open Graph image URLs. Without it a secret is
generated per build, which is fine for one instance and wrong for two: a card
whose URL was signed by one instance is rejected by the next, so a link shared
during a rolling deploy loses its image. Generate one once — it does not rotate.