Create and override Astro Starlight UI components. Use when replacing or extending built-in Starlight components (header, footer, sidebar, page title, etc.), adding custom UI alongside existing components, accessing page route data inside a component, or applying overrides conditionally on specific pages.
75
93%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
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.
a1083f4
Also appears in
since Mar 17, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.