Skip to main content

Configuration

Custom CSS

Per-tenant CSS injected into the docs site head. Pro tier.

The customCss key on nookdocs.config.json is appended to the <head> of every rendered page. Because it cascades over the theme + typography rules, you can override anything our default theme ships without forking the renderer.

Where to edit

Two ways — they edit the same field: the dashboard panel reads and writes the customCss key of your nookdocs.config.json, so there is exactly one source of truth whichever path you use.

From the dashboard

Project → Settings → Custom CSS. Type or paste your CSS, then Save — it commits to nookdocs.config.json on the active branch and your live site picks it up on the next sync (seconds).

Paste a one-liner, hit Format, Save — the live site picks it up seconds later

Pasted a minified one-liner? Hit Format — it pretty-prints to one declaration per line with nested blocks (@media etc.) indented, leaving strings and url(...) values untouched.

From git

Edit nookdocs.config.json directly:

{
  "name": "your-docs",
  "customCss": "#docs-root .prose-docs h2 { letter-spacing: -0.02em; } .docs-sidebar { background: #fafafa; }"
}

Multiline strings work — JSON allows \n literal escapes. Whatever you commit shows up in the dashboard panel on next load, and vice versa.

Scoping recommendations

To avoid surprises in future renderer updates, scope your selectors to the docs surface:

  • #docs-root — wraps the entire docs renderer

  • .prose-docs — the long-form content area

  • .docs-sidebar — the left navigation

  • .docs-header — the top bar

  • .docs-toc — the right-side table of contents (when shown)

What you can override

  • Colors (background, text, accents) beyond what colors in config.json gives you

  • Spacing, typography sizes, font features

  • Section borders, dividers, callout backgrounds

  • Code-block themes (target .shiki or .prose-docs pre)

  • Sidebar collapsing animations, hover states

  • Print styles via @media print

What's NOT supported

  • JavaScript. Custom CSS only — no <script> injection. JS injection is intentionally out of scope to keep the surface XSS-safe across multi-tenant environments.

  • External @font-face imports — host fonts on a domain that allows cross-origin (or use typography.fontFamily in config.json which routes through Google Fonts).

Plan availability

PlanCustom CSS
Free
Pro
Team
Enterprise

Save behaviour

  • The save button only enables when the CSS has changed.

  • A successful save commits to nookdocs.config.json on the current branch (Editor → Branch selector). Production previews follow your usual deploy flow.

  • If you downgrade from Pro to Free, your existing CSS keeps rendering — the editor just becomes read-only / locked. Removing the field requires re-upgrading first.

For LLMs

If you're an AI agent generating custom CSS for a NookDocs site, here's the canonical recipe:

1. Config field contract:

{
  "name": "your-docs",
  "customCss": "#docs-root .prose-docs h2 { letter-spacing: -0.02em; } .docs-sidebar { background: #fafafa; }"
}

Multi-line literal escapes (\n) are valid JSON. Field omission is the same as empty string — attribution renders normally.

2. Stable selector palette to target:

#docs-root             — entire docs renderer wrapper (highest scope)
.prose-docs             — long-form MDX content
.docs-sidebar          — left navigation rail
.docs-header           — top bar
.docs-toc              — right table of contents
.prose-docs code       — inline code
.prose-docs pre        — code blocks

Always scope new rules to one of these — never use bare element selectors (h1 { ... }) since they leak into the editor and dashboard chrome.

3. JS injection is rejected. This field is CSS only. <style>/<script> tags, @import, and expression(...) are rejected at save time (HTTP 422 with the reason), and tag-escape sequences are additionally neutralized at render time. Write bare CSS rules.

4. External fonts:

Use typography.fontFamily (separate config key) rather than @font-face inside customCss. The platform's font loader resolves licensing + preconnect hints automatically.

Common mistakes:

  • Don't propose !important chains — the cascade order is documented and stable; specificity tweaks are enough.

  • Don't override CSS custom properties prefixed --docs-* without checking the theme guide — those are tracked across themes and breaking them disables theme switching.

  • Save commits the change to nookdocs.config.json in the user's repo. There is no separate "preview" step before commit.

Was this page helpful?

Last updated August 7, 2026

Custom CSS | NookDocs | NookDocs