AgentSkillsCN

docusaurus-doc-title

在 Docusaurus 站点的着陆页中添加具有展开/折叠导航功能的 DocsSitemap 组件。从 Markdown frontmatter 中提取 doc-titles.json,并以可折叠章节的形式呈现完整的文档站点地图。当用户提出“文档标题”、“文档站点地图”、“Docusaurus 文档标题”,或希望在 Docusaurus 站点上建立完整的文档索引时,可使用此技能。

SKILL.md
--- frontmatter
name: docusaurus-doc-title
description: >-
  Add DocsSitemap component with expand/collapse navigation to a Docusaurus site's landing page.
  Generates doc-titles.json from markdown frontmatter and renders a full docs sitemap with
  collapsible sections. Use when the user says 'doc titles', 'docs sitemap', 'docusaurus doc title',
  or wants a full documentation index on their Docusaurus site.
user-invocable: true

Docusaurus DocsSitemap (Doc Titles)

Add a DocsSitemap component that reads sidebars.ts (or .js) and doc-titles.json to render an expand/collapse full-page navigation on the Docusaurus landing page.

Prerequisites

  • gray-matter npm dependency
  • Docusaurus site with sidebars.ts (or .js)
  • routeBasePath set to /docs (so src/pages/index.tsx can serve as landing page)

Step 1: Detect Docusaurus Root

Find the directory containing docusaurus.config.ts (or docusaurus.config.js). This is the Docusaurus root directory, referred to as {DOCUSAURUS_ROOT} throughout this skill. All file paths below are relative to this root.

Step 2: Create the doc-titles generation script

Create {DOCUSAURUS_ROOT}/scripts/generate-doc-titles.js:

js
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const matter = require('gray-matter');

const DOCS_DIR = path.join(__dirname, '../docs');
const OUTPUT_FILE = path.join(__dirname, '../src/data/doc-titles.json');

The script recursively finds all .md/.mdx files in docs/, extracts title from frontmatter or first H1 heading, and outputs src/data/doc-titles.json as { "docId": "Title" }.

Step 3: Create the DocsSitemap component

Create {DOCUSAURUS_ROOT}/src/components/DocsSitemap/index.tsx:

tsx
import type { ReactNode } from 'react';
import useBaseUrl from '@docusaurus/useBaseUrl';
import sidebars from '@site/sidebars';
import docTitles from '@site/src/data/doc-titles.json';

function generateLabel(sidebarId: string): string {
  const name = sidebarId.replace(/Sidebar$/, '');
  // Add special cases as needed (e.g., inbox -> INBOX)
  return name.charAt(0).toUpperCase() + name.slice(1);
}

Key features:

  • Reads sidebar entries from sidebars.ts (or .js)
  • For autogenerated sidebar items, resolves docs from doc-titles.json by matching dirName prefix
  • Renders each sidebar as a <details>/<summary> section (open by default)
  • Animated chevron () rotates 90deg when open
  • Hover effect on summary uses --ifm-color-primary

For autogenerated sidebars, filter doc-titles.json entries by dirName/ prefix, excluding dirName/index, and render as links.

Step 4: Add to the landing page

Create {DOCUSAURUS_ROOT}/src/pages/index.tsx that imports and renders <DocsSitemap />. This requires routeBasePath in docusaurus.config.ts (or .js) to be /docs (not /).

Minimal landing page:

tsx
import Layout from '@theme/Layout';
import DocsSitemap from '@site/src/components/DocsSitemap';

export default function Home() {
  return (
    <Layout>
      <main style={{ padding: '2rem', maxWidth: '900px', margin: '0 auto' }}>
        <DocsSitemap />
      </main>
    </Layout>
  );
}

Step 5: Update config

In docusaurus.config.ts (or .js):

  • Change routeBasePath: '/' to routeBasePath: '/docs'
  • Update search plugin's docsRouteBasePath to /docs

Delete {DOCUSAURUS_ROOT}/docs/intro.md if it has slug: / (it conflicts with the new landing page).

Update any absolute doc links from /category/page to /docs/category/page.

Step 6: Wire up scripts and gitignore

In package.json, add:

json
"generate:doc-titles": "node scripts/generate-doc-titles.js"

Ensure generate script calls it, and start/build call generate first.

Add to .gitignore:

code
src/data/doc-titles.json

Step 7: Verify

Run pnpm run generate then pnpm run build. Verify the landing page shows expandable sidebar sections with all doc links.