Skip to content
K

Site UI Configuration

Configure ArdoRoot, header, footer, edit links, last-updated metadata, and context sidebars from root.tsx.

Build-time options belong in ardo() config. Site chrome belongs in React. Configure the header, sidebar, footer, edit links, last-updated metadata, and multi-section sidebars in your app's root.tsx with <ArdoRoot>.

Minimal Root

Every Ardo app needs the generated config and sidebar data. Import them from virtual modules and pass them to ArdoRoot.

import { ArdoRoot, ArdoRootLayout } from "ardo/ui"
import config from "virtual:ardo/config"
import sidebar from "virtual:ardo/sidebar"
import "ardo/ui/styles.css"

export function Layout({ children }: { children: React.ReactNode }) {
  return <ArdoRootLayout>{children}</ArdoRootLayout>
}

export default function Root() {
  return <ArdoRoot config={config} sidebar={sidebar} />
}

ArdoRootLayout owns the document-level theme bootstrap and global shell setup. ArdoRoot owns the React Router outlet, Ardo providers, default header, sidebar, and footer.

ArdoRoot Props

PropTypePurpose
configArdoConfigGenerated site config from virtual:ardo/config.
sidebarSidebarItem[] | Record<string, SidebarItem[]>Generated sidebar data from virtual:ardo/sidebar or virtual:ardo/sidebars.
contextsArdoContextItem[]Optional rail items for switching between multiple sidebar contexts.
headerReactNodeReplace the entire default header.
sidebarContentReactNodeReplace the generated sidebar content.
footerReactNodeReplace the default footer element.
headerPropsArdoHeaderPropsConfigure the default header. Ignored when header is provided.
sidebarPropsArdoSidebarPropsConfigure the default sidebar. Ignored when sidebarContent is provided.
footerPropsArdoFooterPropsConfigure the default footer. Ignored when footer is provided.
editLink{ pattern: string; text?: string }Site-wide edit-link pattern for Markdown pages.
lastUpdated{ enabled?: boolean; text?: string; formatOptions?: Intl.DateTimeFormatOptions }Site-wide last-updated display settings.
tocLabelstringLabel for the generated table-of-contents panel.
classNamestringReplace the default layout class.
childrenReactNodeReplace the default React Router <Outlet /> content.

Use headerProps when you want the default responsive header but need to configure the logo, navigation, search, theme toggle, or action area.

import { ArdoNav, ArdoNavLink, ArdoSocialLink } from "ardo/ui"
import logo from "./assets/logo.svg"

export default function Root() {
  return (
    <ArdoRoot
      config={config}
      sidebar={sidebar}
      headerProps={{
        logo,
        title: "My Docs",
        searchPlaceholder: "Search documentation...",
        nav: (
          <ArdoNav>
            <ArdoNavLink to="/guide/getting-started">Guide</ArdoNavLink>
            <ArdoNavLink to="/api-reference">API</ArdoNavLink>
          </ArdoNav>
        ),
        actions: <ArdoSocialLink href="https://github.com/example/project" icon="github" />,
      }}
    />
  )
}
Header propPurpose
logoString URL or { light, dark } logo variants.
titleHeader title. Defaults to config.title.
navDesktop navigation content, usually ArdoNav and ArdoNavLink.
actionsRight-side actions such as ArdoSocialLink or custom buttons.
searchSet to false to hide search. Defaults to true.
searchPlaceholderPlaceholder for the search input.
themeToggleSet to false to hide the theme toggle. Defaults to true.
mobileMenuContentAdditional content for the mobile menu. ArdoRoot supplies the sidebar.
classNameReplace the default header class.

Pass header instead of headerProps when your design needs a fully custom header element.

For light customization, pass footerProps. For the common "default footer with sponsor and copyright" case, pass an explicit footer element.

import { ArdoFooter } from "ardo/ui"

export default function Root() {
  return (
    <ArdoRoot
      config={config}
      sidebar={sidebar}
      footer={
        <ArdoFooter
          sponsor={{ text: "Example Co", link: "https://example.com" }}
          message="Released under the MIT License."
          copyright="Copyright 2026 Example Co"
        />
      }
    />
  )
}
Footer propPurpose
messageReact content rendered as footer message text.
copyrightReact content rendered as copyright text.
trustedMessageHtmlTrusted HTML for the message line. Do not pass user-provided content.
trustedCopyrightHtmlTrusted HTML for the copyright line. Do not pass user-provided content.
projectProject metadata override for the linked package/version line.
sponsorSponsor link rendered as "Sponsored by ...".
buildTimeBuild timestamp override. Defaults to generated config metadata.
buildHashGit hash override. Defaults to generated config metadata.
ardoLinkSet to false to hide the "Built with Ardo" link.
childrenFull custom footer content. Skips automatic footer rendering.
classNameReplace the default footer class.

editLink and lastUpdated are site-wide content settings. Ardo applies them to Markdown and MDX document pages, and page frontmatter can opt out with editLink: false or lastUpdated: false.

<ArdoRoot
  config={config}
  sidebar={sidebar}
  editLink={{
    pattern: "https://github.com/example/project/edit/main/docs/app/routes/:path",
    text: "Edit this page on GitHub",
  }}
  lastUpdated={{
    enabled: true,
    text: "Last updated",
    formatOptions: { dateStyle: "medium" },
  }}
  tocLabel="On this page"
/>

The :path placeholder receives the route file path relative to the generated Markdown route root.

Context Sidebars

Use virtual:ardo/sidebars and contexts when your docs have distinct areas, such as guide pages and generated API reference pages. The sidebar rail becomes a context switcher, and ArdoRoot selects the active sidebar map entry by context id.

import { ArdoRoot } from "ardo/ui"
import config from "virtual:ardo/config"
import sidebars from "virtual:ardo/sidebars"

export default function Root() {
  return (
    <ArdoRoot
      config={config}
      sidebar={sidebars}
      contexts={[
        { id: "guide", label: "Guide", href: "/guide/getting-started" },
        { id: "api-reference", label: "API", href: "/api-reference" },
      ]}
    />
  )
}

Each context item has:

FieldPurpose
idSidebar map key. Conventionally the top-level route folder, such as guide or api.
labelText shown in the sidebar rail tooltip.
hrefLanding link for the context. Also used to infer the default active route prefix.
matchOptional string prefix or RegExp when href is not enough to match the context's routes.

Use virtual:ardo/sidebar for a single global sidebar. Use virtual:ardo/sidebars only when you want context-aware navigation.