Wire up: dashboard layout
This page assumes @dagilleland/layout-dashboard is already installed — via npm, pnpm, or a manual copy. What’s below is identical regardless of which method you used.
Prerequisites: an Astro project using Starlight, with Tailwind v4 set up per Starlight’s own guide — both components are styled entirely with Tailwind utility classes, referencing Starlight’s own --sl-color-* custom properties so they automatically match your site’s theme.
Unlike the other three layouts in this family, this package has two independent parts: the widgets, which need no wiring at all, and an optional full-width treatment, which needs the same overrides as full-width.
The widgets: zero wiring needed
Section titled “The widgets: zero wiring needed”DashboardGrid and Widget aren’t Starlight overrides — they’re ordinary components, usable the moment they’re installed. No content-schema field, no override, no astro.config.mjs change:
import { DashboardGrid, Widget } from '@dagilleland/layout-dashboard';
<DashboardGrid> <Widget title="Active users" value="2,481" trend="up" delta="4.2% vs last week" /> <Widget title="Error rate" value="0.8%" trend="down" delta="0.3pt vs last week" /></DashboardGrid>Drop that into any .mdx page and it renders inside your page’s normal content column — sidebar, table of contents, and content-width cap all unaffected. Good enough if you just want a stat grid somewhere on an otherwise ordinary page. See Filling a dashboard for content-design tips: one widget per idea, leading with the number, and more.
The full-width treatment: same overrides as full-width
Section titled “The full-width treatment: same overrides as full-width”If you also want the grid to span the full page width — no right-hand table of contents, no content-width cap — that’s the same wide mechanism full-width uses. Follow that page’s four steps unchanged, just matching 'dashboard' instead of 'full-width':
1. Add a frontmatter field
Section titled “1. Add a frontmatter field”import { defineCollection, z } from 'astro:content';import { docsLoader } from '@astrojs/starlight/loaders';import { docsSchema } from '@astrojs/starlight/schema';
export const collections = { docs: defineCollection({ loader: docsLoader(), schema: docsSchema({ extend: () => z.object({ pageLayout: z.enum(['dashboard']).optional(), }), }), }),};2. Override TwoColumnContent
Section titled “2. Override TwoColumnContent”---import Default from '@astrojs/starlight/components/TwoColumnContent.astro';
const { entry } = Astro.locals.starlightRoute;const wide = entry.data.pageLayout === 'dashboard';---
{wide ? ( <div class="main-pane main-pane--full"> <slot /> </div>) : ( <Default> <slot name="right-sidebar" slot="right-sidebar" /> <slot /> </Default>)}
<style> @layer starlight.core { .main-pane--full { isolation: isolate; width: 100%; } }</style>3. Override ContentPanel
Section titled “3. Override ContentPanel”---import Default from '@astrojs/starlight/components/ContentPanel.astro';
const { entry } = Astro.locals.starlightRoute;const wide = entry.data.pageLayout === 'dashboard';---
{wide ? ( <div class="content-panel content-panel--uncapped"> <div class="uncapped-container"> <slot /> </div> </div>) : ( <Default><slot /></Default>)}
<style> @layer starlight.core { .content-panel--uncapped { padding: 1.5rem var(--sl-content-pad-x); } .uncapped-container { max-width: none; } }</style>4. Register both overrides
Section titled “4. Register both overrides”starlight({ components: { TwoColumnContent: './src/components/overrides/TwoColumnContent.astro', ContentPanel: './src/components/overrides/ContentPanel.astro', },});5. Use it on a page
Section titled “5. Use it on a page”---title: A dashboard pagepageLayout: dashboard---
import { DashboardGrid, Widget } from '@dagilleland/layout-dashboard';
<DashboardGrid> <Widget title="Active users" value="2,481" trend="up" delta="4.2% vs last week" /></DashboardGrid>See Building: dashboard layout for why the width-cap override matters even once the right column is gone.