Docusaurus

Facebook's React-based documentation-focused SSG. Over 50k GitHub stars, definitive choice for technical documentation sites.

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

トレンド・動向

Widely adopted for open source project documentation sites. Rich versioning and internationalization features.

# Static Site Generator Docusaurus ## Overview Docusaurus is a React-based documentation-focused static site generator developed by Facebook (Meta), serving as the definitive solution for technical documentation sites with over 50k GitHub stars. Optimized for building documentation websites for open source projects and enterprise products, it comes equipped with advanced features like versioning, internationalization, search functionality, and dark mode out of the box. With adoption by major OSS projects including React, Vue, and Angular, Docusaurus provides a comprehensive documentation platform designed to let developers focus on writing great technical content. ## Details Docusaurus 2025 edition continues to evolve as a third-generation platform, fully compatible with React 18 and modern web standards to provide a next-generation documentation experience. It offers extensible content authoring through MDX, complete TypeScript support, and flexible feature expansion through plugin architecture. Meeting enterprise-level requirements with multi-language support, detailed version management, advanced search capabilities (Algolia integration), and accessibility compliance as standard features, it optimizes both developer experience and end-user experience. With continuous maintenance and updates, it ensures stability suitable for long-term operation. ### Key Features - **Documentation-First Design**: Layout and functionality optimized for technical documentation - **React Ecosystem**: Complete React/JSX support and component reusability - **Versioning System**: Parallel management of multiple documentation versions - **Internationalization**: i18n functionality for globalization and localization - **Advanced Search**: High-performance full-text search with Algolia integration - **PWA Support**: Progressive Web App features with offline capabilities ## Pros and Cons ### Pros - Facebook-backed reliability with guaranteed continuous maintenance - Comprehensive standard features for all documentation site requirements - Excellent developer experience with simple setup workflow - Rich track record of adoption by proven OSS projects - Advanced customization leveraging React skills - Standard implementation of SEO and performance optimization ### Cons - May be over-featured for non-documentation use cases - Requires React/JavaScript knowledge, creating barriers for designers - Customization depends on React ecosystem - Build times tend to increase for large-scale sites - Plugin ecosystem less extensive than Gatsby - Higher learning curve compared to simpler SSGs ## Reference Pages - [Docusaurus Official Website](https://docusaurus.io/) - [Docusaurus Documentation](https://docusaurus.io/docs) - [Docusaurus GitHub Repository](https://github.com/facebook/docusaurus) ## Code Examples ### Installation and Project Creation ```bash # Create a Docusaurus project npx create-docusaurus@latest my-website classic # Create TypeScript version npx create-docusaurus@latest my-website classic --typescript # Navigate to project directory cd my-website # Start development server npm start # Production build npm run build # Serve built site locally npm run serve # Update dependencies npm run docusaurus -- --version npm update @docusaurus/core @docusaurus/preset-classic ``` ### Basic Configuration (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: 'Building amazing documentation', favicon: 'img/favicon.ico', // Set the production url of your site here url: 'https://your-docusaurus-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', // Internationalization configuration i18n: { defaultLocale: 'en', locales: ['en', 'ja', 'es', 'fr'], localeConfigs: { en: { label: 'English', direction: 'ltr', htmlLang: 'en-US', }, ja: { label: '日本語', direction: 'ltr', htmlLang: 'ja-JP', }, }, }, presets: [ [ 'classic', /** @type {import('@docusaurus/preset-classic').Options} */ ({ docs: { sidebarPath: require.resolve('./sidebars.js'), editUrl: 'https://github.com/your-org/my-website/tree/main/', showLastUpdateAuthor: true, showLastUpdateTime: true, // Multiple versions support versions: { current: { label: '3.0.0 (current)', path: 'current', banner: 'none', }, '2.0.0': { label: '2.0.0', path: '2.0.0', banner: 'unmaintained', }, }, // Only include specific versions onlyIncludeVersions: ['current', '2.0.0', '1.0.0'], }, blog: { showReadingTime: true, editUrl: 'https://github.com/your-org/my-website/tree/main/', blogSidebarCount: 'ALL', blogSidebarTitle: 'All posts', feedOptions: { type: 'all', copyright: `Copyright © ${new Date().getFullYear()} My Project.`, createFeedItems: async (params) => { const {blogPosts, defaultCreateFeedItems, ...rest} = params; return defaultCreateFeedItems({ // keep only the 10 most recent blog posts in the feed blogPosts: blogPosts.filter((item, index) => index < 10), ...rest, }); }, }, }, theme: { customCss: require.resolve('./src/css/custom.css'), }, gtag: { trackingID: 'G-XXXXXXXXXX', anonymizeIP: true, }, }), ], ], 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', srcDark: 'img/logo-dark.svg', }, hideOnScroll: false, items: [ { type: 'docSidebar', sidebarId: 'tutorialSidebar', position: 'left', label: 'Docs', }, { to: '/blog', label: 'Blog', position: 'left' }, { type: 'docsVersionDropdown', position: 'right', dropdownActiveClassDisabled: true, }, { type: 'localeDropdown', position: 'right', }, { href: 'https://github.com/your-org/my-website', position: 'right', className: 'header-github-link', 'aria-label': 'GitHub repository', }, ], }, footer: { style: 'dark', links: [ { title: 'Docs', items: [ { label: 'Getting Started', to: '/docs/intro', }, { label: 'API Reference', to: '/docs/api', }, ], }, { 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', }, { label: 'Changelog', href: 'https://github.com/your-org/my-website/releases', }, ], }, ], logo: { alt: 'My Site Logo', src: 'img/logo.svg', width: 160, height: 51, }, copyright: `Copyright © ${new Date().getFullYear()} My Project, Inc. Built with Docusaurus.`, }, prism: { theme: lightCodeTheme, darkTheme: darkCodeTheme, additionalLanguages: [ 'bash', 'json', 'python', 'java', 'php', 'ruby', 'go', 'rust', 'kotlin', 'swift' ], }, // Algolia search integration algolia: { appId: 'YOUR_APP_ID', apiKey: 'YOUR_SEARCH_API_KEY', indexName: 'YOUR_INDEX_NAME', contextualSearch: true, externalUrlRegex: 'external\\.com|domain\\.com', searchParameters: {}, searchPagePath: 'search', insights: false, }, // Announcement bar announcementBar: { id: 'support_us', content: 'We are looking to revamp our docs, please fill <a target="_blank" rel="noopener noreferrer" href="#">this survey</a>', backgroundColor: '#fafbfc', textColor: '#091E42', isCloseable: false, }, // Color mode configuration colorMode: { defaultMode: 'light', disableSwitch: false, respectPrefersColorScheme: true, }, }), 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)', }, { tagName: 'meta', name: 'apple-mobile-web-app-capable', content: 'yes', }, ], }, ], // Content plugins [ '@docusaurus/plugin-content-docs', { id: 'api', path: 'api', routeBasePath: 'api', sidebarPath: require.resolve('./sidebars-api.js'), editUrl: 'https://github.com/your-org/my-website/tree/main/', }, ], ], }; module.exports = config; ``` ### Documentation with Front Matter ```markdown --- id: getting-started title: Getting Started sidebar_label: Quick Start sidebar_position: 1 description: Learn how to get started with our platform keywords: [docusaurus, tutorial, getting started] slug: /getting-started image: /img/getting-started-social.png last_update: date: 2025-01-01 author: Your Name custom_edit_url: https://github.com/your-org/my-website/edit/main/docs/getting-started.md --- # Getting Started Welcome to our comprehensive guide! ## Overview This documentation will help you understand: - Basic concepts and terminology - Installation and setup process - Your first implementation - Best practices and common patterns ## Important Notes :::tip Pro Tip Using this feature will significantly improve your workflow efficiency. ::: :::warning Caution This operation cannot be undone, please proceed carefully. ::: :::danger Critical Never run this command in production environment. ::: :::info Information This feature is available in version 2.0 and later. ::: ## Code Examples ```javascript title="config.js" showLineNumbers const config = { apiKey: 'your-api-key', endpoint: 'https://api.example.com', // highlight-next-line timeout: 5000, retries: 3 }; export default config; ``` ```bash # Installation npm install our-package # Development server npm run dev # Production build npm run build ``` ## Interactive Tabs import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; <Tabs> <TabItem value="npm" label="npm" default> ```bash npm install @our-org/awesome-package ``` </TabItem> <TabItem value="yarn" label="Yarn"> ```bash yarn add @our-org/awesome-package ``` </TabItem> <TabItem value="pnpm" label="pnpm"> ```bash pnpm add @our-org/awesome-package ``` </TabItem> </Tabs> ## MDX Components import BrowserWindow from '@site/src/components/BrowserWindow'; <BrowserWindow> This content appears inside a browser window mockup! </BrowserWindow> ## API Reference | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `apiKey` | string | Yes | Your API authentication key | | `endpoint` | string | Yes | API endpoint URL | | `timeout` | number | No | Request timeout in milliseconds | ## Next Steps Continue to [Advanced Configuration](./advanced-config) to learn about more powerful features. ``` ### Sidebar Configuration (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 = { // Main tutorial sidebar tutorialSidebar: [ 'intro', { type: 'category', label: 'Getting Started', collapsible: true, collapsed: false, items: [ 'getting-started/installation', 'getting-started/quick-start', 'getting-started/configuration', ], }, { type: 'category', label: 'Guides', collapsible: true, collapsed: false, items: [ { type: 'autogenerated', dirName: 'guides', // Generate sidebar slice from docs/guides }, ], }, { type: 'category', label: 'API Reference', collapsible: true, collapsed: true, items: [ 'api/overview', { type: 'category', label: 'REST API', items: [ 'api/rest/authentication', 'api/rest/users', 'api/rest/projects', ], }, { type: 'category', label: 'GraphQL API', items: [ 'api/graphql/getting-started', 'api/graphql/schema', 'api/graphql/mutations', ], }, ], }, ], // API-specific sidebar apiSidebar: [ { type: 'autogenerated', dirName: 'api', }, ], // Community sidebar communitySidebar: [ 'community/overview', { type: 'link', label: 'Discord', href: 'https://discord.gg/your-server', }, { type: 'link', label: 'GitHub Discussions', href: 'https://github.com/your-org/your-repo/discussions', }, { type: 'html', value: '<hr>', }, { type: 'category', label: 'Contributing', items: [ 'community/contributing/getting-started', 'community/contributing/code-of-conduct', 'community/contributing/style-guide', ], }, ], // Changelog sidebar changelogSidebar: [ { type: 'doc', id: 'changelog/overview', label: 'Overview', }, { type: 'category', label: 'Releases', items: [ { type: 'autogenerated', dirName: 'changelog/releases', }, ], }, ], }; module.exports = sidebars; ``` ### Custom React Components ```jsx // src/components/HomepageFeatures/index.js import React from 'react'; import clsx from 'clsx'; import styles from './styles.module.css'; const FeatureList = [ { title: 'Easy to Use', Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, description: ( <> Docusaurus was designed from the ground up to be easily installed and used to get your website up and running quickly. </> ), }, { title: 'Focus on What Matters', Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, description: ( <> Docusaurus lets you focus on your docs, and we&apos;ll do the chores. Go ahead and move your docs into the <code>docs</code> directory. </> ), }, { title: 'Powered by React', Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, description: ( <> Extend or customize your website layout by reusing React. Docusaurus can be extended while reusing the same header and footer. </> ), }, ]; 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/components/BrowserWindow/index.js import React from 'react'; import clsx from 'clsx'; import styles from './styles.module.css'; export default function BrowserWindow({children, minHeight, url = 'http://localhost:3000'}) { return ( <div className={styles.browserWindow} style={{minHeight}}> <div className={styles.browserWindowHeader}> <div className={styles.buttons}> <span className={styles.dot} style={{background: '#f25f58'}} /> <span className={styles.dot} style={{background: '#fbbe3c'}} /> <span className={styles.dot} style={{background: '#58cb42'}} /> </div> <div className={clsx(styles.browserWindowAddressBar, 'text--truncate')}> {url} </div> <div className={styles.browserWindowMenuIcon}> <div> <span className={styles.bar} /> <span className={styles.bar} /> <span className={styles.bar} /> </div> </div> </div> <div className={styles.browserWindowBody}>{children}</div> </div> ); } // src/pages/showcase.js import React from 'react'; import Layout from '@theme/Layout'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; const projects = [ { title: 'React', description: 'A JavaScript library for building user interfaces', website: 'https://reactjs.org/', source: 'https://github.com/facebook/react', tags: ['opensource', 'facebook'], }, { title: 'Jest', description: 'Delightful JavaScript Testing Framework', website: 'https://jestjs.io/', source: 'https://github.com/facebook/jest', tags: ['opensource', 'testing'], }, ]; function Project({title, description, website, source, tags}) { return ( <div className="col col--4 margin-bottom--lg"> <div className="card"> <div className="card__header"> <h3>{title}</h3> </div> <div className="card__body"> <p>{description}</p> <div className="button-group button-group--block"> <a className="button button--secondary" href={website}> Website </a> {source && ( <a className="button button--secondary" href={source}> Source </a> )} </div> </div> <div className="card__footer"> <div className="tags"> {tags.map((tag) => ( <span key={tag} className="badge badge--secondary"> {tag} </span> ))} </div> </div> </div> </div> ); } export default function Showcase() { const {siteConfig} = useDocusaurusContext(); return ( <Layout title="Showcase" description="See who's using Docusaurus"> <div className="container margin-vert--lg"> <div className="text--center margin-bottom--xl"> <h1>Showcase</h1> <p>See what others have built with Docusaurus</p> </div> <div className="row"> {projects.map((project) => ( <Project key={project.title} {...project} /> ))} </div> </div> </Layout> ); } ``` ### Versioning and Internationalization ```bash # Version management # Create a new version npm run docusaurus docs:version 2.0.0 # List all versions npm run docusaurus docs:version:list # Initialize translation files npm run write-translations -- --locale ja # Write translation IDs npm run write-heading-ids # Start with specific locale npm run start -- --locale ja # Build specific locale npm run build -- --locale ja # Build all locales npm run build # Serve specific locale npm run serve -- --locale ja ``` ```json // i18n/en/docusaurus-plugin-content-docs/current.json { "version.label": { "message": "Next", "description": "The label for version current" }, "sidebar.tutorialSidebar.category.Getting Started": { "message": "Getting Started", "description": "The label for category Getting Started in sidebar tutorialSidebar" }, "sidebar.tutorialSidebar.category.Guides": { "message": "Guides", "description": "The label for category Guides in sidebar tutorialSidebar" } } // i18n/en/code.json { "theme.common.edit": { "message": "Edit this page", "description": "The edit button label" }, "theme.common.next": { "message": "Next", "description": "The next button label" }, "theme.common.previous": { "message": "Previous", "description": "The previous button label" }, "theme.docs.breadcrumbs.home": { "message": "Home page", "description": "The ARIA label for the home page in the breadcrumbs" }, "theme.docs.breadcrumbs.navAriaLabel": { "message": "Breadcrumbs", "description": "The ARIA label for the breadcrumbs" } } ``` ### Custom CSS and Theming ```css /* src/css/custom.css */ /* CSS Custom Properties for theming */ :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); /* Custom variables */ --ifm-font-family-base: 'Inter', system-ui, -apple-system, sans-serif; --ifm-font-family-monospace: 'JetBrains Mono', 'Fira Code', monospace; --ifm-line-height-base: 1.6; --ifm-spacing-horizontal: 1rem; --ifm-spacing-vertical: 1rem; } /* Dark theme overrides */ [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); } /* Custom component styles */ .hero__title { font-size: 3.5rem; font-weight: 800; line-height: 1.2; background: linear-gradient(45deg, var(--ifm-color-primary), var(--ifm-color-primary-light)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .hero__subtitle { font-size: 1.25rem; font-weight: 400; opacity: 0.8; } /* Feature cards */ .feature-card { background: var(--ifm-card-background-color); border: 1px solid var(--ifm-color-emphasis-200); border-radius: 12px; padding: 2rem; height: 100%; transition: all 0.2s ease-in-out; } .feature-card:hover { border-color: var(--ifm-color-primary); transform: translateY(-4px); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1); } /* Code blocks */ .prism-code { border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } .token.title { color: var(--ifm-color-info); } /* Custom admonitions */ .alert { border-left: 4px solid var(--ifm-alert-border-color); border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); } .alert--tip { --ifm-alert-background-color: var(--ifm-color-info-contrast-background); --ifm-alert-border-color: var(--ifm-color-info); --ifm-alert-foreground-color: var(--ifm-color-info-contrast-foreground); } /* Navigation enhancements */ .navbar { backdrop-filter: blur(10px); background-color: rgba(255, 255, 255, 0.9); } [data-theme='dark'] .navbar { background-color: rgba(24, 25, 26, 0.9); } .navbar__item { font-weight: 500; } /* GitHub link icon */ .header-github-link:hover { opacity: 0.6; } .header-github-link:before { content: ''; width: 24px; height: 24px; display: flex; background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") no-repeat; } [data-theme='dark'] .header-github-link:before { background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") no-repeat; } /* Responsive design */ @media screen and (max-width: 996px) { .hero__title { font-size: 2.5rem; } .feature-card { padding: 1.5rem; } } @media screen and (max-width: 768px) { .hero__title { font-size: 2rem; } } /* Table of contents */ .table-of-contents { border-left: 3px solid var(--ifm-color-primary); padding-left: 1rem; } .table-of-contents__link--active { color: var(--ifm-color-primary); font-weight: 600; } /* Pagination */ .pagination-nav__item { border-radius: 8px; border: 1px solid var(--ifm-color-emphasis-200); } .pagination-nav__item:hover { border-color: var(--ifm-color-primary); } ``` ### Deployment Configuration ```yaml # .github/workflows/deploy.yml name: Deploy to GitHub Pages on: push: branches: - main # Review gh actions docs if you want to further define triggers, paths, etc # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on permissions: contents: read pages: write id-token: write jobs: build: name: Build Docusaurus runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - 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: name: Deploy to GitHub Pages needs: build # Grant GITHUB_TOKEN the permissions required to make a Pages deployment permissions: pages: write # to deploy to Pages id-token: write # to verify the deployment originates from an appropriate source # Deploy to the github-pages environment environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 ``` ```javascript // docusaurus.config.js - Deployment configuration const config = { // GitHub Pages configuration url: 'https://your-username.github.io', baseUrl: '/your-repo-name/', organizationName: 'your-username', projectName: 'your-repo-name', trailingSlash: false, // Deploy branch deploymentBranch: 'gh-pages', // Custom domain customFields: { CNAME: 'docs.yoursite.com', }, // Environment variables customFields: { description: process.env.SITE_DESCRIPTION || 'Default description', keywords: process.env.SITE_KEYWORDS || 'docusaurus, docs', }, }; ```