Theming with DaisyUI
dioxus-docs-kit uses Tailwind CSS 4 and DaisyUI 5 for styling. The default theme is dark, but you can configure light/dark toggle via DocsConfig:
DocsConfig::new(nav_json, content_map)
.with_theme_toggle("light", "dark", "dark") // (light theme, dark theme, default)
.build()DaisyUI themes control all component colors automatically. To use a different built-in theme (e.g. cupcake, dracula), just change the theme names passed to with_theme_toggle.
See the full list of built-in DaisyUI themes at daisyui.com/docs/themes.
Density Variants
DocsLayout accepts a variant prop with two built-in density presets:
use dioxus_docs_kit::{DocsLayout, DocsVariant};
DocsLayout { variant: DocsVariant::Reference, Outlet::<Route> {} }| Variant | Feel | --dk-article-width |
|---|---|---|
Prose (default) |
Wide margins, serif-friendly, long-form reading | 72ch |
Reference |
Tighter column, smaller type, denser headings | 64ch |
The variant emits a class on dk-root (dk-variant-prose / dk-variant-reference) so you can layer further CSS tweaks per variant.
CSS Token Surface
Visual identity lives in a flat set of --dk-* custom properties on dk-root. Override any subset to retheme without touching DaisyUI — useful when you need a brand look that DaisyUI's palette doesn't cover:
.dk-root {
--dk-article-width: 68ch;
--dk-heading-font: "Inter Tight", system-ui, sans-serif;
--dk-accent: oklch(0.65 0.20 250);
--dk-radius: 0.25rem;
}Pre-built theme presets
The crate ships drop-in presets in crates/dioxus-docs-kit/examples/themes/:
warm-editorial.css— amber accent, serif headings, cream surfacesbrutalist-light.css— high contrast, zero radius, monospaceshadcn-light.css/shadcn-dark.css— shadcn-style neutralsdefault.css— baseline (nothing overridden)
Copy any of them into your assets/ and import via document::Stylesheet. See crates/dioxus-docs-kit/THEMING.md for the full token reference.
SEO Meta
Set auto_meta: true on your DocsContext (the default in fresh integrations) and the kit emits <title>, <meta name="description">, OpenGraph, and Twitter Card tags from each page's frontmatter:
let docs_ctx = DocsContext {
current_path: current_path.into(),
base_path: "/docs".into(),
navigate: /* ... */,
site_url: Some("https://your-site.com".into()),
auto_meta: true,
};auto_meta = trueemits title and description unconditionally.- Canonical URLs (
<link rel="canonical">) andog:urlonly emit whensite_urlis also set. - Set
auto_meta = falseif your app already manages<head>(custom OG images, JSON-LD, etc.) and you want to avoid duplicate tags.
Sitemap Generation
DocsRegistry::generate_sitemap(site_url, docs_path) returns a fully-formed XML sitemap for every doc page. Wire it up as a server function so crawlers can fetch it:
const SITE_URL: &str = "https://your-site.com";
#[get("/sitemap-docs.xml")]
async fn sitemap_docs() -> Result<String, ServerFnError> {
Ok(DOCS.generate_sitemap(SITE_URL, "/docs"))
}
#[get("/robots.txt")]
async fn robots_txt() -> Result<String, ServerFnError> {
Ok(format!(
"User-agent: *\nAllow: /\n\nSitemap: {SITE_URL}/sitemap-docs.xml\n"
))
}If you also use the blog engine, BlogRegistry exposes the same generate_sitemap() method — combine both behind a sitemap.xml index. See src/main.rs in the example for the full pattern.
Configuring Navigation
Navigation is defined in docs/_nav.json. The structure supports tabs, groups, and pages:
{
"tabs": ["Docs", "Guides", "API Reference"],
"groups": [
{
"group": "Getting Started",
"tab": "Docs",
"pages": ["getting-started/introduction", "getting-started/quickstart"]
},
{
"group": "Guides",
"tab": "Guides",
"pages": ["guides/basic-usage", "guides/customization"]
}
]
}- tabs — Top-level navigation tabs shown in the docs header
- groups — Sidebar sections, each assigned to a tab
- pages — Paths relative to the
docs/directory (without.mdxextension)
Each page path must correspond to a .mdx file in the docs/ directory. The build.rs script reads _nav.json to generate include_str!() calls at compile time.
Adding a New Page
Create the MDX file
Create docs/my-section/my-page.mdx with frontmatter:
---
title: My Page
description: A brief description
sidebarTitle: My Page
icon: file-text
---
Your content here.Add to _nav.json
Add "my-section/my-page" to the appropriate group's pages array.
Rebuild
Run dx serve — the build script re-generates the content map automatically.
Adding OpenAPI Specs
dioxus-docs-kit can render interactive API reference pages from OpenAPI 3.x YAML specs. Each endpoint gets its own page with a Mintlify-style two-column layout.
static DOCS: LazyLock<DocsRegistry> = LazyLock::new(|| {
DocsConfig::new(nav_json, content_map)
.with_openapi(
"api-reference",
include_str!("../docs/api-reference/petstore.yaml"),
)
.build()
});- The first argument (
"api-reference") is the URL prefix for API pages - The second argument is the OpenAPI YAML content
- Endpoint slugs are derived from
operationIdvalues (camelCase → kebab-case) - Sidebar entries are generated automatically, grouped by tag
You also need an api-reference/overview page in _nav.json. The individual endpoint pages are generated dynamically from the spec.
Styling Prose Content
Documentation content is rendered inside Tailwind's prose class via the @tailwindcss/typography plugin. You can customize prose styles in your tailwind.css:
@import "tailwindcss";
@plugin "@tailwindcss/typography";
@plugin "daisyui";
/* Custom prose overrides */
.prose {
--tw-prose-body: oklch(0.85 0 0);
--tw-prose-headings: oklch(0.95 0 0);
}MDX Components
All content pages support Mintlify-style MDX components out of the box:
Callouts
Tip, Note, Warning, and Info callout boxes
Cards & Card Groups
Linked card grids with icons
Steps
Numbered step-by-step instructions
Code Groups
Tabbed code blocks with syntax highlighting
See the Basic Usage guide for a full component reference.