---
title: "Metadata and SEO"
description: "Titles, descriptions, Open Graph images, sitemaps, and per-page head control."
---

> Documentation Index
> Fetch the complete documentation index at: https://nimbus-docs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Metadata and SEO

Nimbus handles the metadata baseline automatically and gives you per-page and site-wide control where you need it.

## Titles and descriptions

`title` and `description` frontmatter populate `<title>` and `<meta name="description">`, and feed the search snippet and `llms.txt` indexes. Site-wide fallbacks come from the Nimbus config:

```ts title="astro.config.ts"
const nimbusConfig = defineNimbusConfig({
  site: "https://docs.example.com",
  title: "Acme",
  description: "Build with Acme.",
});
```

## Open Graph images

Set a site-wide fallback card and alt text, then override per page:

```ts title="astro.config.ts"
const nimbusConfig = defineNimbusConfig({
  // …
  socialImage: "/og.png",
  socialImageAlt: "Acme documentation",
});
```

```yaml
---
title: Pricing
socialImage: /og/pricing.png
---
```

Nimbus also ships an OG image route, so pages without an explicit image get a generated card: the site's logo, the page's section and its title. See [Customize OG cards](/ai/override-markdown#customize-og-cards).

A docs page uses its frontmatter `socialImage`, or else its generated card, `/og/<page>.png`.

Other pages, such as the 404 page and hand-written routes, use the first that exists: `config.socialImage`, `public/opengraph.png` or `public/logo.png`, then the generated `/og.png` card.

Image paths are logical paths without Astro's deployment base. For a site deployed at `/docs`, keep `socialImage: "/og.png"`; Nimbus produces `/docs/og.png`. Absolute and protocol-relative image URLs are preserved.

### Image sizes

`og:image:width` and `og:image:height` are written only when the size is known, so a link preview is never cropped to the wrong shape:

- Generated cards (`/og.png` and `/og/<page>.png`) are 1200 × 630.
- `config.socialImage`, the auto-detected `public/opengraph.png` or `public/logo.png`, and every image under `public/og/` are measured at build time.
- Any other image, such as a remote URL or a per-page file elsewhere in `public/`, gets no size tags. Pass the size where you know it, as `socialImageSize` on `NimbusHead` or on the starter's `BaseLayout`:

```astro
<NimbusHead title={title} socialImage="/diagrams/cover.png" socialImageSize={{ width: 1600, height: 900 }} />
```

## Sitemap and robots

When `site` is set, the sitemap integration and `/robots.txt` are wired automatically. Disable the sitemap with `sitemap: false` in the integration options.

The sitemap is written as `sitemap-index.xml` plus `sitemap-0.xml`, and `/sitemap.xml` is a copy of the index for tools that only try that name. A site that serves its own `/sitemap.xml`, as a file in `public/`, a `sitemap.xml` route, or a dynamic `[name].xml` route at the root, keeps it.

A docs page's `<lastmod>` is its frontmatter `lastUpdated`, or else the date of the last commit to its file, matching its "Last updated" line. Pages with no content file, such as API pages, have none.

A `serialize` option in `sitemap` runs afterwards, so it can change or drop the value.

Git dates need the repository's history. On a shallow clone, which most CI systems make by default, the build says so once and leaves out every git date: the sitemap's `lastmod` and the "Last updated" line on pages. Fetch the full history to restore them, with `fetch-depth: 0` in GitHub Actions or `git fetch --unshallow`.

## Per-page and site-wide head

Add elements to `<head>` site-wide via `config.head`, or per page via frontmatter — the two are merged:

```yaml
---
title: Analytics-tracked page
head:
  - tag: meta
    attrs: { name: "robots", content: "noindex" }
  - tag: link
    attrs: { rel: "canonical", href: "https://example.com/canonical" }
---
```

Valid tags: `meta`, `link`, `script`, `style`, `title`, `noscript`, `base`. To exclude a page from crawlers without hand-writing the tag, use `noindex: true`.

## Canonical URLs

On versioned sites, Nimbus emits `<link rel="canonical">` pointing older versions at the current one, plus `<link rel="alternate">` between siblings — driven by `previousSlug`.

Source: https://nimbus-docs.com/publish/metadata-and-seo/index.mdx
