Layout

The docs area is wrapped with the <Layout> component from @canopy-iiif/app/ui/server. It arranges the page into three distinct regions (sidebar navigation, main content, and optional on-page table of contents) and wires up global navigation metadata during build time.

content/docs/_layout.mdx
---type: "docs"--- <Layout navigation={true} fluid={true}>  {props.children}</Layout>

Core props

  • navigation: toggles the left-hand sidebar that renders your section menu. Set it to false when you want a full-width document without navigation.
  • sidebar: accepts a React node or render function to replace the default sidebar. null keeps the auto-generated navigation.
  • contentNavigation: enables the right-hand table of contents generated from Markdown headings (## and deeper). Disable it when a page is short or when you want to hide the toc.
  • fluid: switches the content container from a centered max-width layout to full-width gutters (useful for wide screenshots or tables).
  • Class name props (className, contentClassName, sidebarClassName, contentNavigationClassName): allow fine-grained styling hooks when additional spacing or typography tweaks are required.

Page context

During the MDX build, heading data and navigation metadata are injected into the page context. <Layout> reads that context to:

  • Build the section navigation directly from the content/ directory tree.
  • Generate the table of contents from Markdown headings.
  • Prefill component props such as pageTitle for downstream components like <ContentNavigation />.

Because the layout receives its configuration at build time, individual MDX files can stay lean—compose Markdown, set front matter (title, description, etc.), and let the wrapper render the chrome.

Customising per section

If a section needs a different layout treatment, create or edit the relevant _layout.mdx file and pass custom props:

content/docs/theme/_layout.mdx
<Layout  fluid={false}  navigation  sidebarClassName="md:max-w-xs"  contentNavigation={false}>  {props.children}</Layout>

Navigation mirrors the file system, so overrides only need to worry about layout props. The sections below outline how the menus and tables of contents are generated.

Primary navigation

Configure top-level links in content/_app.mdx when you render <CanopyHeader />. Pass a navigation array with href/label pairs and the header renders them on every page:

content/_app.mdx
<CanopyHeader  navigation={[    {href: "/search", label: "Works"},    {href: "/docs", label: "Docs"},    {href: "/about", label: "About"},  ]}  title="Canopy IIIF"  logo={Logo}/>

Section navigation

When <Layout navigation={true}> wraps a page, it builds a sidebar from the MDX files that share the same directory. Order follows the file path (directories first, then index.mdx, then remaining files alphabetically). Nested folders become nested menus automatically, so you never maintain a parallel menu schema—rename a file or add a new one and the sidebar updates on the next build.

content/├── docs/│   ├── _layout.mdx│   ├── index.mdx│   └── content/│       ├── index.mdx│       └── markdown.mdx└── about/    └── index.mdx

Visiting /docs/content/markdown renders the docs sidebar because the page lives under content/docs/content/. Pages outside that tree (e.g., /about) receive a minimalist layout unless you wrap them in <Layout navigation={true}>.

Table of contents

<Layout> also builds an on-page table of contents from headings inside each MDX file (levels two and below). Keep headings short, descriptive, and unique; the generated IDs power deep links and the right-hand toc.