skills/documentation/astro-starlight/skills/starlight-custom-component/SKILL.md
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.
npx skillsauth add pantheon-org/tekhne starlight-custom-componentInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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:[email protected]">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.
tools
A skill that produces warnings but no errors.
testing
A well-formed example skill for testing the validator.
development
A skill with code blocks and imperative instructions for testing content and contamination analysis.
tools