Skip to content

Metadata

Page metadata is a set of information that describes a page. It is used to provide information about the page to search engines and other tools. You can customize individual Markdown and MDX pages in Starlight by setting values in their frontmatter

Frontmatter

Every documentation page needs frontmatter to define its metadata. Here’s a complete example:

intro.mdx
---
title: Introduction to Machine Learning
description: Learn the fundamentals of machine learning algorithms and applications.
sidebar:
label: ML Introduction # Optional: Custom sidebar label (defaults to title)
order: 2 # Controls position in the sidebar
author:
name: 'author name'
portfolio: 'https://author.info'
lastUpdated: true # Shows last update timestamp
---

Every page must include at least a title.

Frontmatter fields

The following fields are available in page frontmatter:

title (required)

type: string

You must provide a title for every page. This will be displayed at the top of the page, in browser tabs, and in page metadata.

description

type: string

The page description is used for page metadata and will be picked up by search engines and in social media previews.

author

type: { name: string; portfolio?: string }

The author property identifies who created the page and provides optional attribution through a portfolio link. When specified, author information is displayed in the page footer.

src/content/docs/example.mdx
---
title: Authoring Page
author:
name: 'author name'
portfolio: 'https://auth.info'
---
Multiple Contributors:

For pages with multiple contributors, the ChaiDocs Team will determine the primary author based on contribution levels. Only one author can be listed per page.

Example Display

When properly configured, the author information appears in the page footer as:

slug

type: string

Override the slug of the page. See “Defining custom IDs” in the Astro docs for more details.

editUrl

type: string | boolean

Overrides the global editLink config. Set to false to disable the “Edit page” link for a specific page or provide an alternative URL where the content of this page is editable.

type: HeadConfig[]

You can add additional tags to your page’s <head> using the head frontmatter field. This means you can add custom styles, metadata or other tags to a single page.

src/content/docs/example.mdx
---
title: About us
head:
# Use a custom <title> tag
- tag: title
content: Custom about title
---

tableOfContents

type: false | { minHeadingLevel?: number; maxHeadingLevel?: number; }

Customize the heading levels to be included or set to false to hide the table of contents on this page.

---
title: Page with only H2s in the table of contents
tableOfContents:
minHeadingLevel: 2
maxHeadingLevel: 2
---

template

type: 'doc' | 'splash' default: 'doc'

Set the layout template for this page. Pages use the 'doc' layout by default. Set to 'splash' to use a wider layout without any sidebars designed for landing pages.

hero

type: HeroConfig

Add a hero component to the top of this page. Works well with template: splash.

For example, this config shows some common options, including loading an image from your repository.

src/content/docs/example.mdx
---
title: My Home Page
template: splash
hero:
title: 'My Project: Stellar Stuff Sooner'
tagline: Take your stuff to the moon and back in the blink of an eye.
image:
alt: A glittering, brightly colored logo
file: ~/assets/logo.png
actions:
- text: Tell me more
link: /getting-started/
icon: right-arrow
- text: View on GitHub
link: https://github.com/astronaut/my-project
icon: external
variant: minimal
attrs:
rel: me
---

You can display different versions of the hero image in light and dark modes.

src/content/docs/example.mdx
---
hero:
image:
alt: A chai mascot.
dark: @/assets/chai-dark.png
light: @/assets/chai-light.png
---

HeroConfig

interface HeroConfig {
title?: string;
tagline?: string;
image?:
| {
// Relative path to an image in your repository.
file: string;
// Alt text to make the image accessible to assistive technology
alt?: string;
}
| {
// Relative path to an image in your repository to be used for dark mode.
dark: string;
// Relative path to an image in your repository to be used for light mode.
light: string;
// Alt text to make the image accessible to assistive technology
alt?: string;
}
| {
// Raw HTML to use in the image slot.
// Could be a custom `<img>` tag or inline `<svg>`.
html: string;
};
actions?: Array<{
text: string;
link: string;
variant?: 'primary' | 'secondary' | 'minimal';
icon?: string;
attrs?: Record<string, string | number | boolean>;
}>;
}

type: { content: string }

Displays an announcement banner at the top of this page.

The content value can include HTML for links or other content. For example, this page displays a banner including a link to example.com.

src/content/docs/example.mdx
---
title: Page with a banner
banner:
content: |
New Cohort is Live!
<a href="https://courses.chaicode.com">Check it out</a>
---

lastUpdated

type: Date | boolean

If a date is specified, it must be a valid YAML timestamp and will override the date stored in Git history for this page.

src/content/docs/example.mdx
---
title: Page with a custom last update date
lastUpdated: 2022-08-09
---

prev

type: boolean | string | { link?: string; label?: string }

If a string is specified, the generated link text will be replaced and if an object is specified, both the link and the text will be overridden.

---
# Hide the previous page link
prev: false
---

next

type: boolean | string | { link?: string; label?: string }

Same as prev but for the next page link.

src/content/docs/example.mdx
---
# Hide the next page link
next: false
---

pagefind

type: boolean default: true

Set whether this page should be included in the Pagefind search index. Set to false to exclude a page from search results:

src/content/docs/example.mdx
---
# Hide this page from the search index
pagefind: false
---

draft

type: boolean default: false

Set whether this page should be considered a draft and not be included in production builds. Set to true to mark a page as a draft and make it only visible during development.

src/content/docs/example.mdx
---
# Exclude this page from production builds
draft: true
---

Because draft pages are not included in build output, you cannot add draft pages directly to your site sidebar config.

type: SidebarConfig

Control how this page is displayed in the sidebar, when using an autogenerated link group.

SidebarConfig

interface SidebarConfig {
label?: string;
order?: number;
hidden?: boolean;
badge?: string | BadgeConfig;
attrs?: Record<string, string | number | boolean | undefined>;
}

label

type: string default: the page title

Set the label for this page in the sidebar when displayed in an autogenerated group of links.

src/content/docs/example.mdx
---
title: About this project
sidebar:
label: About
---

order

type: number

Control the order of this page when sorting an autogenerated group of links. Lower numbers are displayed higher up in the link group.

src/content/docs/example.mdx
---
title: Page to display first
sidebar:
order: 1
---

Example Scenario

When using autogenerated link groups, the order property is essential for controlling how pages appear within a group. Consider this file structure:

  • Directorysrc/
    • Directorycontent/
      • Directorydocs/
        • Directoryweb-dev/
          • DirectoryJavaScript/
            • intro.mdx
          • DirectoryTypeScript/
            • intro.mdx

To display pages in this order:

  1. JavaScript
  2. TypeScript

Set the order field in each page’s frontmatter:

---
title: JavaScript Introduction
Sidebar:
order: 1
---

Important Note - When adding new pages in the future, you may need to adjust the order values of existing pages to maintain the desired sequence.

hidden

type: boolean default: false

Prevents this page from being included in an autogenerated sidebar group.

src/content/docs/example.mdx
---
title: Page to hide from autogenerated sidebar
sidebar:
hidden: true
---

badge

type: string | BadgeConfig

Add a badge to the page in the sidebar when displayed in an autogenerated group of links. When using a string, the badge will be displayed with a default accent color.

src/content/docs/example.mdx
---
title: Page with a badge
sidebar:
# Uses the default variant matching your site’s accent color
badge: New
---

BadgeConfig

interface BadgeConfig {
text: string;
variant?: 'note' | 'tip' | 'caution' | 'danger' | 'success' | 'default';
class?: string;
}

Optionally, pass a BadgeConfig object with text, variant, and class fields to customize the badge.

src/content/docs/example.mdx
---
title: Page with a badge
sidebar:
badge:
text: Experimental
variant: caution
---

attrs

type: Record<string, string | number | boolean | undefined>

HTML attributes to add to the page link in the sidebar when displayed in an autogenerated group of links.

src/content/docs/example.mdx
---
title: Page opening in a new tab
sidebar:
# Opens the page in a new tab
attrs:
target: _blank
---

Customize Frontmatter

The frontmatter schema for ChaiDocs’s docs content collection is configured in src/content.config.ts using the docsSchema() helper:

src/content.config.ts
import { defineCollection } from 'astro:content';
import { docsLoader, i18nLoader } from '@astrojs/starlight/loaders';
import { docsSchema } from '@astrojs/starlight/schema';
export const collections = {
docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
};

Learn more about content collection schemas in “Defining a collection schema” in the Astro docs.

docsSchema() takes the following options:

extend

type: Zod schema or function that returns a Zod schema default: z.object({})

Extend ChaiDocs’s schema with additional fields by setting extend in the docsSchema() options. The value should be a Zod schema.

In the following example, we provide a stricter type for description to make it required and add a new optional category field:

src/content.config.ts
import { defineCollection, z } from 'astro:content';
import { docsLoader } from '@astrojs/starlight/loaders';
import { docsSchema } from '@astrojs/starlight/schema';
export const collections = {
docs: defineCollection({
loader: docsLoader(),
schema: docsSchema({
extend: z.object({
// Make a built-in field required instead of optional.
description: z.string(),
// Add a new field to the schema.
category: z.enum(['tutorial', 'guide', 'reference']).optional(),
}),
}),
}),
};

To take advantage of the Astro image() helper, use a function that returns your schema extension:

src/content.config.ts
import { defineCollection, z } from 'astro:content';
import { docsLoader } from '@astrojs/starlight/loaders';
import { docsSchema } from '@astrojs/starlight/schema';
export const collections = {
docs: defineCollection({
loader: docsLoader(),
schema: docsSchema({
extend: ({ image }) => {
return z.object({
// Add a field that must resolve to a local image.
cover: image(),
});
},
}),
}),
};

Start your journey with ChaiCode

All of our courses are available on chaicode.com. Feel free to check them out.