Skip to content

Theming

A theme is a package like any other: it contributes layouts and assets.

How a page gets its look

A collection says which function renders its pages:

Collection.create "docs" decoder
|> Collection.layout (fun context -> (* markup *) )

That function receives a PageContext<'FrontMatter> - the page, its decoded front matter, the site, every other page, and the rendered content - and returns markup. Everything else a theme does (stylesheets, scripts, web components) it contributes as a plugin:

registry
|> Registry.asset (WriteText(css, RelativePath.create "assets/theme.css"))
|> Registry.extra (Stylesheet "assets/theme.css")

So "using a theme" is two lines: register the package, and use its layout.

Site.create "My library"
|> Theme.register theme                        // its assets
|> Site.collection (Theme.docs theme "content") // its layout and front matter

The default theme

Nacara.Theme.Default is the one this site uses, and what dotnet new nacara-docs starts you with: navbar, sidebar, table of contents, dark mode, and the components for tabs, callouts and code frames. It is documented with the other packages:

  • Default theme - what you get, and how to add it
  • Customising - colours, spacing, fonts, your own CSS
  • Navbar - sections, dropdowns, and the frame
  • Menu - where a sidebar comes from, and writing your own
  • Front matter - what a page says about itself
  • Components - composing a layout of your own

Three ways to make it yours

Override the tokens. Colours, spacing and the measure are custom properties, and your own stylesheet is loaded after the theme's, so yours wins.

Compose the pieces. The navbar, sidebar, table of contents and page navigation are exported functions. Your own layout can use them and arrange the middle differently - a landing page, a reference page with two columns.

Write a theme. A layout function, a stylesheet, and register; nothing else is required. Publish it and it is an ordinary NuGet package, like the default one.

What the engine owns

Some things stay with the engine whichever theme you use:

The engine decidesThe theme decides
Which pages exist, and their routesWhat a page looks like
That front matter is typed, and fails the build when it is notWhich fields it reads
What a URL is - base path, locale, version prefixWhich links a page shows
Which locale a page belongs to, and which one stands in for itHow that is said to a reader
What a code block contains - its title, marked lines, folded rangesThe markup that draws it
That a page carries its headings, whichever plugin read them out of itWhether a table of contents is shown, and where
That an asset is written once, and only when its bytes changedWhich stylesheets and scripts a page carries

So swapping themes does not change your content, and a plugin can ship a widget - a search box, a version switcher - without knowing which theme draws it.

Edit this page