Docusaurus
Quick Guide: Docusaurus 3.x is a React-powered static site generator for documentation. Configure everything in
docusaurus.config.js(ESM). Use@docusaurus/preset-classicfor docs + blog + pages + sitemap in one preset. Sidebars can be fully autogenerated from filesystem structure using_category_.jsonand front mattersidebar_position. Customize theme components via swizzling (prefer--wrapover--eject). MDX is the default content format — use front matter for metadata, admonitions for callouts, and import React components directly in.mdxfiles. Version docs withdocusaurus docs:version. Deploy thebuild/output to any static host.
<critical_requirements>
CRITICAL: Before Using This Skill
All code must follow project conventions in CLAUDE.md
(You MUST use docusaurus.config.js (or .ts) as the single source of truth for all site configuration — never scatter config across multiple files)
(You MUST use @docusaurus/preset-classic unless you have a specific reason to configure plugins individually — the preset bundles docs, blog, pages, sitemap, and theme)
(You MUST prefer --wrap over --eject when swizzling — wrapping preserves upstream updates, ejecting creates a maintenance burden)
(You MUST use front matter sidebar_position and _category_.json for sidebar ordering in autogenerated sidebars — do not fight the filesystem-driven convention)
(You MUST NOT mix versioned and unversioned docs in the same plugin instance — use separate plugin instances for different doc sets)
</critical_requirements>
Auto-detection: Docusaurus, docusaurus.config.js, docusaurus.config.ts, @docusaurus/preset-classic, @docusaurus/core, sidebars.js, docs:version, docusaurus build, docusaurus start, docusaurus deploy, docusaurus swizzle, MDX, category.json, sidebar_position, @site, @theme, @theme-original, plugin-content-docs, plugin-content-blog
When to use:
- Configuring
docusaurus.config.js(site metadata, presets, plugins, theme, navbar, footer) - Setting up or modifying sidebar structure (autogenerated or manual)
- Adding versioned documentation
- Customizing theme components via swizzling
- Writing MDX content with Docusaurus-specific features (admonitions, tabs, code blocks)
- Creating custom pages with React components
- Configuring the blog plugin
- Setting up search (Algolia DocSearch or local)
- Deploying Docusaurus to static hosting
- Configuring i18n / localization
When NOT to use:
- General React component patterns (Docusaurus uses React internally but this skill covers Docusaurus APIs, not React fundamentals)
- CSS/styling approaches not specific to Docusaurus theming (general CSS patterns are a separate concern)
- Git hooks, linting, or formatting setup (separate from documentation framework concerns)
- Content that belongs in the docs themselves, not the site framework
- VitePress — Vue-based, different config format and plugin system
- Nextra — Next.js-based, uses
_meta.jsonnot_category_.json, different routing model - Starlight — Astro-based, uses
astro.config.mjsand content collections, different architecture entirely
Examples
- Core Configuration & Sidebars — docusaurus.config.js, preset-classic, sidebars, front matter, custom pages
- MDX & Content — MDX features, admonitions, tabs, code blocks, assets, blog plugin
- Customization & Deployment — Swizzling, CSS variables, versioning, i18n, search, deployment
Other resources:
- Quick Reference — CLI commands, front matter fields, config option tables
<philosophy>
Philosophy
Docusaurus is an opinionated documentation framework that trades flexibility for convention. It makes strong decisions about routing (filesystem-based), content format (MDX), and structure (docs + blog + pages) so you can focus on writing content rather than building infrastructure.
Core principles:
- Convention over configuration — filesystem structure drives routing and sidebar generation; fight this and you fight the framework
- Preset-first —
preset-classicbundles the common plugin set; only decompose into individual plugins when you need multiple docs instances or unusual setups - Content as data — front matter is the metadata layer;
sidebar_position,slug,tags,custom_edit_urlall live in the document, not in external config - Swizzle, don't fork — customize theme components via the swizzle CLI; wrapping preserves upstream compatibility, ejecting creates a snapshot you must maintain
- Static output —
docusaurus buildproduces a static site; there is no server runtime, no SSR in production, no API routes
<patterns>
Core Patterns
Pattern 1: docusaurus.config.js Structure
The config file is the single entry point. It uses ESM (export default) and configures site metadata, presets (which bundle plugins + theme), and theme-level settings like navbar and footer.
// docusaurus.config.js — minimal production setup
export default {
title: "My Docs",
tagline: "Documentation for My Project",
url: "https://docs.example.com",
baseUrl: "/",
onBrokenLinks: "throw",
onBrokenMarkdownLinks: "throw",
favicon: "img/favicon.ico",
presets: [
[
"@docusaurus/preset-classic",
{
docs: {
sidebarPath: "./sidebars.js",
editUrl: "https://github.com/my-org/my-repo/edit/main/docs-site/",
showLastUpdateTime: true,
},
blog: { showReadingTime: true },
theme: { customCss: ["./src/css/custom.css"] },
},
],
],
themeConfig: {
navbar: {
title: "My Docs",
items: [
/* nav items */
],
},
footer: {
style: "dark",
links: [
/* footer columns */
],
},
docs: { sidebar: { hideable: true, autoCollapseCategories: true } },
},
};
Key gotcha: onBrokenLinks: 'throw' is essential for production — it fails the build on broken internal links rather than silently deploying dead links.
Full example: See examples/core.md for complete config with navbar, footer, and multi-instance docs setup.
Pattern 2: Sidebar Configuration
Docusaurus offers two sidebar strategies. Autogenerated sidebars derive structure from the filesystem and are the default recommendation. Manual sidebars give full control but require maintenance.
// sidebars.js — autogenerated (recommended)
export default {
docs: [{ type: "autogenerated", dirName: "." }],
};
Control ordering and labels via front matter and _category_.json:
---
sidebar_position: 3
sidebar_label: Quick Start
---
// docs/guides/_category_.json
{
"label": "Guides",
"position": 2,
"collapsible": true,
"collapsed": false,
"link": { "type": "generated-index", "title": "All Guides" }
}
Key gotcha: Without sidebar_position, items sort alphabetically by filename. Use number prefixes (01-intro.md) or front matter — but not both, as number prefixes are stripped from the URL slug.
Full example: See examples/core.md for manual sidebars, custom sidebar items generator, and multi-sidebar setups.
Pattern 3: Swizzling Theme Components
Swizzling lets you customize any theme component. Wrapping adds behavior around the original; ejecting gives you a full copy to modify.
# List all swizzlable components
npx docusaurus swizzle --list
# Wrap a component (SAFE — preserves upstream updates)
npx docusaurus swizzle @docusaurus/theme-classic Footer -- --wrap
# Eject a component (DANGEROUS — you own the snapshot)
npx docusaurus swizzle @docusaurus/theme-classic Footer -- --eject
// src/theme/Footer/index.js — wrapping example
import React from