# Docusaurus User Guide

## 1. Quick Start

Docusaurus is a static site generator built by Facebook, optimized for creating documentation websites with versioning, i18n, search, and blog support out of the box. It uses React for theming and MDX for content authoring, producing fast single-page applications from Markdown files.

**Key features:**

- Versioned documentation with automatic snapshot management
- Internationalization (i18n) with locale-aware content paths
- Algolia DocSearch integration for full-text search
- Blog engine with author management and RSS feeds
- MDX support — embed React components directly in Markdown
- Theme customization via swizzling (wrap or eject components)
- Progressive Web App (PWA) support for offline access
- Mermaid diagram rendering in Markdown

**Prerequisites:** Node.js >= 24.14

**Quickest way to start:**

```bash
npx create-docusaurus@latest my-site classic
```

```text
[INFO] Creating new Docusaurus project...
[SUCCESS] Created my-site.
```

```bash
cd my-site
npm start
```

```text
[SUCCESS] Docusaurus website is running at: http://localhost:3000/
```

> [!TIP]
> Add `--typescript` to scaffold a TypeScript project: `npx create-docusaurus@latest my-site classic --typescript`

**What to try next:**

- Edit `docs/intro.md` and watch it hot-reload in the browser
- Add a blog post in `blog/`
- Customize the navbar and footer in `docusaurus.config.js`
- See the Configuration section below for full config options

## 2. Installation

### System Requirements

| Requirement | Minimum |
|---|---|
| Node.js | >= 24.14 |
| Package manager | npm, Yarn (v1 or v4), pnpm, or Bun |
| Git | Required for `deploy` command and VCS-based metadata |
| OS | Windows, macOS, Linux |

### Installation Methods

=== "npm"
    ```bash
    npx create-docusaurus@latest my-site classic
    ```

=== "Yarn"
    ```bash
    yarn create docusaurus my-site classic
    ```

=== "pnpm"
    ```bash
    pnpm create docusaurus my-site classic
    ```

=== "Bun"
    ```bash
    bun create docusaurus my-site classic
    ```

> [!IMPORTANT]
> The `create-docusaurus` CLI auto-detects your package manager from lockfiles or `npm_config_user_agent`. Override explicitly with `--package-manager npm|yarn|pnpm|bun`.

### Template Options

The `classic` template (recommended) includes docs, blog, and pages plugins with the classic theme. Additional options:

| Template | Description |
|---|---|
| `classic` | Full-featured site with docs, blog, and pages |
| `classic --typescript` | Same as classic with TypeScript configuration |
| Git repo URL | Clone any Git repository as a template |
| Local path | Use a local directory as a template |

### Language Selection

If you don't pass `--javascript` or `--typescript`, the scaffolder prompts you to choose. TypeScript templates include a `tsconfig.json` that extends `@docusaurus/tsconfig`.

### Git Clone Strategy

When using a Git repository as a template, `create-docusaurus` supports multiple strategies:

| Strategy | Behavior |
|---|---|
| `deep` | Full clone |
| `shallow` | Depth-1 clone |
| `copy` | Depth-1 recursive clone |
| `custom` | User-defined Git command |

### Post-Install Verification

```bash
cd my-site
npx docusaurus --version
```

```text
3.9.2
```

```bash
npm start
```

```text
[SUCCESS] Docusaurus website is running at: http://localhost:3000/
```

### Install Troubleshooting

**Problem: `npx create-docusaurus` fails with permission errors**

Ensure you have write access to the target directory. On Unix systems, avoid running with `sudo` — instead fix npm global permissions.

**Problem: Node.js version too old**

```bash
node --version
```

Docusaurus requires Node.js >= 24.14. Use `nvm` or `fnm` to manage Node versions.

**Problem: Yarn PnP compatibility issues with Mermaid plugin**

Community issue #10645 reports that adding the Mermaid plugin can break builds when using Yarn v4 with PnP enabled. Switch to `nodeLinker: node-modules` in `.yarnrc.yml` as a workaround.

**Problem: Package manager detection incorrect**

Override with `--package-manager <name>` or delete stale lockfiles from the target directory before scaffolding.

**Problem: `Failed to update package.json`**

The scaffolder writes the final `package.json` after copying template files. Ensure the target directory is writable and no file locks are held.

> [!WARNING]
> If you scaffold into the current directory (`.`), `create-docusaurus` warns that the directory already exists. Use a fresh directory name for clean setups.

## 3. Configuration

Docusaurus is configured through a `docusaurus.config.js` (or `.ts`, `.mjs`, `.cjs`) file at your site root. This file exports a configuration object or an async function returning one.

### Minimal Configuration

```javascript
// docusaurus.config.js
/** @type {import('@docusaurus/types').Config} */
const config = {
  title: 'My Site',
  tagline: 'Dinosaurs are cool',
  url: 'https://my-site.com',
  baseUrl: '/',

  organizationName: 'my-org',
  projectName: 'my-site',

  presets: [
    [
      'classic',
      /** @type {import('@docusaurus/preset-classic').Options} */
      ({
        docs: { sidebarPath: './sidebars.js' },
        blog: { showReadingTime: true },
        theme: { customCss: './src/css/custom.css' },
      }),
    ],
  ],
};

module.exports = config;
```

### Common Configuration Options

| Option | Type | Default | Description |
|---|---|---|---|
| `title` | `string` | — | Site title (appears in navbar, browser tab) |
| `tagline` | `string` | — | Site tagline |
| `url` | `string` | — | Production URL of your site |
| `baseUrl` | `string` | `'/'` | Base URL path |
| `favicon` | `string` | — | Path to favicon |
| `trailingSlash` | `boolean \| undefined` | `undefined` | Append trailing slash to URLs |
| `i18n` | `object` | — | Internationalization configuration |
| `onBrokenLinks` | `string` | `'throw'` | Behavior on broken links: `'ignore'`, `'log'`, `'warn'`, `'throw'` |
| `onBrokenAnchors` | `string` | `'warn'` | Behavior on broken anchors |
| `onBrokenMarkdownLinks` | `string` | `'warn'` | Behavior on broken Markdown links |
| `staticDirectories` | `string[]` | `['static']` | Directories for static assets |
| `markdown` | `object` | — | Parser configuration (MDX options, mermaid) |

### User-Facing Environment Variables

| Variable | Purpose |
|---|---|
| `PORT` | Override dev server port (default: 3000) |
| `DOCUSAURUS_CLI_SITE_DIR` | Override default site directory |
| `DOCUSAURUS_CLI_CONFIG` | Override config file path |
| `BASE_URL` | Override `baseUrl` at build time |

> [!NOTE]
> For the complete configuration reference including all plugin options, theme config, deployment environment variables, and `future` flags, see the Admin Guide.

### Preset Classic Options

The `classic` preset bundles the most common plugins. Configure them within the preset:

```javascript
presets: [
  ['classic', {
    docs: {
      sidebarPath: './sidebars.js',
      editUrl: 'https://github.com/my-org/my-site/edit/main/',
      showLastUpdateAuthor: true,
      showLastUpdateTime: true,
    },
    blog: {
      showReadingTime: true,
      editUrl: 'https://github.com/my-org/my-site/edit/main/',
    },
    theme: {
      customCss: './src/css/custom.css',
    },
    sitemap: { changefreq: 'weekly', priority: 0.5 },
    gtag: { trackingID: 'G-XXXXXXXXXX' },
    googleTagManager: { containerId: 'GTM-XXXXXXX' },
  }],
],
```

The preset includes these plugins/themes:

| Plugin/Theme | Key |
|---|---|
| `@docusaurus/plugin-content-docs` | `docs` |
| `@docusaurus/plugin-content-blog` | `blog` |
| `@docusaurus/plugin-content-pages` | `pages` |
| `@docusaurus/theme-classic` | `theme` |
| `@docusaurus/plugin-sitemap` | `sitemap` |
| `@docusaurus/plugin-google-gtag` | `gtag` |
| `@docusaurus/plugin-google-tag-manager` | `googleTagManager` |
| `@docusaurus/plugin-google-analytics` | `googleAnalytics` |
| `@docusaurus/theme-search-algolia` | (if installed) |

Set any key to `false` to disable that plugin entirely.

## 4. Core Usage

### CLI Commands

Docusaurus provides 8 built-in commands, all invoked as `npx docusaurus <command>`:

| Command | Description |
|---|---|
| `start [siteDir]` | Start development server with hot reload |
| `build [siteDir]` | Build static site for production |
| `serve [siteDir]` | Serve the built site locally |
| `deploy [siteDir]` | Build and deploy to GitHub Pages |
| `swizzle [themeName] [componentName] [siteDir]` | Customize theme components |
| `clear [siteDir]` | Remove build artifacts and caches |
| `write-translations [siteDir]` | Extract translation message files |
| `write-heading-ids [siteDir] [files...]` | Generate heading IDs in Markdown |

> [!TIP]
> Plugins can register additional CLI commands via the `extendCli` lifecycle. If `npx docusaurus <command>` doesn't match a built-in, Docusaurus loads all plugins and checks for external command handlers.

#### Development Server — `start`

```bash
npx docusaurus start
```

| Option | Description |
|---|---|
| `-p, --port <port>` | Port number (default: 3000) |
| `-h, --host <host>` | Host binding (default: localhost) |
| `-l, --locale <locale>` | Run with a specific locale |
| `--no-open` | Don't auto-open browser |
| `--poll [interval]` | Use polling instead of filesystem watching |
| `--hot-only` | Don't fall back to page refresh on HMR failure |
| `--no-minify` | Disable JS minification |
| `--config <config>` | Path to config file |

#### Production Build — `build`

```bash
npx docusaurus build
```

```text
[INFO] [en] Creating an optimized production build...
[SUCCESS] Generated static files in "build".
```

| Option | Description |
|---|---|
| `--dev` | Build in development mode (full React error messages) |
| `--bundle-analyzer` | Visualize bundle size with interactive treemap |
| `--out-dir <dir>` | Output directory (default: `build`) |
| `-l, --locale <locale...>` | Build specific locale(s) only |
| `--no-minify` | Disable JS bundle minification |
| `--config <config>` | Path to config file |

#### Serve Built Site — `serve`

```bash
npx docusaurus serve
```

| Option | Description |
|---|---|
| `--dir <dir>` | Build output directory to serve (default: `build`) |
| `-p, --port <port>` | Port number (default: 3000) |
| `-h, --host <host>` | Host binding (default: localhost) |
| `--build` | Build before serving |
| `--no-open` | Don't auto-open browser (default in CI) |
| `--config <config>` | Path to config file |

#### Deploy to GitHub Pages — `deploy`

```bash
GIT_USER=<username> npx docusaurus deploy
```

| Option | Description |
|---|---|
| `-l, --locale <locale>` | Deploy specific locale(s) |
| `--out-dir <dir>` | Output directory (default: `build`) |
| `--skip-build` | Skip build step before deploying |
| `--target-dir <dir>` | Target directory for deployment |
| `--config <config>` | Path to config file |

> [!WARNING]
> The `deploy` command requires either `GIT_USER` or `USE_SSH=true` environment variable. Without one, deployment fails. Set `ORGANIZATION_NAME` and `PROJECT_NAME` in your config or as environment variables.

#### Theme Customization — `swizzle`

```bash
npx docusaurus swizzle [themeName] [componentName] [siteDir]
```

| Option | Description |
|---|---|
| `-w, --wrap` | Create a wrapper component |
| `-e, --eject` | Eject full source code |
| `-l, --list` | List available components |
| `-t, --typescript` | Use TypeScript files |
| `-j, --javascript` | Use JavaScript files |
| `--danger` | Enable swizzling for unsafe components |
| `--config <config>` | Path to config file |

#### Remove Build Artifacts — `clear`

```bash
npx docusaurus clear
```

Removes the `.docusaurus/` generated folder, the `build/` output folder, and bundler persistent caches from `node_modules/.cache` and `.yarn/.cache`.

#### Extract Translations — `write-translations`

```bash
npx docusaurus write-translations --locale fr
```

| Option | Description |
|---|---|
| `-l, --locale <locale>` | Target locale folder |
| `--override` | Overwrite existing translation messages |
| `--config <config>` | Path to config file |
| `--messagePrefix <prefix>` | Prefix for new untranslated messages |

#### Generate Heading IDs — `write-heading-ids`

```bash
npx docusaurus write-heading-ids
```

| Option | Description |
|---|---|
| `--syntax <syntax>` | `"classic"` for `{#id}` or `"mdx-comment"` for `{/* #id */}` |
| `--migrate` | Convert existing IDs to the target syntax |
| `--overwrite` | Regenerate all IDs from heading text |
| `--maintain-case` | Keep original casing instead of lowercasing |

### Writing Documentation

Place Markdown or MDX files in your `docs/` directory. Each file becomes a documentation page.

**Frontmatter metadata:**

```markdown
---
id: my-doc
title: My Document
sidebar_label: My Doc
sidebar_position: 3
slug: /custom-url
description: A description for SEO
draft: false
---

# My Document

Content goes here with **Markdown** and MDX support.
```

**Key frontmatter fields:**

| Field | Type | Description |
|---|---|---|
| `id` | `string` | Unique document identifier (defaults to filename) |
| `title` | `string` | Page title |
| `sidebar_label` | `string` | Label shown in sidebar (defaults to title) |
| `sidebar_position` | `number` | Order in sidebar |
| `slug` | `string` | Custom URL path |
| `description` | `string` | SEO meta description |
| `draft` | `boolean` | Hidden in production if `true` |
| `unlisted` | `boolean` | Accessible by URL but hidden from navigation |
| `last_update` | `object` | Override VCS-based last update info |
| `tags` | `string[]` | Tags for categorization |

> [!NOTE]
> The `draft` and `unlisted` frontmatter fields are production-only concepts. All pages are visible in development mode. Override this with the `SIMULATE_PRODUCTION_VISIBILITY` environment variable.

### Writing Blog Posts

Place files in `blog/` with the naming convention `YYYY-MM-DD-title.md`:

```markdown
---
title: My First Blog Post
authors:
  - name: Author Name
    title: Role
    url: https://github.com/author
    image_url: https://github.com/author.png
tags: [docusaurus, getting-started]
---

Blog post content. Everything above the truncation marker appears as the summary.

<!--truncate-->

Full content below the fold.
```

**Authors management:** Define reusable authors in `blog/authors.yml`:

```yaml
authorKey:
  name: Author Name
  title: Developer
  url: https://github.com/author
  image_url: https://github.com/author.png
  socials:
    github: author
    twitter: author
```

Then reference by key in frontmatter:

```yaml
authors: [authorKey]
```

The blog plugin generates individual author pages with configurable permalinks. Legacy fields (`author`, `author_title`, `author_url`, `author_image_url`) are supported but deprecated.

### Creating Pages

Place React components (`.js`/`.tsx`) or MDX files in `src/pages/`. Each file maps directly to a route:

| File | Route |
|---|---|
| `src/pages/index.js` | `/` |
| `src/pages/about.md` | `/about` |
| `src/pages/contact/index.tsx` | `/contact` |

Pages support the same `draft` and `unlisted` frontmatter as docs and blog posts. Edit URL generation is configurable per page.

### Internationalization (i18n)

Configure locales in `docusaurus.config.js`:

```javascript
i18n: {
  defaultLocale: 'en',
  locales: ['en', 'fr', 'zh-CN'],
},
```

Extract translation files:

```bash
npx docusaurus write-translations --locale fr
```

```text
[SUCCESS] Wrote translations to "i18n/fr".
```

Start the dev server in a specific locale:

```bash
npx docusaurus start --locale fr
```

Build all locales:

```bash
npx docusaurus build
```

Build a specific locale only:

```bash
npx docusaurus build --locale fr
```

> [!NOTE]
> Localized content lives in `i18n/{locale}/` directories. The system prioritizes localized paths over base content paths, so you can selectively translate individual files without duplicating the entire docs tree.

### Document Versioning

Create a version snapshot of your current docs:

```bash
npx docusaurus docs:version 1.0
```

This copies `docs/` to `versioned_docs/version-1.0/` and creates `versioned_sidebars/version-1.0-sidebars.json`. The current `docs/` directory becomes the "next" (unreleased) version. Configure the docs plugin to control version behavior (badges, banners, only-include-versions).

### Search with Algolia

Configure Algolia DocSearch in your theme config:

```javascript
themeConfig: {
  algolia: {
    appId: 'YOUR_APP_ID',
    apiKey: 'YOUR_SEARCH_API_KEY',
    indexName: 'YOUR_INDEX_NAME',
    searchPagePath: 'search',
  },
},
```

The theme generates an `opensearch.xml` for browser search integration and creates a dedicated search page at the configured `searchPagePath`.

## 5. Common Tasks

### Task: Set Up a Multi-Version Documentation Site

**Goal:** Maintain documentation for multiple released versions.

**Steps:**

1. Write your docs in `docs/` as usual
2. When releasing v1.0, snapshot:
   ```bash
   npx docusaurus docs:version 1.0
   ```
3. Continue editing `docs/` for the next version
4. Release v2.0:
   ```bash
   npx docusaurus docs:version 2.0
   ```
5. Configure the version dropdown in your navbar's `themeConfig`

**Verify:** The version dropdown appears in the navbar, and users can switch between versions.

**If it fails:** Ensure `versioned_docs/` and `versioned_sidebars/` directories are committed. Check that version names don't contain special characters.

### Task: Deploy to GitHub Pages

**Goal:** Publish your site to `https://<org>.github.io/<repo>/`.

**Prerequisites:** Git installed, GitHub repository configured.

**Steps:**

1. Configure your `docusaurus.config.js`:
   ```javascript
   url: 'https://my-org.github.io',
   baseUrl: '/my-repo/',
   organizationName: 'my-org',
   projectName: 'my-repo',
   trailingSlash: false,
   ```
2. Deploy using SSH:
   ```bash
   USE_SSH=true npx docusaurus deploy
   ```
   Or using HTTPS:
   ```bash
   GIT_USER=<your-github-username> npx docusaurus deploy
   ```

**Verify:** Visit `https://my-org.github.io/my-repo/` after deployment.

**If it fails:**
- Ensure `organizationName` and `projectName` are set
- Check that Git can push to the repo
- For organization sites (`<org>.github.io`), set `deploymentBranch` explicitly

### Task: Add a Custom Page with React

**Goal:** Create a custom page using React components.

**Steps:**

1. Create `src/pages/my-page.tsx`:
   ```tsx
   import type {ReactNode} from 'react';
   import Layout from '@theme/Layout';
   import Heading from '@theme/Heading';

   export default function MyPage(): ReactNode {
     return (
       <Layout title="My Page" description="A custom page">
         <main className="container margin-vert--lg">
           <Heading as="h1">My Custom Page</Heading>
           <p>This is a custom React page.</p>
         </main>
       </Layout>
     );
   }
   ```
2. Visit `http://localhost:3000/my-page`

### Task: Customize the Theme Colors

**Goal:** Match the site to your brand.

**Steps:**

1. Edit `src/css/custom.css`:
   ```css
   :root {
     --ifm-color-primary: #2e8555;
     --ifm-color-primary-dark: #29784c;
     --ifm-color-primary-darker: #277148;
     --ifm-color-primary-darkest: #205d3b;
     --ifm-color-primary-light: #33925d;
     --ifm-color-primary-lighter: #359962;
     --ifm-color-primary-lightest: #3cad6e;
   }
   ```
2. The dev server hot-reloads CSS changes immediately

### Task: Add Mermaid Diagrams to Docs

**Goal:** Render diagrams directly in Markdown.

**Steps:**

1. Install the theme:
   ```bash
   npm install @docusaurus/theme-mermaid
   ```
2. Add to `docusaurus.config.js`:
   ```javascript
   markdown: { mermaid: true },
   themes: ['@docusaurus/theme-mermaid'],
   ```
3. Use in Markdown:
   ````markdown
   ```mermaid
   graph TD;
     A-->B;
     A-->C;
     B-->D;
   ```
   ````

### Task: Set Up Client-Side Redirects

**Goal:** Redirect old URLs to new ones after restructuring docs.

**Steps:**

1. Install the plugin:
   ```bash
   npm install @docusaurus/plugin-client-redirects
   ```
2. Configure in `docusaurus.config.js`:
   ```javascript
   plugins: [
     ['@docusaurus/plugin-client-redirects', {
       redirects: [
         { from: '/old-page', to: '/new-page' },
         { from: ['/docs/old', '/docs/legacy'], to: '/docs/current' },
       ],
       fromExtensions: ['html', 'htm'],
       createRedirects(existingPath) {
         if (existingPath.includes('/docs/')) {
           return [existingPath.replace('/docs/', '/documentation/')];
         }
         return undefined;
       },
     }],
   ],
   ```

The plugin validates that all redirect destinations actually exist, deduplicates entries, and warns on conflicts with existing paths.

### Task: Enable PWA for Offline Access

**Goal:** Let users access docs offline.

**Steps:**

1. Install the plugin:
   ```bash
   npm install @docusaurus/plugin-pwa
   ```
2. Configure in `docusaurus.config.js`:
   ```javascript
   plugins: [
     ['@docusaurus/plugin-pwa', {
       debug: false,
       offlineModeActivationStrategies: [
         'appInstalled',
         'standalone',
         'queryString',
       ],
       pwaHead: [
         { tagName: 'link', rel: 'icon', href: '/img/logo.png' },
         { tagName: 'link', rel: 'manifest', href: '/manifest.json' },
         { tagName: 'meta', name: 'theme-color', content: '#2e8555' },
       ],
     }],
   ],
   ```

> [!NOTE]
> The PWA plugin only activates in production builds. You won't see service worker behavior during development. It is also incompatible with `hashRouter`.

### Task: Speed Up Builds with Docusaurus Faster

**Goal:** Reduce build times with Rspack and SWC.

**Steps:**

1. Install the package:
   ```bash
   npm install @docusaurus/faster
   ```
2. Enable in `docusaurus.config.js`:
   ```javascript
   future: {
     faster: {
       swcJsLoader: true,
       swcJsMinimizer: true,
       swcHtmlMinimizer: true,
       lightningCssMinimizer: true,
       rspackBundler: true,
       mdxCrossCompilerCache: true,
     },
   },
   ```

> [!TIP]
> Enable individual optimizations incrementally. Start with `swcJsLoader` and `swcJsMinimizer` for the biggest impact, then try `rspackBundler` for the full Webpack-to-Rspack switch. The `mdxCrossCompilerCache` flag caches MDX compilation across client/server builds in production.

### Task: Add Google Analytics / Tag Manager

**Goal:** Track site usage with Google's analytics services.

Configure in the classic preset:

```javascript
presets: [
  ['classic', {
    gtag: { trackingID: 'G-XXXXXXXXXX', anonymizeIP: true },
    // OR
    googleTagManager: { containerId: 'GTM-XXXXXXX' },
  }],
],
```

> [!NOTE]
> Analytics plugins only inject tracking scripts when `NODE_ENV=production`. They are inactive during development.

### Task: Use the npm2yarn Remark Plugin

**Goal:** Auto-generate tabbed code blocks showing npm, Yarn, pnpm, and Bun variants.

Add to your docs or blog plugin's `remarkPlugins`:

```javascript
docs: {
  remarkPlugins: [
    [require('@docusaurus/remark-plugin-npm2yarn'), { sync: true }],
  ],
},
```

Then write a single npm command in Markdown:

````markdown
```bash npm2yarn
npm install @docusaurus/core
```
````

The plugin renders tabs showing the equivalent command for each package manager.

## 6. Troubleshooting

### Diagnostic Decision Tree

```text
Build fails?
├── Syntax error in MDX? → Check for unescaped special characters ({, <, })
├── Broken link error? → Check onBrokenLinks config or fix the link
├── Out of memory? → Increase Node heap: NODE_OPTIONS=--max-old-space-size=4096
├── Webpack error? → Check for version conflicts in node_modules
└── Plugin error? → Ensure all @docusaurus/* packages are the same version

Dev server issues?
├── Port in use? → Use --port to specify another port
├── Hot reload not working? → Try --poll flag or check file watcher limits
└── Locale not loading? → Check i18n config and file placement
```

### Error: `Unexpected character '!' in MDX`

**Cause:** MDX parsing treats certain characters as JSX syntax. Using `!` before names (like in HTML comments `<!-- -->`) or in certain positions triggers Acorn parsing errors. Community issues #11934 and #11954 report this for standard `.md` files.

**Solution:**

1. Wrap problematic content in code fences
2. Use `{/* comment */}` instead of `<!-- comment -->` in MDX files
3. Escape special characters: `\{`, `\<`

**Prevention:** Use the `.md` format with CommonMark-compatible content for content-heavy files; reserve `.mdx` for files that need React components.

### Error: Build failing after webpack upgrade to v5.106.0

**Cause:** Webpack 5.106.0 introduced breaking changes affecting Docusaurus builds. This is tracked in community issue #11923 (20+ comments).

**Solution:**

1. Pin webpack in your `package.json` resolutions:
   ```json
   "resolutions": {
     "webpack": "5.105.0"
   }
   ```
2. Or upgrade to the latest Docusaurus patch release that addresses compatibility
3. Consider switching to Rspack via `@docusaurus/faster` to avoid Webpack issues entirely

**Prevention:** Lock dependency versions in CI environments.

### Error: `Git not installed or not added to PATH!`

**Cause:** The `deploy` command requires Git to be installed and accessible.

**Solution:**

1. Install Git for your platform
2. Verify: `git --version`
3. Ensure Git is in your system PATH

### Error: `Please set the GIT_USER environment variable`

**Cause:** Deploying via HTTPS requires `GIT_USER`.

**Solution:**

```bash
GIT_USER=your-username npx docusaurus deploy
```

Or use SSH instead:

```bash
USE_SSH=true npx docusaurus deploy
```

### Error: `Missing project organization name`

**Cause:** The `deploy` command needs `organizationName` in config or as an env var.

**Solution:**

Set in `docusaurus.config.js`:

```javascript
organizationName: 'my-org',
projectName: 'my-repo',
```

Or via environment variables:

```bash
ORGANIZATION_NAME=my-org PROJECT_NAME=my-repo npx docusaurus deploy
```

### Error: Code blocks flash in dark mode

**Cause:** CSS loads asynchronously, causing a flash of light-mode styles before dark mode applies. Tracked in community issue #11566.

**Solution:** Use the `colorMode.respectPrefersColorScheme` option in `themeConfig` and consider adding a blocking inline script to set the color mode class on `<html>` before the page renders.

### Error: i18n locales build but render English content

**Cause:** Locale-specific content files may not be properly placed or the locale directory structure is incorrect. Tracked in community issue #11952.

**Solution:**

1. Verify content exists in `i18n/{locale}/docusaurus-plugin-content-docs/current/`
2. Check that `i18n.locales` in config includes your locale
3. Build with explicit locale: `npx docusaurus build --locale fr`
4. Verify that the `i18n/{locale}` folder actually exists — its presence is how Docusaurus infers `translate = true`

### Error: Windows incorrect path conversion from Git POSIX paths

**Cause:** On Windows, Git POSIX paths (`/x/...`) get incorrectly converted to Windows paths (`X:\...`). Tracked in community issue #11920.

**Solution:** Use forward slashes consistently in your configuration. Set `core.autocrlf=true` in Git config.

### Error: Links with dots in directory names break the build

**Cause:** Docusaurus path resolution can treat dots in directory names as file extensions. Tracked in community issue #11940.

**Solution:** Avoid dots in directory names within your docs structure. Use hyphens instead.

### Error: `Docusaurus was unable to resolve the [plugin]`

**Cause:** Plugin module not found. The resolver checks these patterns in order: `@docusaurus/plugin-{name}`, `docusaurus-plugin-{name}`, then the literal module path.

**Solution:**

1. Verify the plugin is installed: `npm ls @docusaurus/plugin-{name}`
2. Check for typos in the plugin name
3. Ensure the plugin version matches your `@docusaurus/core` version

### Error: `Document id [id] used by [path1] and [path2]`

**Cause:** Two documents in the docs plugin share the same `id`. Document IDs must be unique within a plugin instance.

**Solution:** Give one of the documents a unique `id` in its frontmatter, or rename the file.

> [!WARNING]
> Always ensure all `@docusaurus/*` packages are on the same version. Version mismatches between core, plugins, and themes are the single most common source of cryptic build errors. Run `npm ls | grep docusaurus` to verify.

### Error: `no searchPagePath provided in themeConfig.algolia`

**Cause:** The Algolia search theme requires `searchPagePath` to generate the search page and OpenSearch XML.

**Solution:** Add `searchPagePath: 'search'` (or `false` to disable) to your `themeConfig.algolia` configuration.

### Build runs out of memory

**Cause:** Large sites with many pages, versioned docs, or heavy assets exhaust Node.js heap.

**Solution:**

```bash
NODE_OPTIONS=--max-old-space-size=4096 npx docusaurus build
```

For very large sites, also consider enabling `@docusaurus/faster` to reduce memory pressure through the Rspack bundler.

### Error: `Generating [feedType] feed failed`

**Cause:** Blog feed generation failed due to invalid frontmatter or missing required fields.

**Solution:**

1. Check blog post frontmatter for valid dates and required fields
2. Ensure `title` is present in every blog post

**Prevention:** Validate frontmatter before committing.

> [!CAUTION]
> The `docusaurus clear` command deletes the `.docusaurus/` generated folder and `build/` output. While this is safe and reversible, it means your next `start` or `build` will take longer as caches are regenerated.

### Error: `@docusaurus/tsconfig: baseUrl is deprecated in TypeScript 6.0`

**Cause:** TypeScript 6.0 deprecated the `baseUrl` tsconfig option. Tracked in community issue #11893.

**Solution:** Update to the latest `@docusaurus/tsconfig` package which addresses the deprecation.

### Error: `Using @docusaurus/faster on bigger sites with i18n breaks Cloudflare Pages`

**Cause:** The `@docusaurus/faster` package with Rspack can produce output that exceeds Cloudflare Pages limits on large i18n sites. Tracked in community issue #11961.

**Solution:** Disable `rspackBundler` in your `future.faster` config and keep Webpack as the bundler when deploying to Cloudflare Pages.

## 7. FAQ

**Q: How do I use TypeScript with Docusaurus?**

Scaffold with `--typescript` or add TypeScript manually. Docusaurus natively supports `.ts` and `.tsx` files for config, pages, and components. Add `@docusaurus/tsconfig` as a base:

```json
{ "extends": "@docusaurus/tsconfig" }
```

Run type checking with `tsc` — the Docusaurus build itself does not type-check.

**Q: Can I use Docusaurus without the blog or docs plugin?**

Yes. Configure the preset to disable either:

```javascript
presets: [
  ['classic', {
    docs: false,
    blog: false,
    pages: {},
    theme: {},
  }],
],
```

**Q: What's the difference between `start` and `serve`?**

`start` runs the development server with hot module replacement for active development. `serve` hosts the production `build/` output as static files for local preview. Use `serve --build` to build and serve in one step. In CI environments, `serve` defaults to `--no-open`.

**Q: How do I handle draft and unlisted pages?**

Set `draft: true` in frontmatter to hide pages entirely in production. Set `unlisted: true` to make them accessible by direct URL but hidden from navigation, search, and sitemaps. Both are visible in development mode.

**Q: How do I configure the sidebar?**

Create a `sidebars.js` file. Options include:

- **Auto-generated**: `module.exports = { docs: [{ type: 'autogenerated', dirName: '.' }] };`
- **Manual**: Explicitly list document IDs and categories
- **Mixed**: Combine auto-generated sections with manual entries

Sidebar items support `label`, `collapsed`, `position`, and `link` (category index pages). The sidebar loading pipeline is: load → normalize shorthands → validate → generate (unwrap autogenerated) → post-process (defaults, category links, flatten empty categories).

**Q: How do I add a custom plugin?**

Create a function matching the plugin interface and add it to your config:

```javascript
plugins: [
  function myPlugin(context, options) {
    return {
      name: 'my-plugin',
      async loadContent() { /* ... */ },
      async contentLoaded({ content, actions }) { /* ... */ },
    };
  },
],
```

Plugins can register CLI commands via the `extendCli` lifecycle, add webpack config via `configureWebpack`, and inject head tags via `injectHtmlTags`.

**Q: Can I use Vercel Analytics with Docusaurus?**

Yes. Install `@docusaurus/plugin-vercel-analytics` and add to your plugins:

```javascript
plugins: ['@docusaurus/plugin-vercel-analytics'],
```

**Q: How do I debug build issues?**

The debug plugin (included in the classic preset) exposes `/__docusaurus/debug` in development — inspect site config, routes, and plugin data. For build performance, enable `DOCUSAURUS_RSPACK_TRACE=true` to generate trace files, or use `@docusaurus/plugin-rsdoctor` for detailed build analysis.

**Q: How do I set a custom `trailingSlash` policy?**

Set `trailingSlash` in `docusaurus.config.js`:

- `true` — URLs always end with `/`
- `false` — URLs never end with `/`
- `undefined` (default) — no normalization

> [!TIP]
> When deploying to GitHub Pages, always set `trailingSlash` explicitly. Without it, GitHub Pages adds a trailing slash via a server redirect on direct access, which can cause SEO issues and break relative links.

**Q: What is the `@generated/` alias?**

Docusaurus plugins output data files to a generated directory (`.docusaurus/` by default). These files are aliased to `@generated/` so you can import them in your React components. For example, `@generated/docusaurus.config` provides the resolved site config.

**Q: How do I use the ESLint plugin?**

Install `@docusaurus/eslint-plugin` and add to your ESLint config. It provides rules to enforce Docusaurus coding conventions, including restrictions on synchronous filesystem operations and direct lodash imports.

---

_Generated May 2026 from facebook/docusaurus at 9929ac0. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
