Skip to content

Starlight for Dune

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

Starlight screenshot

Demohttps://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/search presented 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 respects site.basePath for path-prefix multisite hosting.
  • Sidebar is built from Dune's navAll page 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 Dune collection block.
  • Language switcher (starlight-lang-select in the header and mobile menu, plus hreflang alternates) is driven by Dune's per-page translations prop; it lists only languages the current page exists in. Labels default to the language code; set language_labels: name for native names via Intl.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/updated frontmatter (no git integration); EditLink joins edit_link_base with the page's content path.
  • Not ported: Pagefind, sitemap/head-entries pipeline (Dune provides its own), Expressive Code code blocks (plain pre/code styling from markdown.css applies), <StarlightPage> API, plugins/overrides system, fallback-content notice for untranslated pages, per-page sidebar badges, hero dark/light image variants beyond file/dark/light/html (ported as plain img without Astro image optimization).