Skills for setting up and customizing Astro Starlight documentation sites, covering project setup, custom theming, and component overrides.
100
100%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Passed
No known issues
Starlight's built-in UI can be extended or replaced by registering your own Astro components. Use this when CSS is not enough or you need behavioral changes.
starlight-theme insteadstarlight-base insteadStarlight's UI is a set of named slots. You swap slot implementations, not DOM nodes.
.astro file for a named component slot in astro.config.mjs. No CSS selector is involved — you replace the entire component rendering.Astro.locals, not props. All route metadata is available via Astro.locals.starlightRoute. See overrides-reference.md for all available properties.Step 1 — Identify the slot name from the Overrides Reference. Common ones: Header, Footer, PageTitle, Sidebar, TableOfContents, Hero, Pagination. Use the Overrides Map to visually locate UI areas.
Step 2 — Create the component:
---
// src/components/CustomFooter.astro
---
<footer>
<p>Built with Starlight</p>
</footer>Step 3 — Register in astro.config.mjs:
starlight({
components: {
Footer: './src/components/CustomFooter.astro',
},
})---
// src/components/CustomSocialIcons.astro
import Default from '@astrojs/starlight/components/SocialIcons.astro';
---
<a href="mailto:hello@example.com">Contact</a>
<Default><slot /></Default>For layout components with named slots (PageFrame, TwoColumnContent), transfer them explicitly:
<Default>
<slot />
<slot name="right-sidebar" slot="right-sidebar" />
</Default>---
const { title, description } = Astro.locals.starlightRoute.entry.data;
const isHomepage = Astro.locals.starlightRoute.id === '';
---See overrides-reference.md for the full starlightRoute property table.
WHY: Paths in components: {} are relative to the project root. Consequence: Build error — component not found.
BAD: Footer: '/src/components/CustomFooter.astro'
GOOD: Footer: './src/components/CustomFooter.astro'
<slot /> when wrapping a built-in componentWHY: Without <slot />, child content is silently discarded.
BAD: <Default /> (no slot)
GOOD: <Default><slot /></Default>
Consequence: Sidebar links and other nested content disappear.
Astro.props in override componentsWHY: Override components do not receive page data as props — only via Astro.locals.
BAD: const { title } = Astro.props; — always undefined
GOOD: const { title } = Astro.locals.starlightRoute.entry.data;
Consequence: All page metadata is undefined.
WHY: Only the key in components: {} determines the slot, not the file name.
BAD: Naming a file Footer.astro without registering it in config.
GOOD: Footer: './src/components/MyFooter.astro' in config.
Consequence: Default component renders unchanged.
WHY: PageFrame and TwoColumnContent expose named slots. Omitting them silently drops content. Consequence: Right sidebar disappears from all pages.
BAD: Wrap with only <Default><slot /></Default>
GOOD:
<Default>
<slot />
<slot name="right-sidebar" slot="right-sidebar" />
</Default>WHY: Only listed components are stable public API. Others may change without notice. Consequence: Imports break on minor version bumps.
BAD: Import an internal component not in the official reference. GOOD: Override only components from the official list.