Skip to content

<PageFrame>

The <PageFrame> component is an override of Starlight’s <PageFrame>, which has been extended to create a new mobile bar on top of the page, which contains the mobile table of contents (TOC), among other things.

Originally, the <PageFrame> component is used to render the left sidebar, page header and main content.

Usage

Overriding

If you want to extend the <PageFrame> component for your own website, you can do so by creating your own override as seen below.

Note that including the <style> tag is important, as none of the default styles are otherwise included.

  1. Create your own PageFrame.astro component in the src/overrides directory (or src/components if you prefer).
    ---
    import MobileMenuToggle from 'virtual:starlight/components/MobileMenuToggle';
    import MobileTableOfContents from 'virtual:starlight/components/MobileTableOfContents';
    import SiteTitle from 'virtual:starlight/components/SiteTitle';
    import type { Props } from '../props';
    const { hasSidebar } = Astro.props;
    ---
    <div class="page sl-flex">
    {
    hasSidebar ? (
    <nav class="sidebar" aria-label={Astro.locals.t('sidebarNav.accessibleLabel')}>
    <div id="starlight__sidebar" class="sidebar-pane">
    <div class="sidebar-content sl-flex">
    <slot name="sidebar" />
    </div>
    </div>
    </nav>
    ) : (<header class="header"><slot name="header" /></header>)
    }
    <div class="main-frame">
    {hasSidebar && (
    <div class="mobile-header">
    <div class="title-wrapper ">
    <SiteTitle {...Astro.props} />
    </div>
    <MobileTableOfContents {...Astro.props} />
    <MobileMenuToggle {...Astro.props} />
    </div>
    )}
    <slot />
    </div>
    </div>
    <style>
    .page {
    flex-direction: column;
    min-height: 100vh;
    }
    .header {
    z-index: var(--sl-z-index-navbar);
    position: fixed;
    inset-inline-start: 0;
    inset-block-start: 0;
    width: 100%;
    height: var(--sl-nav-height);
    border-bottom: 1px solid var(--sl-color-hairline-shade);
    padding: var(--sl-nav-pad-y) var(--sl-nav-pad-x);
    padding-inline-end: var(--sl-nav-pad-x);
    background-color: var(--sl-color-bg-nav);
    }
    :global([data-has-sidebar]) .header {
    padding-inline-end: calc(var(--sl-nav-gap) + var(--sl-nav-pad-x) + var(--sl-menu-button-size));
    }
    .sidebar-pane {
    visibility: var(--sl-sidebar-visibility, hidden);
    position: fixed;
    z-index: var(--sl-z-index-menu);
    inset-block: var(--sl-nav-height) 0;
    inset-inline-start: 0;
    width: 100%;
    background-color: var(--sl-color-black);
    overflow-y: auto;
    }
    :global([aria-expanded='true']) ~ .sidebar-pane {
    --sl-sidebar-visibility: visible;
    }
    .sidebar-content {
    height: 100%;
    min-height: max-content;
    padding: 1rem var(--sl-sidebar-pad-x) 0;
    flex-direction: column;
    gap: 1rem;
    }
    @media (min-width: 50rem) {
    .sidebar-content::after {
    content: '';
    padding-bottom: 1px;
    }
    }
    .main-frame {
    padding-top: calc(var(--sl-nav-height) + var(--sl-mobile-toc-height));
    padding-inline-start: var(--sl-content-inline-start);
    }
    @media (min-width: 50rem) {
    :global([data-has-sidebar]) .header {
    padding-inline-end: var(--sl-nav-pad-x);
    }
    .sidebar-pane {
    --sl-sidebar-visibility: visible;
    width: var(--sl-sidebar-width);
    background-color: var(--sl-color-bg-sidebar);
    border-inline-end: 1px solid var(--sl-color-hairline-shade);
    }
    }
    </style>
  2. Add the override to your astro.config.mjs file.
    astro.config.mjs
    import starlight from '@astrojs/starlight';
    import { defineConfig } from 'astro/config';
    export default defineConfig({
    integrations: [
    starlight({
    title: 'My Docs',
    components: {
    // Override the theme's `PageFrame` component.
    PageFrame: './src/overrides/PageFrame.astro'
    },
    }),
    ],
    })