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.
94%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
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. Consequence: Sidebar links and other nested content disappear.
BAD: <Default /> (no slot)
GOOD: <Default><slot /></Default>
Astro.props in override componentsWHY: Override components do not receive page data as props, only via Astro.locals. Consequence: All page metadata is undefined.
BAD: const { title } = Astro.props; (always undefined)
GOOD: const { title } = Astro.locals.starlightRoute.entry.data;
WHY: Only the key in components: {} determines the slot, not the file name. Consequence: Default component renders unchanged.
BAD: Naming a file Footer.astro without registering it in config.
GOOD: Footer: './src/components/MyFooter.astro' in config.
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.
WHY: Wrapping keeps you compatible with future Starlight updates and avoids duplicating Starlight's markup. Consequence: Replaced markup drifts from upstream behaviour.
BAD: Copy the whole header markup to add one banner.
GOOD: Import the default component and render your banner before <Default><slot /></Default>.
WHY: The key in components: {} must be an exact named slot from the Overrides Reference. Consequence: An unknown key overrides nothing.
BAD: components: { MyHeader: './src/components/Header.astro' }
GOOD: Look up the slot (for example Header) in the Overrides Reference, then register it under that exact name.
WHY: Colour and font changes belong to starlight-theme; overrides add maintenance cost for no behavioural gain. Consequence: Needless coupling to Starlight's component structure.
BAD: Replace Header to change its background colour.
GOOD: Change the colour with CSS variables as described in starlight-theme.
WHY: Content and navigation are covered by starlight-base. Consequence: Content guidance is missed and the wrong patterns are applied.
BAD: Create a custom component just to list pages.
GOOD: Add pages and sidebar entries as described in starlight-base.
| Topic | Reference | When to Use |
|---|---|---|
| Overrides and route data | Overrides Reference | Looking up slot names and starlightRoute properties |
| Guide | Overriding Components Guide | Learning the override flow |
| Route data | Route Data Reference | Reading page data in a component |
| Visual map | Starlight Overrides Map (interactive) | Locating the UI area to override |
| Astro slots | Astro Components: Slots | Understanding default and named slots |
pantheon-org/tekhne
c8416e9
Also appears in
last in sync Aug 28, 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.