Skip to content

Plugins Reference

Starlight plugins can customize Starlight configuration, UI, and behavior, while also being easy to share and reuse. This reference page documents the API that plugins have access to.

Lean more about using a Starlight plugin in the Configuration Reference.

Quick API Reference

A Starlight plugin has the following shape. See below for details of the different properties and hook parameters.

interface StarlightPlugin {
name: string;
hooks: {
setup: (options: {
config: StarlightUserConfig;
updateConfig: (newConfig: StarlightUserConfig) => void;
addIntegration: (integration: AstroIntegration) => void;
astroConfig: AstroConfig;
command: 'dev' | 'build' | 'preview';
isRestart: boolean;
logger: AstroIntegrationLogger;
}) => void | Promise<void>;
};
}

name

type: string

A plugin must provide a unique name that describes it. The name is used when logging messages related to this plugin and may be used by other plugins to detect the presence of this plugin.

hooks

Hooks are functions which Starlight calls to run plugin code at specific times. Currently, Starlight supports a single setup hook.

hooks.setup

Plugin setup function called when Starlight is initialized (during the astro:config:setup integration hook). The setup hook can be used to update the Starlight configuration or add Astro integrations.

This hook is called with the following options:

config

type: StarlightUserConfig

A read-only copy of the user-supplied Starlight configuration. This configuration may have been updated by other plugins configured before the current one.

updateConfig

type: (newConfig: StarlightUserConfig) => void

A callback function to update the user-supplied Starlight configuration. Provide the root-level configuration keys you want to override. To update nested configuration values, you must provide the entire nested object.

To extend an existing config option without overriding it, spread the existing value into your new value. In the following example, a new social media account is added to the existing configuration by spreading config.social into the new social object:

plugin.ts
export default {
name: 'add-twitter-plugin',
hooks: {
setup({ config, updateConfig }) {
updateConfig({
social: {
...config.social,
twitter: 'https://twitter.com/astrodotbuild',
},
});
},
},
};

addIntegration

type: (integration: AstroIntegration) => void

A callback function to add an Astro integration required by the plugin.

In the following example, the plugin first checks if Astro’s React integration is configured and, if it isn’t, uses addIntegration() to add it:

plugin.ts
import react from '@astrojs/react';
export default {
name: 'plugin-using-react',
hooks: {
plugin({ addIntegration, astroConfig }) {
const isReactLoaded = astroConfig.integrations.find(
({ name }) => name === '@astrojs/react'
);
// Only add the React integration if it's not already loaded.
if (!isReactLoaded) {
addIntegration(react());
}
},
},
};

astroConfig

type: AstroConfig

A read-only copy of the user-supplied Astro configuration.

command

type: 'dev' | 'build' | 'preview'

The command used to run Starlight:

  • dev - Project is executed with astro dev
  • build - Project is executed with astro build
  • preview - Project is executed with astro preview

isRestart

type: boolean

false when the dev server starts, true when a reload is triggered. Common reasons for a restart include a user editing their astro.config.mjs while the dev server is running.

logger

type: AstroIntegrationLogger

An instance of the Astro integration logger that you can use to write logs. All logged messages will be prefixed with the plugin name.

plugin.ts
export default {
name: 'long-process-plugin',
hooks: {
plugin({ logger }) {
logger.info('Starting long process…');
// Some long process…
},
},
};

The example above will log a message that includes the provided info message:

Terminal window
[long-process-plugin] Starting long process…

Route injection

Plugins adding an Astro integration can inject routes using the Integrations API injectRoute function to render dynamically generated content. By default, pages rendered on custom routes do not use the Starlight layout. To use the Starlight layout, pages must wrap their content with the <VirtualPage /> component.

plugin/src/Example.astro
---
import VirtualPage, {
type VirtualPageProps,
} from '@astrojs/starlight/components/VirtualPage.astro';
import CustomComponent from './CustomComponent.astro';
const props = {
title: 'My custom page',
slug: 'custom-page/example',
template: 'doc',
hasSidebar: true,
headings: [{ depth: 2, slug: 'description', text: 'Description' }],
dir: 'ltr',
lang: 'en',
pagefind: true,
head: [],
} satisfies VirtualPageProps;
---
<VirtualPage {...props}>
<h2 id="description">Description</h2>
<CustomComponent />
</VirtualPage>

Props

Required props

The <VirtualPage /> component requires the following props:

title

type: string

The page title displayed at the top of the page, in browser tabs, and in page metadata.

slug

Type: string

The slug of the page.

headings

Type: { depth: number; slug: string; text: string }[]

Array of all headings of the page.

template

type: 'doc' | 'splash'

Set the layout template for this page. Use 'splash' to use a wider layout without any sidebars.

pagefind

type: boolean

Set whether this page should be included in the Pagefind search index.

dir

Type: 'ltr' | 'rtl'

Page writing direction.

lang

Type: string

BCP-47 language tag for this page’s locale, e.g. en, zh-CN, or pt-BR.

Type: { tag: string; attrs: Record<string, string | boolean | undefined>; content: string }[]

Additional tags to your page’s <head>. Similar to the global head option.

hasSidebar

Type: boolean

Whether or not the sidebar should be displayed on this page.

Optional props

Additionaly, the following props can be provided to customize the page:

description

type: string

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

type: SidebarEntry[] | undefined
default: the sidebar generated based on the global sidebar config

Site navigation sidebar entries for this page or fallback to the global sidebar option if not provided.

tableOfContents

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

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

lastUpdated

type: Date

A valid YAML timestamp to display the last updated date of the page.

prev

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

Overrides the global pagination option. 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.

next

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

Same as prev but for the next page link.

hero

type: HeroConfig

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

type: { content: string }

Displays an announcement banner at the top of this page.

The content value can include HTML for links or other content.