Takazudo

dev-docusaurus-claude-resources

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.

Takazudo 10 1 Updated 3mo ago

Resources

1
GitHub

Install

npx skillscat add takazudo/claude-resources/dev-docusaurus-claude-resources

Install via the SkillsCat registry.

SKILL.md

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-matter npm 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 → use pnpm
  • package-lock.json → use npm
  • yarn.lock → use yarn

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-matter

Step 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 containing commands/, 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 from CLAUDE_DIR so that CLAUDE.md files at the project root are discovered while commands/skills/agents are read from .claude/.
  • DOCS_PREFIX: Controls the output directory under docs/. Default "claude" produces docs/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.json

Both 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:

  1. Add claude to the CATEGORY_STRUCTURE in generate-category-nav.mjs:
const CATEGORY_STRUCTURE = {
  // ... existing categories ...
  claude: ['claudemd', 'commands', 'skills', 'agents'],
};
  1. If the CategoryNav component needs to render pages within a specific subcategory, add an optional subcategory prop:
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

  1. Run the generation: node {DOCUSAURUS_ROOT}/scripts/generate-claude-docs.js
  2. Check that {DOCUSAURUS_ROOT}/docs/claude/ contains generated MDX files
  3. Check that {DOCUSAURUS_ROOT}/src/data/claude-sidebar.json was created
  4. 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:

  1. Discovers source files by scanning the Claude Code config directory (skips node_modules, broken symlinks, and non-existent directories gracefully)
  2. Parses YAML frontmatter using gray-matter to extract metadata (name, description, model) — all matter() calls are wrapped in try/catch for robustness
  3. 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="">)
  1. Generates individual MDX pages for each resource, plus index pages per category
  2. Generates sidebar JSON — a complete sidebar configuration written to src/data/claude-sidebar.json
  3. Removes stale files — writes new files first, then removes items not in the expected set (avoids transient missing-file errors). Uses fs.rmSync for directory cleanup.
  4. 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 .mdx files 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.js and adjust the Configuration section at the top.