Build modern documentation websites with Docusaurus. Covers docs, blog, pages, versioning, i18n, search integration, and deployment patterns. React-based with MDX support for interactive documentation.
Resources
1Install
npx skillscat add vamseeachanta/workspace-hub/docusaurus Install via the SkillsCat registry.
SKILL.md
Docusaurus Documentation Skill
Build fast, optimized documentation websites with Docusaurus. This skill covers project setup, versioning, internationalization, and search integration.
When to Use This Skill
USE When
- Building documentation for open source projects
- Need React components in documentation
- Require multi-version documentation
- Need internationalized documentation
- Want blog functionality alongside docs
- Building developer portals
- Need fast, SEO-optimized static sites
- Want MDX for interactive examples
DON'T USE When
- Simple single-page documentation (use basic HTML)
- Python-specific API docs with autodoc (use Sphinx)
- No React experience and simple needs (use MkDocs)
- Need real-time collaborative editing (use GitBook)
- Building slide presentations (use Marp)
Prerequisites
Installation
# Create new Docusaurus project
npx create-docusaurus@latest my-website classic
# With TypeScript
npx create-docusaurus@latest my-website classic --typescript
cd my-website
npm startSystem Requirements
- Node.js 18.0 or higher
- npm 8 or yarn 1.22+
- Git (for versioning features)
Core Capabilities
1. Project Structure
my-website/
├── blog/ # Blog posts
├── docs/ # Documentation
│ ├── intro.md
│ └── tutorial-basics/
├── src/
│ ├── components/ # React components
│ ├── css/ # Custom styles
│ └── pages/ # Custom pages
├── static/ # Static assets
├── docusaurus.config.js # Main configuration
└── sidebars.js # Sidebar configuration2. Main Configuration
// docusaurus.config.js
/** @type {import('@docusaurus/types').Config} */
const config = {
title: 'My Project',
tagline: 'A powerful documentation framework',
favicon: 'img/favicon.ico',
url: 'https://myproject.github.io',
baseUrl: '/',
organizationName: 'myorg',
projectName: 'my-project',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
i18n: {
defaultLocale: 'en',
locales: ['en'],
},
presets: [
['classic', {
docs: {
sidebarPath: './sidebars.js',
editUrl: 'https://github.com/myorg/my-project/tree/main/',
showLastUpdateTime: true,
},
blog: {
showReadingTime: true,
postsPerPage: 10,
},
theme: {
customCss: './src/css/custom.css',
},
}],
],
themeConfig: {
navbar: {
title: 'My Project',
logo: { alt: 'Logo', src: 'img/logo.svg' },
items: [
{ type: 'docSidebar', sidebarId: 'tutorialSidebar', label: 'Docs' },
{ to: '/blog', label: 'Blog' },
{ type: 'docsVersionDropdown' },
{ href: 'https://github.com/myorg/my-project', position: 'right' },
],
},
footer: {
style: 'dark',
links: [
{ title: 'Docs', items: [{ label: 'Getting Started', to: '/docs/intro' }] },
{ title: 'Community', items: [{ label: 'Discord', href: 'https://discord.gg/xxx' }] },
],
copyright: `Copyright ${new Date().getFullYear()} My Project.`,
},
prism: {
theme: require('prism-react-renderer').themes.github,
darkTheme: require('prism-react-renderer').themes.dracula,
additionalLanguages: ['bash', 'python', 'yaml'],
},
},
};
module.exports = config;3. Sidebar Configuration
// sidebars.js
const sidebars = {
tutorialSidebar: [
'intro',
{
type: 'category',
label: 'Getting Started',
collapsed: false,
items: [
'getting-started/installation',
'getting-started/quick-start',
],
},
{
type: 'category',
label: 'Guides',
link: { type: 'doc', id: 'guides/index' },
items: ['guides/basic-usage', 'guides/advanced'],
},
{
type: 'category',
label: 'Examples',
items: [{ type: 'autogenerated', dirName: 'examples' }],
},
],
};
module.exports = sidebars;4. Documentation Pages
<!-- docs/intro.md -->
---
id: intro
title: Introduction
sidebar_position: 1
description: Introduction to My Project
---
# Introduction
Welcome to **My Project** documentation!
## Quick Example
```javascript
import { MyProject } from 'my-project';
const project = new MyProject();:::tip Did you know?
You can use admonitions for callouts!
:::
### 5. MDX and React Components
```jsx
// docs/interactive-example.mdx
---
id: interactive-example
title: Interactive Example
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Interactive Example
<Tabs>
<TabItem value="js" label="JavaScript" default>
```javascript
function hello() {
console.log('Hello!');
}
def hello():
print("Hello!")
Inline JSX
export const Highlight = ({children, color}) => (
<span style={{ backgroundColor: color, padding: '0.2rem', borderRadius: '4px' }}>
{children}
);
This is highlighted text.
### 6. Admonitions
```markdown
:::note
This is a note.
:::
:::tip Pro Tip
Use tips for helpful suggestions.
:::
:::info
Informational content.
:::
:::caution
Warnings about potential issues.
:::
:::danger Critical
Critical warnings.
:::
:::note Custom Title
Admonition with custom title.
:::7. Blog Posts
<!-- blog/2024-01-15-release-v2.md -->
---
slug: release-v2
title: Releasing Version 2.0
authors:
- name: John Doe
title: Lead Developer
image_url: https://github.com/johndoe.png
tags: [release, announcement]
image: /img/blog/v2-release.png
---
# Releasing Version 2.0
We are excited to announce v2.0!
<!-- truncate -->
## What's New
- Feature 1
- Feature 2
## Migration Guide
See our [migration guide](/docs/migration/v2).8. Versioning
# Create a new version
npm run docusaurus docs:version 1.0
# Creates:
# - versioned_docs/version-1.0/
# - versioned_sidebars/version-1.0-sidebars.json
# - versions.json// docusaurus.config.js
module.exports = {
presets: [['@docusaurus/preset-classic', {
docs: {
lastVersion: 'current',
versions: {
current: { label: '2.0 (Next)', path: 'next' },
'1.0': { label: '1.0', path: '1.0' },
},
},
}]],
};9. Internationalization (i18n)
// docusaurus.config.js
module.exports = {
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr', 'de'],
localeConfigs: {
en: { label: 'English', htmlLang: 'en-US' },
fr: { label: 'Francais', htmlLang: 'fr-FR' },
},
},
};# Generate translation files
npm run write-translations -- --locale fr
# Copy docs to translate
mkdir -p i18n/fr/docusaurus-plugin-content-docs/current
cp -r docs/* i18n/fr/docusaurus-plugin-content-docs/current/
# Start in French
npm run start -- --locale fr10. Search with Algolia
// docusaurus.config.js
module.exports = {
themeConfig: {
algolia: {
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indexName: 'your_index_name',
contextualSearch: true,
},
},
};# Alternative: Local search plugin
npm install @easyops-cn/docusaurus-search-local11. Custom CSS
/* src/css/custom.css */
:root {
--ifm-color-primary: #2e8555;
--ifm-code-font-size: 95%;
--ifm-font-family-base: 'Inter', sans-serif;
}
[data-theme='dark'] {
--ifm-color-primary: #25c2a0;
}
.navbar { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); }12. GitHub Pages Deployment
# .github/workflows/deploy.yml
name: Deploy to GitHub Pages
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:
environment:
name: github-pages
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/deploy-pages@v4# Manual deployment
npm run build
npm run deploy13. Vercel/Netlify Deployment
// vercel.json
{
"buildCommand": "npm run build",
"outputDirectory": "build",
"framework": "docusaurus-2"
}# netlify.toml
[build]
command = "npm run build"
publish = "build"Integration Examples
Integration with TypeDoc
npm install typedoc docusaurus-plugin-typedocmodule.exports = {
plugins: [
['docusaurus-plugin-typedoc', {
entryPoints: ['../src/index.ts'],
tsconfig: '../tsconfig.json',
out: 'api',
}],
],
};Integration with OpenAPI
npm install docusaurus-plugin-openapi-docs docusaurus-theme-openapi-docsmodule.exports = {
plugins: [
['docusaurus-plugin-openapi-docs', {
id: 'openapi',
config: {
petstore: {
specPath: 'api/openapi.yaml',
outputDir: 'docs/api',
},
},
}],
],
themes: ['docusaurus-theme-openapi-docs'],
};Best Practices
1. Documentation Structure
docs/
├── intro.md
├── getting-started/
│ ├── _category_.json
│ ├── installation.md
│ └── quick-start.md
├── guides/
│ ├── _category_.json
│ ├── index.md
│ └── advanced.md
├── api/
│ └── reference.md
├── faq.md
└── changelog.md// docs/getting-started/_category_.json
{
"label": "Getting Started",
"position": 1,
"collapsible": true,
"collapsed": false
}2. SEO Optimization
---
title: My Page | Brand Name
description: Description for search engines (150-160 chars)
keywords: [keyword1, keyword2]
image: /img/og/my-page.png
---3. Content Guidelines
---
id: unique-id
title: Clear Title
sidebar_label: Short Label
description: SEO description
---
# Page Title (H1 - only one)
## Section (H2)
### Subsection (H3)
:::tip Best Practice
Use admonitions appropriately.
:::
See also: [Related Page](./related.md)Troubleshooting
Build Fails with Module Not Found
rm -rf node_modules .docusaurus build
npm install
npm run buildHot Reload Not Working
npm run clear
npm run startBroken Links
module.exports = {
onBrokenLinks: 'warn', // Change from 'throw' for debugging
};i18n Build Issues
npm run build -- --locale en
npm run write-translations -- --locale frDebug Mode
DEBUG=docusaurus* npm run build
npm run start -- --port 3001Algolia Indexing Issues
// Check Algolia configuration
module.exports = {
themeConfig: {
algolia: {
appId: 'YOUR_APP_ID', // Not the API key
apiKey: 'SEARCH_ONLY_KEY', // Search-only API key
indexName: 'your_index',
debug: true, // Enable debug mode
},
},
};Version Dropdown Not Showing
// Ensure versions.json exists and navbar is configured
module.exports = {
themeConfig: {
navbar: {
items: [
{ type: 'docsVersionDropdown', position: 'right' },
],
},
},
};Advanced Configuration
Custom Homepage
// src/pages/index.js
import React from 'react';
import Layout from '@theme/Layout';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import styles from './index.module.css';
function HomepageHeader() {
const { siteConfig } = useDocusaurusContext();
return (
<header className={styles.heroBanner}>
<div className="container">
<h1 className="hero__title">{siteConfig.title}</h1>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<a className="button button--primary button--lg" href="/docs/intro">
Get Started
</a>
</div>
</div>
</header>
);
}
export default function Home() {
return (
<Layout title="Home" description="Welcome to our documentation">
<HomepageHeader />
<main>
<section className={styles.features}>
<div className="container">
<div className="row">
<Feature title="Easy to Use" description="Simple setup and configuration" />
<Feature title="Powerful" description="Full React and MDX support" />
<Feature title="Fast" description="Optimized for performance" />
</div>
</div>
</section>
</main>
</Layout>
);
}Plugin Development
// plugins/my-plugin/index.js
module.exports = function myPlugin(context, options) {
return {
name: 'my-plugin',
async loadContent() {
return { data: 'example' };
},
async contentLoaded({ content, actions }) {
const { createData, addRoute } = actions;
const dataPath = await createData('my-data.json', JSON.stringify(content));
addRoute({
path: '/custom-page',
component: '@site/src/components/CustomPage',
modules: { data: dataPath },
exact: true,
});
},
configureWebpack(config, isServer) {
return {
resolve: {
alias: { '@data': path.resolve(__dirname, 'data') },
},
};
},
};
};Version History
v1.0.0 (2026-01-17)
- Initial skill creation
- Project setup and configuration
- Documentation pages with MDX
- Blog functionality
- Sidebar configuration
- Theme customization
- Versioning setup
- Internationalization (i18n)
- Algolia search integration
- GitHub Pages deployment
- Best practices and troubleshooting
Related Resources
Build blazing-fast documentation websites with React and MDX.