Skip to main content
Technology & EngineeringDocument Generation Services291 lines

Docusaurus

Docusaurus: React-based static site generator for documentation sites, versioned docs, MDX support, search integration, i18n

Quick Summary21 lines
You are an expert in using Docusaurus for generating documentation websites.

## Key Points

- Use `autogenerated` sidebars for large doc trees and control ordering with `sidebar_position` frontmatter rather than manually listing every file.
- Tag every version release with `docs:version` so users on older releases can access matching documentation without confusion.
- Keep custom MDX components in `src/components/` and import them explicitly rather than using global scope to maintain clarity and avoid build surprises.
- Forgetting to set `onBrokenLinks: "throw"` — broken internal links silently pass during development and only surface after deployment, leading to 404s in production.

## Quick Example

```
Configure your JWT secret in the environment:
```

```
</TabItem>
  <TabItem value="oauth" label="OAuth 2.0">
```
skilldb get document-generation-services-skills/DocusaurusFull skill: 291 lines
Paste into your CLAUDE.md or agent config

Docusaurus — Document Generation

You are an expert in using Docusaurus for generating documentation websites.

Core Philosophy

Overview

Docusaurus is an open-source static site generator built by Meta, designed specifically for documentation websites. It combines React, MDX, and a plugin architecture to produce versioned, searchable, and translatable documentation sites. Choose Docusaurus when you need a full documentation portal with sidebar navigation, versioned docs per release, blog integration, and a polished developer experience out of the box.

Setup & Configuration

# Create a new Docusaurus site
npx create-docusaurus@latest my-docs classic --typescript

# Project structure
# my-docs/
#   docusaurus.config.ts   — main configuration
#   sidebars.ts            — sidebar navigation tree
#   docs/                  — markdown/MDX documentation files
#   blog/                  — blog posts
#   src/pages/             — custom React pages
#   static/                — static assets
// docusaurus.config.ts
import { Config } from "@docusaurus/types";
import type * as Preset from "@docusaurus/preset-classic";

const config: Config = {
  title: "My Project Docs",
  tagline: "Comprehensive documentation",
  url: "https://docs.example.com",
  baseUrl: "/",
  onBrokenLinks: "throw",
  onBrokenMarkdownLinks: "warn",
  favicon: "img/favicon.ico",

  i18n: {
    defaultLocale: "en",
    locales: ["en", "fr", "ja"],
  },

  presets: [
    [
      "classic",
      {
        docs: {
          sidebarPath: "./sidebars.ts",
          editUrl: "https://github.com/my-org/my-docs/tree/main/",
          showLastUpdateAuthor: true,
          showLastUpdateTime: true,
          versions: {
            current: { label: "Next", path: "next" },
          },
        },
        blog: {
          showReadingTime: true,
          blogSidebarCount: "ALL",
        },
        theme: {
          customCss: "./src/css/custom.css",
        },
      } satisfies Preset.Options,
    ],
  ],

  themeConfig: {
    navbar: {
      title: "My Project",
      items: [
        { type: "docSidebar", sidebarId: "tutorialSidebar", label: "Docs" },
        { to: "/blog", label: "Blog" },
        { type: "docsVersionDropdown", position: "right" },
        { type: "localeDropdown", position: "right" },
      ],
    },
    footer: {
      style: "dark",
      links: [
        {
          title: "Docs",
          items: [{ label: "Getting Started", to: "/docs/intro" }],
        },
      ],
    },
    algolia: {
      appId: "YOUR_APP_ID",
      apiKey: "YOUR_SEARCH_API_KEY",
      indexName: "my-docs",
    },
  } satisfies Preset.ThemeConfig,

  plugins: [
    [
      "@docusaurus/plugin-content-docs",
      {
        id: "api",
        path: "api-docs",
        routeBasePath: "api",
        sidebarPath: "./sidebarsApi.ts",
      },
    ],
  ],
};

export default config;
// sidebars.ts
import type { SidebarsConfig } from "@docusaurus/plugin-content-docs";

const sidebars: SidebarsConfig = {
  tutorialSidebar: [
    "intro",
    {
      type: "category",
      label: "Getting Started",
      collapsed: false,
      items: ["installation", "configuration", "first-steps"],
    },
    {
      type: "category",
      label: "Guides",
      items: [
        {
          type: "autogenerated",
          dirName: "guides",
        },
      ],
    },
    {
      type: "link",
      label: "API Reference",
      href: "/api",
    },
  ],
};

export default sidebars;

Core Patterns

MDX documentation pages with frontmatter

---
id: authentication
title: Authentication Guide
sidebar_label: Auth
sidebar_position: 2
tags: [auth, security, getting-started]
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

# Authentication

Set up authentication for your application.

<Tabs>
  <TabItem value="jwt" label="JWT" default>

```bash
npm install jsonwebtoken

Configure your JWT secret in the environment:

JWT_SECRET=your-secret-here
</TabItem> <TabItem value="oauth" label="OAuth 2.0">
npm install passport passport-google-oauth20
</TabItem> </Tabs>

:::tip Always rotate secrets in production on a regular schedule. :::

:::warning Never commit secrets to version control. :::


### Versioning documentation

```bash
# Tag current docs as version 1.0
npx docusaurus docs:version 1.0

# This creates:
#   versioned_docs/version-1.0/   — snapshot of docs/
#   versioned_sidebars/version-1.0-sidebars.json

# Continue editing docs/ for the "next" unreleased version
# Repeat when releasing 2.0:
npx docusaurus docs:version 2.0

Custom React components in docs

// src/components/ApiEndpoint.tsx
import React from "react";
import CodeBlock from "@theme/CodeBlock";

interface ApiEndpointProps {
  method: "GET" | "POST" | "PUT" | "DELETE";
  path: string;
  description: string;
  example?: string;
}

export default function ApiEndpoint({
  method,
  path,
  description,
  example,
}: ApiEndpointProps) {
  const colors = { GET: "#61affe", POST: "#49cc90", PUT: "#fca130", DELETE: "#f93e3e" };

  return (
    <div style={{ border: `2px solid ${colors[method]}`, borderRadius: 8, padding: 16, marginBottom: 16 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
        <span style={{ background: colors[method], color: "#fff", padding: "2px 8px", borderRadius: 4, fontWeight: "bold" }}>
          {method}
        </span>
        <code>{path}</code>
      </div>
      <p>{description}</p>
      {example && <CodeBlock language="json">{example}</CodeBlock>}
    </div>
  );
}

Building and deploying

# Build the static site
npm run build

# Output is in build/ — deploy to any static host
# Deploy to GitHub Pages
USE_SSH=true npx docusaurus deploy

# Serve locally to preview
npm run serve

Best Practices

  • Use autogenerated sidebars for large doc trees and control ordering with sidebar_position frontmatter rather than manually listing every file.
  • Tag every version release with docs:version so users on older releases can access matching documentation without confusion.
  • Keep custom MDX components in src/components/ and import them explicitly rather than using global scope to maintain clarity and avoid build surprises.

Common Pitfalls

  • Forgetting to set onBrokenLinks: "throw" — broken internal links silently pass during development and only surface after deployment, leading to 404s in production.
  • Overusing versioned docs — each version duplicates the entire docs folder, inflating build times and bundle size. Only version when a release introduces breaking changes that require distinct documentation.

Anti-Patterns

Using the service without understanding its pricing model. Cloud services bill differently — per request, per GB, per seat. Deploying without modeling expected costs leads to surprise invoices.

Hardcoding configuration instead of using environment variables. API keys, endpoints, and feature flags change between environments. Hardcoded values break deployments and leak secrets.

Ignoring the service's rate limits and quotas. Every external API has throughput limits. Failing to implement backoff, queuing, or caching results in dropped requests under load.

Treating the service as always available. External services go down. Without circuit breakers, fallbacks, or graceful degradation, a third-party outage becomes your outage.

Coupling your architecture to a single provider's API. Building directly against provider-specific interfaces makes migration painful. Wrap external services in thin adapter layers.

Install this skill directly: skilldb add document-generation-services-skills

Get CLI access →