Add a Claude Code resources documentation section to a Docusaurus site. Auto-discovers and generates browsable docs for CLAUDE.md files, commands, skills, and agents with autogenerated sidebar navigation and hot reload support. Use when: (1) User wants to document Claude Code resources in Docusaurus, (2) User says 'add claude resources', 'claude docs section', or 'show commands and skills', (3) User wants a navigable sidebar for Claude Code components.
Resources
1Install
npx skillscat add takazudo/claude-resources/dev-docusaurus-claude-resources Install via the SkillsCat registry.
Docusaurus Claude Resources
Add a documentation section to a Docusaurus site that auto-discovers and renders all Claude Code resources as browsable pages with autogenerated sidebar navigation.
Generates docs for four resource types:
- CLAUDE.md - All CLAUDE.md files found recursively in the project
- Commands - Custom slash commands from
commands/*.md(frontmatter:description) - Skills - Skill packages from
skills/*/SKILL.md(frontmatter:name,description), including nested reference pages - Agents - Custom subagents from
agents/*.md(frontmatter:name,description,model)
Empty categories are automatically hidden from the sidebar.
Prerequisites
- Docusaurus v3.x project
gray-matternpm package (for YAML frontmatter parsing)
Implementation Steps
Step 1: Detect Docusaurus Root and Package Manager
Find the Docusaurus project root by locating docusaurus.config.ts or docusaurus.config.js. Store this as {DOCUSAURUS_ROOT}.
Also identify the Claude Code configuration directory. This is typically a .claude/ subdirectory in the project root containing commands/, skills/, and agents/.
Detect the project's package manager by checking for lock files:
pnpm-lock.yaml→ usepnpmpackage-lock.json→ usenpmyarn.lock→ useyarn
Use the detected package manager for all commands in subsequent steps.
Step 2: Install dependency
cd {DOCUSAURUS_ROOT}
{pkg-manager} install --save-dev gray-matter
# e.g.: pnpm install --save-dev gray-matter
# e.g.: npm install --save-dev gray-matterStep 3: Create the generation script
Read assets/generate-claude-docs.js from this skill directory and copy it to {DOCUSAURUS_ROOT}/scripts/generate-claude-docs.js.
Then adjust the Configuration section at the top of the script:
// Where Claude Code resources live (commands/, skills/, agents/)
// For projects with .claude/ subdirectory, point to that directory
const CLAUDE_DIR = path.resolve(__dirname, "../../.claude");
// Project root for CLAUDE.md file discovery (scanned recursively)
const PROJECT_ROOT = path.resolve(__dirname, "../..");
// Docusaurus root (where docusaurus.config.js lives)
const DOCUSAURUS_ROOT = path.resolve(__dirname, "..");
// Doc prefix used in output path
const DOCS_PREFIX = "claude";
// Label shown in index page
const SECTION_LABEL = "Claude";Key configuration:
CLAUDE_DIR: Must point to the directory containingcommands/,skills/,agents/. For most projects this is{PROJECT_ROOT}/.claude. Adjust the relative path based on where the Docusaurus site lives within the project.PROJECT_ROOT: The project root where CLAUDE.md files are searched recursively. Kept separate fromCLAUDE_DIRso that CLAUDE.md files at the project root are discovered while commands/skills/agents are read from.claude/.DOCS_PREFIX: Controls the output directory underdocs/. Default"claude"producesdocs/claude/.SECTION_LABEL: The heading shown on the index page.
Step 4: Configure sidebar
The generation script outputs a sidebar JSON file at {DOCUSAURUS_ROOT}/src/data/claude-sidebar.json. Import this in the project's sidebars.ts (or sidebars.js):
import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
import claudeSidebarJson from './src/data/claude-sidebar.json';
const sidebars: SidebarsConfig = {
// ... existing sidebars ...
// Claude Code Resources (auto-generated)
claudeSidebar: claudeSidebarJson as SidebarsConfig['string'],
};
export default sidebars;Note on TypeScript: Use SidebarsConfig['string'] for the type assertion. SidebarItemConfig is not exported from the Docusaurus types package.
If the project uses sidebars.js (CommonJS):
const claudeSidebarJson = require('./src/data/claude-sidebar.json');
const sidebars = {
// ... existing sidebars ...
claudeSidebar: claudeSidebarJson,
};
module.exports = sidebars;The generated JSON fully controls sidebar ordering and category structure — no manual _category_.json files are needed.
Step 5: Add navbar item (optional)
In {DOCUSAURUS_ROOT}/docusaurus.config.ts (or .js), add a navbar item:
navbar: {
items: [
{
type: "docSidebar",
sidebarId: "claudeSidebar",
position: "left",
label: "Claude",
},
],
},Use type: "docSidebar" with sidebarId (not type: "doc" with docId) since the Claude sidebar is a separate sidebar.
Step 6: Add scripts
Add generation scripts to {DOCUSAURUS_ROOT}/package.json. Use the project's detected package manager for internal script references:
{
"scripts": {
"generate-claude-docs": "node scripts/generate-claude-docs.js",
"generate": "node scripts/generate-claude-docs.js",
"start": "{pkg-manager} run generate && docusaurus start",
"build": "{pkg-manager} run generate && docusaurus build"
}
}If the project already has other generation scripts (e.g., generate-doc-titles, generate-category-nav), compose them into a single generate script:
{
"scripts": {
"generate-claude-docs": "node scripts/generate-claude-docs.js",
"generate": "node scripts/generate-claude-docs.js && node scripts/generate-doc-titles.mjs && node scripts/generate-category-nav.mjs",
"start": "pnpm run generate && docusaurus start",
"build": "pnpm run generate && docusaurus build"
}
}Run generate-claude-docs first since it creates the docs directory that other generators may scan.
Step 7: Add generated files to .gitignore
Add to {DOCUSAURUS_ROOT}/.gitignore:
# Generated Claude Code docs
docs/claude/
# Generated sidebar JSON
src/data/claude-sidebar.jsonBoth the MDX docs and the sidebar JSON are regenerated on every build, so they should not be committed.
Step 8: Integration with existing CategoryNav (if applicable)
If the project uses a CategoryNav component (from the dev-docusaurus-category-nav skill) with a generate-category-nav script:
- Add
claudeto theCATEGORY_STRUCTUREingenerate-category-nav.mjs:
const CATEGORY_STRUCTURE = {
// ... existing categories ...
claude: ['claudemd', 'commands', 'skills', 'agents'],
};- If the
CategoryNavcomponent needs to render pages within a specific subcategory, add an optionalsubcategoryprop:
interface CategoryNavProps {
category: CategoryKey;
subcategory?: string;
}This allows generated index pages to render only their category's pages (e.g., <CategoryNav category="claude" subcategory="commands" />).
Step 9: Verify
- Run the generation:
node {DOCUSAURUS_ROOT}/scripts/generate-claude-docs.js - Check that
{DOCUSAURUS_ROOT}/docs/claude/contains generated MDX files - Check that
{DOCUSAURUS_ROOT}/src/data/claude-sidebar.jsonwas created - Start the dev server and verify:
- Sidebar shows categories (CLAUDE.md, Commands, Skills, Agents)
- Each resource page renders correctly
- Empty categories are hidden
How It Works
The generation script runs before Docusaurus starts and:
- Discovers source files by scanning the Claude Code config directory (skips
node_modules, broken symlinks, and non-existent directories gracefully) - Parses YAML frontmatter using
gray-matterto extract metadata (name, description, model) — allmatter()calls are wrapped in try/catch for robustness - Escapes content for MDX compatibility:
- Preserves code blocks (including 4+ backtick fences) using placeholder replacement
- Escapes curly braces
{}outside code blocks - Escapes JSX-like tags: opening (
<Name>), closing (</Name>), self-closing (<Name />), and attributed (<Name attr="">)
- Generates individual MDX pages for each resource, plus index pages per category
- Generates sidebar JSON — a complete sidebar configuration written to
src/data/claude-sidebar.json - Removes stale files — writes new files first, then removes items not in the expected set (avoids transient missing-file errors). Uses
fs.rmSyncfor directory cleanup. - Hides empty categories automatically (if no commands exist, the Commands category is omitted from both docs and sidebar)
Skills with references/*.md subdirectories become nested sidebar categories, with each reference as a child page. The skill doc itself is written as index.mdx inside the subdirectory so the category header links directly to the skill page (avoiding a duplicate sidebar entry). Each skill subcategory in the JSON sidebar has collapsed: true so reference lists are collapsed by default.
Hot Reload with File Watcher
For live development, add a file watcher that regenerates docs when source files change. Docusaurus's built-in file watching picks up the regenerated files automatically.
writeFileIfChanged optimization
The generation script only writes files whose content actually changed (already implemented in the asset). This is critical for Docusaurus HMR:
- Content edits to existing source files → only changed
.mdxfiles are written → Docusaurus does fast HMR (instant) - No actual changes → zero files written → Docusaurus does nothing
- File additions/removals → new routes created → Docusaurus does full webpack rebuild (~20-30s, unavoidable)
Watcher script
// watch-claude-sources.js
const DEBOUNCE_MS = 5000;
let timer = null;
function regenerate() {
execSync("node scripts/generate-claude-docs.js", { stdio: "inherit" });
}
function scheduleRegenerate() {
if (timer) clearTimeout(timer);
timer = setTimeout(regenerate, DEBOUNCE_MS);
}
// Watch source directories
fs.watch(commandsDir, { recursive: true }, scheduleRegenerate);
fs.watch(skillsDir, { recursive: true }, scheduleRegenerate);
fs.watch(agentsDir, { recursive: true }, scheduleRegenerate);Key design decisions:
- 5-second debounce — batches rapid edits into a single regeneration
- No dev server restart — the watcher only regenerates docs; Docusaurus's own file watcher handles the rest
- Run watcher as a detached background process alongside the Docusaurus dev server
Assets
assets/generate-claude-docs.js- The generation script. Copy to{DOCUSAURUS_ROOT}/scripts/generate-claude-docs.jsand adjust the Configuration section at the top.