CtrlK
BlogDocsLog inGet started
Tessl Logo
SkillPublic

starlight-custom-component

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.

Quality

94%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide
SecuritybySnyk

Passed

No findings from the security scan

SKILL.md
Quality
Evals
Security

Starlight Custom Components

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.

When to Use

  • Changing a Starlight UI element that CSS alone cannot address
  • Adding new UI alongside an existing Starlight element (e.g., a banner above the header)
  • Replacing a built-in component with different markup or behavior
  • Conditionally rendering different UI on specific pages

When Not to Use

  • Simple color or font changes — use starlight-theme instead
  • Adding documentation content (pages, sidebars) — use starlight-base instead

Philosophy

Starlight's UI is a set of named slots. You swap slot implementations, not DOM nodes.

  • Named slots, not selectors. You register a replacement .astro file for a named component slot in astro.config.mjs. No CSS selector is involved: you replace the entire component rendering.
  • Wrap, don't replace. Import the default component and render it inside your override to add behavior without duplicating Starlight's markup. This keeps you compatible with future Starlight updates.
  • Page data lives in Astro.locals, not props. All route metadata is available via Astro.locals.starlightRoute. See overrides-reference.md for all available properties.

Step-by-Step: Override a Component

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',
  },
})

Wrapping a Built-in Component

---
// 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>

Accessing Page Data

---
const { title, description } = Astro.locals.starlightRoute.entry.data;
const isHomepage = Astro.locals.starlightRoute.id === '';
---

See overrides-reference.md for the full starlightRoute property table.

Anti-Patterns

NEVER register a component path with a leading slash

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'

NEVER omit <slot /> when wrapping a built-in component

WHY: Without <slot />, child content is silently discarded. Consequence: Sidebar links and other nested content disappear.

BAD: <Default /> (no slot)

GOOD: <Default><slot /></Default>

NEVER access page data via Astro.props in override components

WHY: 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;

NEVER rely on file name to determine which slot is overridden

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.

NEVER forget to transfer named slots on layout components

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>

NEVER import component internals not listed in the Overrides Reference

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.

NEVER fully replace a component when wrapping the default would do

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>.

NEVER guess the slot name

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.

NEVER override a component when CSS alone is enough

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.

NEVER use this skill to add documentation pages or sidebars

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.

References

TopicReferenceWhen to Use
Overrides and route dataOverrides ReferenceLooking up slot names and starlightRoute properties
GuideOverriding Components GuideLearning the override flow
Route dataRoute Data ReferenceReading page data in a component
Visual mapStarlight Overrides Map (interactive)Locating the UI area to override
Astro slotsAstro Components: SlotsUnderstanding default and named slots
Repository

pantheon-org/tekhne

Path

skills/documentation/astro-starlight/skills/starlight-custom-component/SKILL.md

Last updated
First committed

Also appears in

pantheon-ai/astro-starlight
Stale

last in sync Aug 28, 2026

Is this your skill?

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.