Docusaurus

Facebook製のReactベースドキュメント特化SSG。50k超のGitHubスターを持つ、技術ドキュメントサイトの決定版。

言語:JavaScript/TypeScript
フレームワーク:React
ビルド速度:Fast
GitHub Stars:50k
初回リリース:2017
人気ランキング:第11位

トレンド・動向

オープンソースプロジェクトのドキュメントサイトで広く採用。バージョニングや国際化機能が充実。

# 静的サイトジェネレータ Docusaurus ## 概要 DocusaurusはFacebook(Meta)が開発したReactベースのドキュメント特化型静的サイトジェネレータで、技術ドキュメントサイトの決定版として50k超のGitHubスターを誇ります。オープンソースプロジェクトやエンタープライズ製品のドキュメントサイト構築に最適化されており、バージョニング、国際化、検索機能、ダークモード等の高度な機能を標準装備。React、Vue、Angular等の主要OSSプロジェクトで採用実績があり、開発者が技術文書に集中できるよう設計された包括的なドキュメントプラットフォームです。 ## 詳細 Docusaurus 2025年版は第3世代として進化を続け、React 18とモダンWebスタンダードに完全対応した次世代ドキュメントプラットフォームを提供しています。MDXによる拡張可能なコンテンツ記述、TypeScript完全サポート、プラグインアーキテクチャによる柔軟な機能拡張を実現。企業レベルの要求に応える多言語対応、詳細なバージョン管理、高度な検索機能(Algolia統合)、アクセシビリティ準拠を標準提供し、開発者体験とエンドユーザー体験の両方を最適化。継続的なメンテナンスとアップデートにより、長期運用に適した安定性を確保しています。 ### 主要機能 - **ドキュメント特化設計**: 技術文書に最適化されたレイアウトと機能 - **Reactエコシステム**: 完全なReact/JSXサポートとコンポーネント再利用 - **バージョニング機能**: 複数バージョンのドキュメント並行管理 - **多言語対応**: 18n機能による国際化とローカライゼーション - **高度な検索**: Algolia統合による高性能な全文検索 - **PWAサポート**: プログレッシブWebアプリ機能とオフライン対応 ## メリット・デメリット ### メリット - Facebook製の信頼性と継続的なメンテナンス保証 - ドキュメントサイトに必要な機能を包括的に標準装備 - 優れた開発者体験とシンプルなセットアップフロー - 豊富な実績を持つOSSプロジェクトでの採用事例 - Reactスキルを活用した高度なカスタマイゼーション - SEO最適化とパフォーマンス最適化が標準実装 ### デメリット - ドキュメント以外の用途では機能過多になる可能性 - React/JavaScript知識が必要でデザイナーには敷居が高い - カスタマイゼーションがReactエコシステムに依存 - ビルド時間が大規模サイトで長くなる傾向 - プラグイン生態系がGatsbyほど豊富ではない - 学習コストがシンプルなSSGより高い ## 参考ページ - [Docusaurus 公式サイト](https://docusaurus.io/) - [Docusaurus ドキュメント](https://docusaurus.io/docs) - [Docusaurus GitHub リポジトリ](https://github.com/facebook/docusaurus) ## 書き方の例 ### インストールとプロジェクト作成 ```bash # Docusaurusプロジェクトの作成 npx create-docusaurus@latest my-website classic # TypeScript版の作成 npx create-docusaurus@latest my-website classic --typescript # プロジェクトディレクトリに移動 cd my-website # 開発サーバーの起動 npm start # 本番ビルド npm run build # ローカルでの本番サイト確認 npm run serve # 依存関係の更新 npm run docusaurus -- --version npm update @docusaurus/core @docusaurus/preset-classic ``` ### 基本設定(docusaurus.config.js) ```javascript // @ts-check // Note: type annotations allow type checking and IDEs autocompletion const lightCodeTheme = require('prism-react-renderer/themes/github'); const darkCodeTheme = require('prism-react-renderer/themes/dracula'); /** @type {import('@docusaurus/types').Config} */ const config = { title: 'My Site', tagline: 'Dinosaurs are cool', favicon: 'img/favicon.ico', // Set the production url of your site here url: 'https://your-docusaurus-test-site.com', // Set the /<baseUrl>/ pathname under which your site is served baseUrl: '/', // GitHub pages deployment config organizationName: 'your-org', // Usually your GitHub org/user name. projectName: 'my-website', // Usually your repo name. onBrokenLinks: 'throw', onBrokenMarkdownLinks: 'warn', // Even if you don't use internalization, you can use this field to set useful // metadata like html lang i18n: { defaultLocale: 'ja', locales: ['ja', 'en'], localeConfigs: { ja: { label: '日本語', direction: 'ltr', htmlLang: 'ja-JP', }, en: { label: 'English', direction: 'ltr', htmlLang: 'en-US', }, }, }, presets: [ [ 'classic', /** @type {import('@docusaurus/preset-classic').Options} */ ({ docs: { sidebarPath: require.resolve('./sidebars.js'), // Please change this to your repo. editUrl: 'https://github.com/your-org/my-website/tree/main/', showLastUpdateAuthor: true, showLastUpdateTime: true, // Multiple versions support versions: { current: { label: '2.0.0 (current)', path: 'current', }, '1.0.0': { label: '1.0.0', path: '1.0.0', }, }, }, blog: { showReadingTime: true, // Please change this to your repo. editUrl: 'https://github.com/your-org/my-website/tree/main/', feedOptions: { type: 'all', copyright: `Copyright © ${new Date().getFullYear()} My Project.`, }, }, theme: { customCss: require.resolve('./src/css/custom.css'), }, }), ], ], themeConfig: /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ ({ // Replace with your project's social card image: 'img/docusaurus-social-card.jpg', navbar: { title: 'My Site', logo: { alt: 'My Site Logo', src: 'img/logo.svg', }, items: [ { type: 'docSidebar', sidebarId: 'tutorialSidebar', position: 'left', label: 'Tutorial', }, {to: '/blog', label: 'Blog', position: 'left'}, { type: 'docsVersionDropdown', position: 'right', }, { type: 'localeDropdown', position: 'right', }, { href: 'https://github.com/your-org/my-website', label: 'GitHub', position: 'right', }, ], }, footer: { style: 'dark', links: [ { title: 'Docs', items: [ { label: 'Tutorial', to: '/docs/intro', }, ], }, { title: 'Community', items: [ { label: 'Stack Overflow', href: 'https://stackoverflow.com/questions/tagged/docusaurus', }, { label: 'Discord', href: 'https://discordapp.com/invite/docusaurus', }, { label: 'Twitter', href: 'https://twitter.com/docusaurus', }, ], }, { title: 'More', items: [ { label: 'Blog', to: '/blog', }, { label: 'GitHub', href: 'https://github.com/your-org/my-website', }, ], }, ], copyright: `Copyright © ${new Date().getFullYear()} My Project, Inc. Built with Docusaurus.`, }, prism: { theme: lightCodeTheme, darkTheme: darkCodeTheme, additionalLanguages: ['bash', 'json', 'python', 'java'], }, // Algolia search integration algolia: { appId: 'YOUR_APP_ID', apiKey: 'YOUR_SEARCH_API_KEY', indexName: 'YOUR_INDEX_NAME', contextualSearch: true, searchParameters: {}, searchPagePath: 'search', }, }), plugins: [ // PWA plugin [ '@docusaurus/plugin-pwa', { debug: true, offlineModeActivationStrategies: [ 'appInstalled', 'standalone', 'queryString', ], pwaHead: [ { tagName: 'link', rel: 'icon', href: '/img/docusaurus.png', }, { tagName: 'link', rel: 'manifest', href: '/manifest.json', }, { tagName: 'meta', name: 'theme-color', content: 'rgb(37, 194, 160)', }, ], }, ], ], }; module.exports = config; ``` ### ドキュメント作成とフロントマター ```markdown --- id: introduction title: はじめに sidebar_label: イントロ sidebar_position: 1 description: このドキュメントの紹介ページです keywords: [docusaurus, 入門, チュートリアル] slug: /intro last_update: date: 2025-01-01 author: あなたの名前 --- # はじめに このドキュメントサイトへようこそ! ## 概要 このサイトでは以下について説明します: - 基本的な使い方 - 高度な機能 - ベストプラクティス ## 重要なポイント :::tip 便利なヒント この機能を使うと作業効率が大幅に向上します。 ::: :::warning 注意 この操作は元に戻せないので注意してください。 ::: :::danger 危険 本番環境では絶対に実行しないでください。 ::: ## コードブロック ```javascript title="example.js" showLineNumbers function greet(name) { console.log(`Hello, ${name}!`); } // ハイライト greet('Docusaurus'); // highlight-line ``` ```bash # インストール npm install docusaurus # 起動 npm start ``` ## タブ機能 import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; <Tabs> <TabItem value="npm" label="npm" default> ```bash npm install @docusaurus/core ``` </TabItem> <TabItem value="yarn" label="Yarn"> ```bash yarn add @docusaurus/core ``` </TabItem> <TabItem value="pnpm" label="pnpm"> ```bash pnpm add @docusaurus/core ``` </TabItem> </Tabs> ## 詳細情報 詳細については[高度な機能](./advanced-features)を参照してください。 ``` ### サイドバー設定(sidebars.js) ```javascript /** * Creating a sidebar enables you to: - create an ordered group of docs - render a "Next" and "Previous" button - provide a description */ // @ts-check /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ const sidebars = { // デフォルトサイドバー tutorialSidebar: [ 'intro', { type: 'category', label: 'チュートリアル', items: [ 'tutorial-basics/create-a-page', 'tutorial-basics/create-a-document', 'tutorial-basics/markdown-features', 'tutorial-basics/deploy-your-site', ], }, { type: 'category', label: '高度な機能', collapsed: false, items: [ 'tutorial-extras/manage-docs-versions', 'tutorial-extras/translate-your-site', ], }, ], // API リファレンス用サイドバー apiSidebar: [ { type: 'autogenerated', dirName: 'api', // Generate sidebar slice from docs/api }, ], // カスタムサイドバー customSidebar: [ { type: 'doc', id: 'introduction', label: 'はじめに', }, { type: 'category', label: '基本機能', collapsible: true, collapsed: false, items: [ { type: 'autogenerated', dirName: 'basics', }, ], }, { type: 'link', label: '外部リンク', href: 'https://example.com', }, { type: 'html', value: '<hr>', }, { type: 'category', label: 'リソース', items: [ 'resources/faq', 'resources/troubleshooting', ], }, ], }; module.exports = sidebars; ``` ### カスタムReactコンポーネント ```jsx // src/components/HomepageFeatures/index.js import React from 'react'; import clsx from 'clsx'; import styles from './styles.module.css'; const FeatureList = [ { title: '使いやすさ', Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, description: ( <> Docusaurusは最初からユーザビリティを重視して設計されており、 素早くサイトを立ち上げて運用できます。 </> ), }, { title: '重要なことに集中', Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, description: ( <> Docusaurusを使うことで、ドキュメント作成に集中でき、 技術的な詳細はフレームワークが処理してくれます。 </> ), }, { title: 'Reactで強化', Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, description: ( <> Reactを使ってWebサイトを拡張・カスタマイズし、 レイアウトを自由自在にコントロールできます。 </> ), }, ]; function Feature({Svg, title, description}) { return ( <div className={clsx('col col--4')}> <div className="text--center"> <Svg className={styles.featureSvg} role="img" /> </div> <div className="text--center padding-horiz--md"> <h3>{title}</h3> <p>{description}</p> </div> </div> ); } export default function HomepageFeatures() { return ( <section className={styles.features}> <div className="container"> <div className="row"> {FeatureList.map((props, idx) => ( <Feature key={idx} {...props} /> ))} </div> </div> </section> ); } // src/pages/custom-page.js import React from 'react'; import Layout from '@theme/Layout'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; export default function CustomPage() { const {siteConfig} = useDocusaurusContext(); return ( <Layout title="カスタムページ" description="カスタムページの説明"> <div className="container margin-vert--lg"> <div className="row"> <div className="col col--8 col--offset-2"> <h1>カスタムページ</h1> <p>このページはReactで作成されたカスタムページです。</p> </div> </div> </div> </Layout> ); } ``` ### バージョニングと多言語対応 ```bash # バージョン管理 # 新しいバージョンの作成 npm run docusaurus docs:version 1.0.0 # 翻訳ファイルの初期化 npm run write-translations -- --locale ja # 翻訳ファイルの書き込み npm run write-heading-ids # 多言語対応での起動 npm run start -- --locale ja # 多言語対応でのビルド npm run build -- --locale ja # 全言語でのビルド npm run build ``` ```json // i18n/ja/docusaurus-plugin-content-docs/current.json { "version.label": { "message": "次期バージョン", "description": "The label for version current" }, "sidebar.tutorialSidebar.category.チュートリアル": { "message": "チュートリアル", "description": "The label for category チュートリアル in sidebar tutorialSidebar" }, "sidebar.tutorialSidebar.category.高度な機能": { "message": "高度な機能", "description": "The label for category 高度な機能 in sidebar tutorialSidebar" } } // i18n/ja/code.json { "theme.common.edit": { "message": "このページを編集", "description": "The edit button label" }, "theme.common.next": { "message": "次へ", "description": "The next button label" }, "theme.common.previous": { "message": "前へ", "description": "The previous button label" } } ``` ### カスタムCSS設定 ```css /* 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; --ifm-code-font-size: 95%; --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); } /* ダークモード対応 */ [data-theme='dark'] { --ifm-color-primary: #25c2a0; --ifm-color-primary-dark: #21af90; --ifm-color-primary-darker: #1fa588; --ifm-color-primary-darkest: #1a8870; --ifm-color-primary-light: #29d5b0; --ifm-color-primary-lighter: #32d8b4; --ifm-color-primary-lightest: #4fddbf; --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); } /* カスタムスタイリング */ .hero__title { font-size: 3rem; font-weight: 800; } .feature-card { padding: 2rem; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); transition: transform 0.2s ease-in-out; } .feature-card:hover { transform: translateY(-4px); } /* レスポンシブ対応 */ @media screen and (max-width: 996px) { .hero__title { font-size: 2rem; } } /* コードブロックのカスタマイズ */ .prism-code { border-radius: 8px; } /* アラートボックスのカスタマイズ */ .alert { border-left: 4px solid var(--ifm-color-primary); } ``` ### デプロイメント設定 ```yaml # .github/workflows/deploy.yml name: Deploy to GitHub Pages on: push: branches: - main permissions: contents: read pages: write id-token: write concurrency: group: "pages" cancel-in-progress: false jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 18 cache: npm - name: Install dependencies run: npm ci - name: Build website run: npm run build - name: Upload Build Artifact uses: actions/upload-pages-artifact@v3 with: path: build deploy: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest needs: build steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 ``` ```javascript // docusaurus.config.js - デプロイ設定 const config = { // GitHub Pages設定 url: 'https://your-username.github.io', baseUrl: '/your-project-name/', organizationName: 'your-username', projectName: 'your-project-name', trailingSlash: false, // その他のデプロイオプション deploymentBranch: 'gh-pages', // カスタムCNAME customFields: { CNAME: 'your-custom-domain.com', }, }; ```