Fix: Docusaurus Not Working — Build Failing, Sidebar Not Showing, or Plugin Errors
Quick Answer
How to fix Docusaurus issues — docs and blog configuration, sidebar generation, custom theme components, plugin setup, MDX compatibility, search integration, and deployment.
The Problem
The Docusaurus build fails with a cryptic error:
npm run build
# Error: [ERROR] Docusaurus found broken links!
# Or: Error: Module not found: Can't resolve '@docusaurus/theme-common'Or the sidebar doesn’t show your docs:
Sidebar appears but is empty — docs exist in the docs/ folderOr MDX content renders as plain text:
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs>
<TabItem value="npm">npm install</TabItem>
</Tabs>
<!-- Renders as plain text instead of tabbed interface -->Or a custom page component doesn’t render:
404 — page not found for a page in src/pages/Why This Happens
Docusaurus is a React-based static site generator optimized for documentation. Its plugin-driven architecture requires specific configuration:
- Broken links are treated as build errors — Docusaurus checks all internal links during build. A typo in a markdown link or a reference to a deleted page fails the build. This is intentional to catch dead links early.
- Sidebar is auto-generated from the file structure or configured manually — by default, Docusaurus scans the
docs/directory and creates a sidebar. Ifsidebars.jshas a manual config that doesn’t match the actual files, pages are missing from navigation. - MDX components must be from
@theme/— Docusaurus provides built-in components via@theme/imports. Using raw HTML or components from other libraries without wrapping them in MDX causes rendering issues. docusaurus.config.jsis the central configuration — presets, plugins, themes, and site metadata are all configured here. Missing presets (like@docusaurus/preset-classic) remove core features.
Fix 1: Set Up Docusaurus
npx create-docusaurus@latest my-docs classic --typescript
cd my-docs
npm start// docusaurus.config.ts
import type { Config } from '@docusaurus/types';
import type * as Preset from '@docusaurus/preset-classic';
const config: Config = {
title: 'My Project',
tagline: 'Docs for My Project',
favicon: 'img/favicon.ico',
url: 'https://docs.myproject.com',
baseUrl: '/',
organizationName: 'my-org',
projectName: 'my-project',
// Broken link handling
onBrokenLinks: 'throw', // 'throw' | 'warn' | 'ignore'
onBrokenMarkdownLinks: 'warn',
i18n: {
defaultLocale: 'en',
locales: ['en'],
},
presets: [
[
'classic',
{
docs: {
sidebarPath: './sidebars.ts',
editUrl: 'https://github.com/my-org/my-project/tree/main/',
showLastUpdateTime: true,
showLastUpdateAuthor: true,
},
blog: {
showReadingTime: true,
editUrl: 'https://github.com/my-org/my-project/tree/main/',
blogSidebarCount: 'ALL',
},
theme: {
customCss: './src/css/custom.css',
},
} satisfies Preset.Options,
],
],
themeConfig: {
navbar: {
title: 'My Project',
logo: { alt: 'Logo', src: 'img/logo.svg' },
items: [
{ type: 'docSidebar', sidebarId: 'docs', position: 'left', label: 'Docs' },
{ to: '/blog', label: 'Blog', position: 'left' },
{ href: 'https://github.com/my-org/my-project', label: 'GitHub', position: 'right' },
],
},
footer: {
style: 'dark',
copyright: `Copyright © ${new Date().getFullYear()} My Project.`,
},
prism: {
theme: require('prism-react-renderer').themes.github,
darkTheme: require('prism-react-renderer').themes.dracula,
additionalLanguages: ['bash', 'typescript', 'json', 'yaml'],
},
colorMode: {
defaultMode: 'light',
respectPrefersColorScheme: true,
},
} satisfies Preset.ThemeConfig,
};
export default config;Fix 2: Sidebar Configuration
// sidebars.ts
import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
const sidebars: SidebarsConfig = {
docs: [
// Simple link
'intro',
// Category with items
{
type: 'category',
label: 'Getting Started',
collapsed: false, // Expanded by default
items: [
'getting-started/installation',
'getting-started/configuration',
'getting-started/quick-start',
],
},
// Auto-generated from directory
{
type: 'category',
label: 'Guides',
items: [
{ type: 'autogenerated', dirName: 'guides' },
],
},
// Category with link
{
type: 'category',
label: 'API Reference',
link: {
type: 'generated-index',
title: 'API Reference',
description: 'All API endpoints and types.',
},
items: [
'api/authentication',
'api/users',
'api/posts',
],
},
// External link
{
type: 'link',
label: 'GitHub',
href: 'https://github.com/my-org/my-project',
},
],
};
export default sidebars;# Docs directory structure
docs/
├── intro.md # /docs/intro
├── getting-started/
│ ├── installation.md # /docs/getting-started/installation
│ ├── configuration.md
│ └── quick-start.md
├── guides/
│ ├── _category_.json # Auto-generated category config
│ ├── basic-usage.md
│ └── advanced.md
└── api/
├── authentication.md
├── users.md
└── posts.md// docs/guides/_category_.json — category metadata
{
"label": "Guides",
"position": 3,
"collapsed": false,
"collapsible": true
}Fix 3: MDX Components
---
title: Installation Guide
sidebar_position: 1
tags: [getting-started, setup]
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Admonition from '@theme/Admonition';
import CodeBlock from '@theme/CodeBlock';
# Installation
## System Requirements
:::info
Node.js 18 or higher is required.
:::
:::warning
**Breaking change:** Version 3.0 requires a new configuration format.
:::
:::danger
Never expose your API keys in client-side code.
:::
:::tip
Use `npx` to always run the latest version.
:::
## Install the Package
<Tabs groupId="package-manager">
<TabItem value="npm" label="npm" default>
```bash
npm install my-packageyarn add my-packagepnpm add my-packageCode Example
export default defineConfig({ // Options here });`}
## Fix 4: Custom Pages and Components
```typescript
// src/pages/index.tsx — custom homepage
import Layout from '@theme/Layout';
import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
export default function Home() {
const { siteConfig } = useDocusaurusContext();
return (
<Layout title="Home" description={siteConfig.tagline}>
<header style={{ textAlign: 'center', padding: '4rem 0' }}>
<h1>{siteConfig.title}</h1>
<p>{siteConfig.tagline}</p>
<Link
className="button button--primary button--lg"
to="/docs/intro"
>
Get Started
</Link>
</header>
</Layout>
);
}// src/components/FeatureCard.tsx — reusable component
export function FeatureCard({ title, description, icon }: {
title: string;
description: string;
icon: string;
}) {
return (
<div className="col col--4" style={{ padding: '1rem' }}>
<div style={{ textAlign: 'center' }}>
<span style={{ fontSize: '3rem' }}>{icon}</span>
<h3>{title}</h3>
<p>{description}</p>
</div>
</div>
);
}
// Use in MDX
import { FeatureCard } from '@site/src/components/FeatureCard';
<div className="row">
<FeatureCard icon="⚡" title="Fast" description="Blazing fast builds" />
<FeatureCard icon="🔧" title="Flexible" description="Highly customizable" />
<FeatureCard icon="📱" title="Responsive" description="Mobile-first design" />
</div>Fix 5: Search Integration
# Option 1: Algolia DocSearch (free for open-source)
# Apply at: https://docsearch.algolia.com/// docusaurus.config.ts — Algolia search
themeConfig: {
algolia: {
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_SEARCH_API_KEY', // Public search-only key
indexName: 'my-project',
contextualSearch: true,
},
},# Option 2: Local search (no external service)
npm install @easyops-cn/docusaurus-search-local// docusaurus.config.ts — local search plugin
themes: [
[
'@easyops-cn/docusaurus-search-local',
{
hashed: true,
language: ['en'],
highlightSearchTermsOnTargetPage: true,
docsRouteBasePath: '/docs',
},
],
],Fix 6: Deployment
# Build static site
npm run build
# Test the build locally
npm run serve# GitHub Pages — built-in command
GIT_USER=your-username npm run deploy
# Or via GitHub Actions# .github/workflows/deploy.yml
name: Deploy Docusaurus
on:
push:
branches: [main]
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20, cache: npm }
- run: npm ci
- run: npm run build
- uses: actions/upload-pages-artifact@v3
with: { path: build }
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4Still Not Working?
“Docusaurus found broken links” — this is a build error, not a warning. Fix the links or temporarily set onBrokenLinks: 'warn' in docusaurus.config.ts. Common causes: typos in markdown links, linking to deleted pages, or missing trailing slashes. Run npm run build to see all broken links at once.
Sidebar shows “undefined” for a category — the _category_.json file has invalid JSON or the label field is missing. Also check that sidebars.ts entries match actual file paths. 'getting-started/installation' expects docs/getting-started/installation.md to exist.
MDX compilation error — Docusaurus uses MDX v3. Some MDX v1/v2 syntax doesn’t work. Common issues: JSX expressions must be on their own line (not inline with markdown), { and } must be escaped in markdown text (use \{), and < in text must use <.
Custom CSS not applying — verify the CSS file path in docusaurus.config.ts matches: theme: { customCss: './src/css/custom.css' }. Use CSS custom properties to override theme values: --ifm-color-primary, --ifm-font-family-base, etc.
For related documentation issues, see Fix: Nextra Not Working and Fix: MDX Not Working.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: AutoAnimate Not Working — Transitions Not Playing, List Items Not Animating, or React State Changes Ignored
How to fix @formkit/auto-animate issues — parent ref setup, React useAutoAnimate hook, Vue directive, animation customization, disabling for specific elements, and framework integration.
Fix: Blurhash Not Working — Placeholder Not Rendering, Encoding Failing, or Colors Wrong
How to fix Blurhash image placeholder issues — encoding with Sharp, decoding in React, canvas rendering, Next.js image placeholders, CSS blur fallback, and performance optimization.
Fix: Embla Carousel Not Working — Slides Not Scrolling, Autoplay Not Starting, or Thumbnails Not Syncing
How to fix Embla Carousel issues — React setup, slide sizing, autoplay and navigation plugins, loop mode, thumbnail carousels, responsive breakpoints, and vertical scrolling.
Fix: Fumadocs Not Working — Pages Not Found, Search Not Indexing, or MDX Components Missing
How to fix Fumadocs documentation framework issues — Next.js App Router setup, content source configuration, sidebar generation, MDX components, search, OpenAPI integration, and custom themes.