Starlight for Dune
Faithful port of Starlight (MIT © Astro contributors — see LICENSE), Astro's documentation theme.

Demo: https://themes.getdune.org/starlight
Tags: dune-theme, docs, sidebar, faithful
Install
dune theme:install jsr:@dune/theme-starlight@1.0.0 --activate
Or by hand, in config/site.yaml:
themes:
- name: starlight
src: jsr:@dune/theme-starlight@1.0.0
theme:
name: starlight
src: jsr:@dune/theme-starlight@1.0.0
The stylesheet bundles the upstream global CSS verbatim (cascade layers,
props, reset, asides, utils, markdown, anchor-links) followed by the
component styles hand-descoped from each .astro component's scoped
<style> block, so pages match Starlight pixel-for-pixel. Client behaviour
(theme picker, mobile menu, ToC scroll spy, tabs sync, sidebar state
persistence, search modal) is the upstream custom-element scripts, bundled
in static/starlight.js.
The theme declares its sanitizer allowances via the sanitize export in
mdx-components.ts (tags like aside/svg/custom elements, role/
aria-*/data-* attributes), so the MDX components work without setting
trusted_html: true. Script execution, event handlers and unsafe URL
schemes stay blocked.
Full deviations-from-upstream detail and a config walkthrough are in the live demo's Using Starlight section.
Templates
| Template | Upstream | Notes |
|---|---|---|
default |
Page.astro (docs) |
sidebar, scroll-spy ToC, prev/next footer |
section |
— (Dune collection indexes) |
page body + linked child list |
splash |
template: splash |
hero landing page (frontmatter hero: block, upstream shape), no sidebar/ToC |
error |
404.astro |
status code as hero title, 404.text tagline; rendered by core for 404/500 |
search |
— (upstream is modal-only) | results page for Dune's /search route |
MDX components
Aside, Badge, Card, CardGrid, LinkCard, LinkButton, Steps,
Tabs/TabItem (incl. syncKey cross-page sync), FileTree, Icon —
markup identical to the upstream user-components. Steps/Tabs/FileTree
transform their JSX children as vnodes instead of upstream's rehype passes
over rendered slot HTML; authoring syntax is unchanged.
Configuration
Admin-editable (config_schema): logo, sidebar_section (route shown in
the sidebar; * for all), search, pagination, social (JSON array of
{icon, label, href}), edit_link_base (upstream editLink.baseUrl),
language_labels (code/name — see Deviations), credits.
Per-page frontmatter: template: splash, hero: (title/tagline/image/
actions), sidebar: false, tableOfContents: false, draft: true (notice
banner), banner: {content: …}, lastUpdated.
Deviations from upstream
- Search is Dune's server-side
/api/searchpresented in the upstream modal shell (Ctrl/Cmd+K, same dialog markup); Pagefind and its result UI are replaced by a small fetch-based renderer styled to match. The fetch URL respectssite.basePathfor path-prefix multisite hosting. - Sidebar is built from Dune's
navAllpage index: a page with child pages becomes a collapsible group (open when it contains the current page) with the page itself as the group's first link. Splash pages are excluded. Upstream's per-entry badges and manual sidebar config are not reproduced. - Component styles are hand-descoped from Astro's scoped styles; a few
elements carry an extra class for scoping (
sl-select,sl-footer,sl-edit-link,sl-page-title,sl-content-notice,sl-icon). - Heading ids + ToC are generated by the theme (marked emits none); ToC covers h2–h3 with the injected "Overview" entry like upstream.
- Section indexes (
template: section) also list child pages from a Dunecollectionblock. - Language switcher (
starlight-lang-selectin the header and mobile menu, plushreflangalternates) is driven by Dune's per-pagetranslationsprop; it lists only languages the current page exists in. Labels default to the language code; setlanguage_labels: namefor native names viaIntl.DisplayNames. A locale string keyed by the language code overrides both. - FileTree uses the generic seti folder/file icons; the ~700-entry per-extension icon map is not ported.
- LastUpdated reads
lastUpdated/updatedfrontmatter (no git integration); EditLink joinsedit_link_basewith the page's content path. - Not ported: Pagefind, sitemap/head-entries pipeline (Dune provides
its own), Expressive Code code blocks (plain
pre/codestyling from markdown.css applies),<StarlightPage>API, plugins/overrides system, fallback-content notice for untranslated pages, per-page sidebar badges, hero dark/light image variants beyondfile/dark/light/html(ported as plainimgwithout Astro image optimization).