diff --git a/.cspell.json b/.cspell.json index 82ebc2c41a..f55f6265d1 100644 --- a/.cspell.json +++ b/.cspell.json @@ -21,11 +21,13 @@ ], "ignorePaths": [ "CHANGELOG.md", + "patches", "packages/docusaurus-theme-translations/locales", "package.json", "yarn.lock", "project-words.txt", "__snapshots__", + "admin/scripts", "website/src/data/users.tsx", "website/src/data/tweets.tsx", "website/docusaurus.config.localized.json", diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ebe9e6a427..fcc62bf31d 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,32 +1,36 @@ { - "image": "mcr.microsoft.com/devcontainers/base:ubuntu-22.04", - "settings": { - "[typescript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true - }, - "[json]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true - }, - "[jsonc]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04", + "customizations": { + "vscode": { + "settings": { + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, + "[jsonc]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + } + }, + "extensions": [ + "dbaeumer.vscode-eslint", + "orta.vscode-jest", + "esbenp.prettier-vscode", + "streetsidesoftware.code-spell-checker" + ] } }, - "extensions": [ - "dbaeumer.vscode-eslint", - "orta.vscode-jest", - "esbenp.prettier-vscode", - "streetsidesoftware.code-spell-checker" - ], "forwardPorts": [3000], "containerUser": "vscode", "postCreateCommand": "yarn install", "waitFor": "postCreateCommand", // otherwise automated jest tests fail "features": { "node": { - "version": "18" + "version": "22" }, "github-cli": "latest" } diff --git a/.eslintrc.js b/.eslintrc.js index edfbf50d97..50453b0ada 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -380,7 +380,14 @@ module.exports = { // We don't provide any escape hatches for this rule. Rest siblings and // function placeholder params are always ignored, and any other unused // locals must be justified with a disable comment. - '@typescript-eslint/no-unused-vars': [ERROR, {ignoreRestSiblings: true}], + '@typescript-eslint/no-unused-vars': [ + ERROR, + { + ignoreRestSiblings: true, + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + }, + ], '@typescript-eslint/prefer-optional-chain': ERROR, '@docusaurus/no-html-links': ERROR, '@docusaurus/prefer-docusaurus-heading': ERROR, diff --git a/.github/workflows/argos.yml b/.github/workflows/argos.yml index 1fb67e6086..4493405645 100644 --- a/.github/workflows/argos.yml +++ b/.github/workflows/argos.yml @@ -30,7 +30,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Use Node.js - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: lts/* diff --git a/.github/workflows/build-blog-only.yml b/.github/workflows/build-blog-only.yml index 552328794b..71ae7a80b2 100644 --- a/.github/workflows/build-blog-only.yml +++ b/.github/workflows/build-blog-only.yml @@ -24,7 +24,7 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: lts/* cache: yarn diff --git a/.github/workflows/build-hash-router.yml b/.github/workflows/build-hash-router.yml index d425e991b6..7ac7d8b148 100644 --- a/.github/workflows/build-hash-router.yml +++ b/.github/workflows/build-hash-router.yml @@ -27,7 +27,7 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: lts/* cache: yarn diff --git a/.github/workflows/build-perf.yml b/.github/workflows/build-perf.yml index ab20d1f8f5..7a137c5d18 100644 --- a/.github/workflows/build-perf.yml +++ b/.github/workflows/build-perf.yml @@ -43,12 +43,12 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: lts/* cache: yarn - name: Track build size changes - uses: preactjs/compressed-size-action@6fa0e7ca017120c754863b31123c5ee2860fd434 # v2 + uses: preactjs/compressed-size-action@946a292cd35bd1088e0d7eb92b69d1a8d5b5d76a # v2 with: repo-token: ${{ secrets.GITHUB_TOKEN }} build-script: build:website:fast @@ -75,7 +75,7 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: lts/* cache: yarn diff --git a/.github/workflows/canary-release.yml b/.github/workflows/canary-release.yml index 2461b9c5bc..37d935ef5d 100644 --- a/.github/workflows/canary-release.yml +++ b/.github/workflows/canary-release.yml @@ -24,7 +24,7 @@ jobs: with: fetch-depth: 0 # Needed to get the commit number with "git rev-list --count HEAD" - name: Set up Node - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: lts/* cache: yarn diff --git a/.github/workflows/continuous-releases.yml b/.github/workflows/continuous-releases.yml index 3efe4903b0..c6510df788 100644 --- a/.github/workflows/continuous-releases.yml +++ b/.github/workflows/continuous-releases.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: lts/* cache: yarn diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 1a043372cf..c25f347e7d 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -15,4 +15,4 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Dependency Review - uses: actions/dependency-review-action@4081bf99e2866ebe428fc0477b69eb4fcda7220a # 4.4.0 + uses: actions/dependency-review-action@3b139cfc5fae8b618d3eae3675e383bb1769c019 # 4.5.0 diff --git a/.github/workflows/lighthouse-report.yml b/.github/workflows/lighthouse-report.yml index c267d3241b..0f30f8e391 100644 --- a/.github/workflows/lighthouse-report.yml +++ b/.github/workflows/lighthouse-report.yml @@ -24,7 +24,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Use Node.js - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: lts/* @@ -64,7 +64,7 @@ jobs: - name: Add Lighthouse stats as comment id: comment_to_pr - uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31 # 2.9.0 + uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # 2.9.1 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} number: ${{ github.event.pull_request.number }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 63929dc49a..d7891556f4 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -22,7 +22,7 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: lts/* cache: yarn @@ -33,7 +33,7 @@ jobs: - name: Check for suspicious yarn.lock # for allowed aliases, see https://github.com/yargs/cliui/pull/139/files#r1670711112 - run: yarn lockfile-lint --path yarn.lock --type yarn --allowed-hosts yarn --validate-https --validate-package-names --validate-integrity --empty-hostname=false --allowed-package-name-aliases react-loadable string-width-cjs strip-ansi-cjs wrap-ansi-cjs + run: yarn lockfile-lint --path yarn.lock --type yarn --allowed-hosts yarn --validate-https --validate-package-names --validate-integrity --empty-hostname=false --allowed-package-name-aliases react-loadable react-helmet-async string-width-cjs strip-ansi-cjs wrap-ansi-cjs - name: Lint run: | diff --git a/.github/workflows/showcase-test.yml b/.github/workflows/showcase-test.yml index 51aaa62586..e2deffb053 100644 --- a/.github/workflows/showcase-test.yml +++ b/.github/workflows/showcase-test.yml @@ -24,7 +24,7 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: lts/* cache: yarn diff --git a/.github/workflows/tests-e2e.yml b/.github/workflows/tests-e2e.yml index 16d3e5b4d5..7428d65a84 100644 --- a/.github/workflows/tests-e2e.yml +++ b/.github/workflows/tests-e2e.yml @@ -43,7 +43,7 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Use Node.js ${{ matrix.node }} - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: ${{ matrix.node }} cache: yarn @@ -68,7 +68,7 @@ jobs: env: # Our website should build even with limited memory # See https://github.com/facebook/docusaurus/pull/10590 - NODE_OPTIONS: '--max-old-space-size=250' + NODE_OPTIONS: '--max-old-space-size=300' DOCUSAURUS_PERF_LOGGER: 'true' working-directory: ../test-website @@ -84,7 +84,7 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Use Node.js LTS - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: lts/* cache: yarn @@ -153,7 +153,7 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Use Node.js LTS - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: lts/* cache: yarn @@ -181,7 +181,7 @@ jobs: env: # Our website should build even with limited memory # See https://github.com/facebook/docusaurus/pull/10590 - NODE_OPTIONS: '--max-old-space-size=250' + NODE_OPTIONS: '--max-old-space-size=300' DOCUSAURUS_PERF_LOGGER: 'true' working-directory: ../test-website @@ -193,7 +193,7 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Use Node.js LTS - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: lts/* cache: yarn @@ -223,6 +223,6 @@ jobs: env: # Our website should build even with limited memory # See https://github.com/facebook/docusaurus/pull/10590 - NODE_OPTIONS: '--max-old-space-size=250' + NODE_OPTIONS: '--max-old-space-size=300' DOCUSAURUS_PERF_LOGGER: 'true' working-directory: ../test-website diff --git a/.github/workflows/tests-swizzle.yml b/.github/workflows/tests-swizzle.yml index 468e0ba435..28bd4988c6 100644 --- a/.github/workflows/tests-swizzle.yml +++ b/.github/workflows/tests-swizzle.yml @@ -28,7 +28,7 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Node LTS - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: lts/* cache: yarn diff --git a/.github/workflows/tests-windows.yml b/.github/workflows/tests-windows.yml index 4b1fbd8215..5607646e12 100644 --- a/.github/workflows/tests-windows.yml +++ b/.github/workflows/tests-windows.yml @@ -34,7 +34,7 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Use Node.js ${{ matrix.node }} - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: ${{ matrix.node }} - name: Installation diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 41ad5ddc12..11a99731b8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,7 +32,7 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Use Node.js ${{ matrix.node }} - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version: ${{ matrix.node }} cache: yarn @@ -49,7 +49,7 @@ jobs: env: # Our website should build even with limited memory # See https://github.com/facebook/docusaurus/pull/10590 - NODE_OPTIONS: '--max-old-space-size=400' + NODE_OPTIONS: '--max-old-space-size=450' DOCUSAURUS_PERF_LOGGER: 'true' - name: Docusaurus site CSS order run: yarn workspace website test:css-order diff --git a/.prettierignore b/.prettierignore index fe032054f7..19af204b9c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,6 +4,7 @@ node_modules build coverage .docusaurus +.idea .svg *.svg diff --git a/CHANGELOG.md b/CHANGELOG.md index 48f8832f29..60cea2a92a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,92 @@ # Docusaurus Changelog +## 3.7.0 (2025-01-03) + +#### :rocket: New Feature + +- `docusaurus-faster`, `docusaurus` + - [#10800](https://github.com/facebook/docusaurus/pull/10800) feat(core): Turn Rspack incremental on by default (again) ([@slorber](https://github.com/slorber)) +- `docusaurus-plugin-content-blog`, `docusaurus-theme-classic` + - [#10768](https://github.com/facebook/docusaurus/pull/10768) feat(blog): Add author social icons for bluesky, mastodon, threads, twitch, youtube, instagram ([@GingerGeek](https://github.com/GingerGeek)) +- `create-docusaurus`, `docusaurus-mdx-loader`, `docusaurus-module-type-aliases`, `docusaurus-plugin-client-redirects`, `docusaurus-plugin-content-blog`, `docusaurus-plugin-content-docs`, `docusaurus-plugin-content-pages`, `docusaurus-plugin-debug`, `docusaurus-plugin-google-analytics`, `docusaurus-plugin-google-gtag`, `docusaurus-plugin-google-tag-manager`, `docusaurus-plugin-ideal-image`, `docusaurus-plugin-pwa`, `docusaurus-plugin-rsdoctor`, `docusaurus-plugin-sitemap`, `docusaurus-plugin-svgr`, `docusaurus-plugin-vercel-analytics`, `docusaurus-preset-classic`, `docusaurus-theme-classic`, `docusaurus-theme-common`, `docusaurus-theme-live-codeblock`, `docusaurus-theme-mermaid`, `docusaurus-theme-search-algolia`, `docusaurus-types`, `docusaurus` + - [#10763](https://github.com/facebook/docusaurus/pull/10763) feat: Add React 19 support to Docusaurus v3 ([@slorber](https://github.com/slorber)) +- `docusaurus-plugin-content-blog` + - [#10729](https://github.com/facebook/docusaurus/pull/10729) feat(blog): Add `frontMatter.sidebar_label` ([@slorber](https://github.com/slorber)) +- `docusaurus-module-type-aliases`, `docusaurus-plugin-svgr`, `docusaurus-preset-classic`, `docusaurus-types`, `docusaurus-utils`, `docusaurus` + - [#10677](https://github.com/facebook/docusaurus/pull/10677) feat(svgr): create new Docusaurus SVGR plugin ([@slorber](https://github.com/slorber)) + +#### :bug: Bug Fix + +- `docusaurus-remark-plugin-npm2yarn` + - [#10803](https://github.com/facebook/docusaurus/pull/10803) fix(npm-to-yarn): add missing npm-to-yarn converter for Bun ([@Lehoczky](https://github.com/Lehoczky)) +- `docusaurus-theme-classic`, `docusaurus-theme-common` + - [#10796](https://github.com/facebook/docusaurus/pull/10796) fix(theme): Footer Column/Link should merge provided className ([@slorber](https://github.com/slorber)) +- `docusaurus-bundler`, `docusaurus-theme-common` + - [#10786](https://github.com/facebook/docusaurus/pull/10786) fix(core): fix React hydration errors, change html minifier settings ([@slorber](https://github.com/slorber)) +- `docusaurus-theme-common` + - [#10782](https://github.com/facebook/docusaurus/pull/10782) fix(theme-common): code block magic comments should support SQL block comments ([@WillBlack403](https://github.com/WillBlack403)) +- `docusaurus-theme-translations` + - [#10783](https://github.com/facebook/docusaurus/pull/10783) fix(theme-translations): Add missing Dutch (nl) theme translations ([@janaukema](https://github.com/janaukema)) + - [#10760](https://github.com/facebook/docusaurus/pull/10760) fix(theme-translation): add missing Korean (ko) theme translations ([@effozen](https://github.com/effozen)) +- `docusaurus-plugin-content-docs` + - [#10754](https://github.com/facebook/docusaurus/pull/10754) fix(docs): fix sidebar item visibility bug for category index ([@slorber](https://github.com/slorber)) +- `docusaurus` + - [#10727](https://github.com/facebook/docusaurus/pull/10727) fix(core): fix codegen routesChunkName possible hash collision ([@slorber](https://github.com/slorber)) +- `docusaurus-mdx-loader` + - [#10723](https://github.com/facebook/docusaurus/pull/10723) fix(mdx-loader): fix md image paths with spaces bug related to transformImage encoding problem ([@slorber](https://github.com/slorber)) + +#### :memo: Documentation + +- [#10740](https://github.com/facebook/docusaurus/pull/10740) docs: Link initialization docs together ([@waldyrious](https://github.com/waldyrious)) + +#### :robot: Dependencies + +- [#10771](https://github.com/facebook/docusaurus/pull/10771) chore(deps): bump nanoid from 3.3.7 to 3.3.8 ([@dependabot[bot]](https://github.com/apps/dependabot)) +- [#10721](https://github.com/facebook/docusaurus/pull/10721) chore(deps): bump actions/dependency-review-action from 4.4.0 to 4.5.0 ([@dependabot[bot]](https://github.com/apps/dependabot)) + +#### :wrench: Maintenance + +- Other + - [#10770](https://github.com/facebook/docusaurus/pull/10770) chore: Devcontainer upgrade to Ubuntu Noble & Node 22 ([@GingerGeek](https://github.com/GingerGeek)) +- `docusaurus-theme-search-algolia` + - [#10801](https://github.com/facebook/docusaurus/pull/10801) refactor(algolia): simplify SearchBar component ([@slorber](https://github.com/slorber)) + - [#10672](https://github.com/facebook/docusaurus/pull/10672) chore(algolia): upgrade algoliasearch to v5 ([@millotp](https://github.com/millotp)) +- `docusaurus` + - [#10798](https://github.com/facebook/docusaurus/pull/10798) refactor(core): Use Intl native API to get locale direction, remove rtl-detect depend… ([@slorber](https://github.com/slorber)) + - [#10747](https://github.com/facebook/docusaurus/pull/10747) refactor(core): swizzle wrap should use ReactNode instead of JSX.Element ([@slorber](https://github.com/slorber)) +- `create-docusaurus`, `docusaurus-mdx-loader`, `docusaurus-module-type-aliases`, `docusaurus-plugin-content-blog`, `docusaurus-plugin-content-docs`, `docusaurus-plugin-content-pages`, `docusaurus-plugin-debug`, `docusaurus-plugin-ideal-image`, `docusaurus-plugin-pwa`, `docusaurus-theme-classic`, `docusaurus-theme-common`, `docusaurus-theme-live-codeblock`, `docusaurus-theme-mermaid`, `docusaurus-theme-search-algolia`, `docusaurus-types`, `docusaurus` + - [#10746](https://github.com/facebook/docusaurus/pull/10746) refactor: prepare types for React 19 ([@slorber](https://github.com/slorber)) +- `docusaurus-theme-common` + - [#10728](https://github.com/facebook/docusaurus/pull/10728) refactor(theme-common): change storageUtils useSyncExternalCode getSnapshot workaround ([@slorber](https://github.com/slorber)) + +#### Committers: 14 + +- Alvin Bryan ([@alvinometric](https://github.com/alvinometric)) +- Hichem Fantar ([@hichemfantar](https://github.com/hichemfantar)) +- Ivan Cheban ([@ivancheban](https://github.com/ivancheban)) +- Jake Boone ([@jakeboone02](https://github.com/jakeboone02)) +- Jan Aukema ([@janaukema](https://github.com/janaukema)) +- Lehoczky Zoltán ([@Lehoczky](https://github.com/Lehoczky)) +- Lin Huang ([@codimiracle](https://github.com/codimiracle)) +- Pierre Millot ([@millotp](https://github.com/millotp)) +- Sébastien Lorber ([@slorber](https://github.com/slorber)) +- Taylor Reece ([@taylorreece](https://github.com/taylorreece)) +- Waldir Pimenta ([@waldyrious](https://github.com/waldyrious)) +- William Black ([@WillBlack403](https://github.com/WillBlack403)) +- Zed Spencer-Milnes ([@GingerGeek](https://github.com/GingerGeek)) +- Zen ([@effozen](https://github.com/effozen)) + +## 3.6.3 (2024-11-22) + +#### :bug: Bug Fix + +- `docusaurus` + - [#10712](https://github.com/facebook/docusaurus/pull/10712) fix(core): disable Rspack incremental in dev ([@slorber](https://github.com/slorber)) + +#### Committers: 1 + +- Sébastien Lorber ([@slorber](https://github.com/slorber)) + ## 3.6.2 (2024-11-19) #### :bug: Bug Fix diff --git a/admin/new.docusaurus.io/package.json b/admin/new.docusaurus.io/package.json index 3e576eba88..73611bee0a 100644 --- a/admin/new.docusaurus.io/package.json +++ b/admin/new.docusaurus.io/package.json @@ -1,6 +1,6 @@ { "name": "new.docusaurus.io", - "version": "3.6.2", + "version": "3.7.0", "private": true, "scripts": { "start": "npx --package netlify-cli netlify dev" diff --git a/admin/scripts/test-release.sh b/admin/scripts/test-release.sh index 622c524c95..0ae82234a5 100755 --- a/admin/scripts/test-release.sh +++ b/admin/scripts/test-release.sh @@ -5,7 +5,9 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -set -euo pipefail +set -xeuo pipefail + +rm -rf ../test-website CUSTOM_REGISTRY_URL="http://localhost:4873" NEW_VERSION="$(node -p "require('./packages/docusaurus/package.json').version")-NEW" @@ -52,7 +54,8 @@ git diff --name-only -- '*.json' | sed 's, ,\\&,g' | xargs git checkout -- cd .. # Build skeleton website with new version -npm_config_registry="$CUSTOM_REGISTRY_URL" npx create-docusaurus@"$NEW_VERSION" test-website classic --javascript $EXTRA_OPTS +npm_config_registry="$CUSTOM_REGISTRY_URL" npx --yes --loglevel silly create-docusaurus@"$NEW_VERSION" test-website classic --javascript $EXTRA_OPTS + # Stop Docker container if [[ -z "${KEEP_CONTAINER:-true}" ]] && ( $(docker container inspect "$CONTAINER_NAME" > /dev/null 2>&1) ); then diff --git a/admin/test-bad-package/README.mdx b/admin/test-bad-package/README.mdx index 40abc5448c..260522db24 100644 --- a/admin/test-bad-package/README.mdx +++ b/admin/test-bad-package/README.mdx @@ -12,7 +12,7 @@ import {version as ReactVersion} from 'react'; import {version as ReactDOMVersion} from 'react-dom'; export function TestComponent() { - const expectedVersion = 18; + const expectedVersion = 19; if (!ReactVersion.startsWith(`${expectedVersion}`)) { throw new Error( `'test-bad-package/README.mdx' is rendered with bad React version: ${ReactVersion}`, diff --git a/admin/test-bad-package/package.json b/admin/test-bad-package/package.json index 62e38ed808..61fa670a38 100644 --- a/admin/test-bad-package/package.json +++ b/admin/test-bad-package/package.json @@ -1,6 +1,6 @@ { "name": "test-bad-package", - "version": "3.6.2", + "version": "3.7.0", "private": true, "dependencies": { "@mdx-js/react": "1.0.1", diff --git a/argos/package.json b/argos/package.json index 5445d71605..4e88441f02 100644 --- a/argos/package.json +++ b/argos/package.json @@ -1,6 +1,6 @@ { "name": "argos", - "version": "3.6.2", + "version": "3.7.0", "description": "Argos visual diff tests", "license": "MIT", "private": true, diff --git a/argos/tests/screenshot.spec.ts b/argos/tests/screenshot.spec.ts index bc14473055..d515fc0f33 100644 --- a/argos/tests/screenshot.spec.ts +++ b/argos/tests/screenshot.spec.ts @@ -55,7 +55,6 @@ function isBlacklisted(pathname: string) { '/tests/pages/react-18', // Flaky because of hydration error '/tests/blog/archive', - '/tests/docs/tests/custom-props', '/tests/pages/code-block-tests', '/tests/pages/embeds', // Flaky because of hydration error with docusaurus serve + .html @@ -131,23 +130,18 @@ function throwOnConsole(page: Page) { const typesToCheck = ['error', 'warning']; const ignoreMessages = [ - // This mismatch warning looks like a React 18 bug to me - 'Warning: Prop `%s` did not match. Server: %s Client: %s%s className "null" ""', - // TODO this fetch error message is unexpected and should be fixed // it's already happening in main branch 'Failed to load resource: the server responded with a status of 404 (Not Found)', - // TODO looks like a legit hydration bug to fix - // on /blog/releases/2.4 - 'Warning: Prop `%s` did not match. Server: %s Client: %s%s href "/docs" "/docs?docusaurus-theme=light"', - 'Warning: Prop `%s` did not match. Server: %s Client: %s%s href "/docs" "/docs?docusaurus-theme=dark"', - // on /blog/releases/3.0 - 'Warning: Prop `%s` did not match. Server: %s Client: %s%s href "/docs" "/docs?docusaurus-data-navbar=false&docusaurus-data-red-border"', - // on /docs/styling-layout - 'Warning: Prop `%s` did not match. Server: %s Client: %s%s href "/docs" "/docs?docusaurus-data-navbar=false&docusaurus-data-red-border"', - 'Warning: Prop `%s` did not match. Server: %s Client: %s%s href "/docs/configuration" "/docs/configuration?docusaurus-theme=light"', - 'Warning: Prop `%s` did not match. Server: %s Client: %s%s href "/docs/configuration" "/docs/configuration?docusaurus-theme=dark"', + // TODO legit hydration bugs to fix on embeds of /docs/styling-layout + // useLocation() returns window.search/hash immediately :s + '/docs/configuration?docusaurus-theme=light', + '/docs/configuration?docusaurus-theme=dark', + + // Warning because react-live not supporting React automatic JSX runtime + // See https://github.com/FormidableLabs/react-live/issues/405 + 'Your app (or one of its dependencies) is using an outdated JSX transform. Update to the modern JSX transform for faster performance', // TODO weird problem related to KaTeX fonts refusing to decode? // on /docs/markdown-features/math-equations diff --git a/examples/README.md b/examples/README.md index a74930f315..fc0fbbc6f5 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,7 +2,7 @@ These example projects are generated with the init CLI: -``` +```bash npx @docusaurus/init@latest init examples/ ` ``` diff --git a/examples/classic-typescript/README.md b/examples/classic-typescript/README.md index 0c6c2c27be..35ad92cc2a 100644 --- a/examples/classic-typescript/README.md +++ b/examples/classic-typescript/README.md @@ -4,13 +4,13 @@ This website is built using [Docusaurus](https://docusaurus.io/), a modern stati ### Installation -``` +```bash $ yarn ``` ### Local Development -``` +```bash $ yarn start ``` @@ -18,7 +18,7 @@ This command starts a local development server and opens up a browser window. Mo ### Build -``` +```bash $ yarn build ``` @@ -28,13 +28,13 @@ This command generates static content into the `build` directory and can be serv Using SSH: -``` +```bash $ USE_SSH=true yarn deploy ``` Not using SSH: -``` +```bash $ GIT_USER= yarn deploy ``` diff --git a/examples/classic-typescript/package.json b/examples/classic-typescript/package.json index e7cdbb3130..eae6620ae4 100644 --- a/examples/classic-typescript/package.json +++ b/examples/classic-typescript/package.json @@ -16,18 +16,18 @@ "dev": "docusaurus start" }, "dependencies": { - "@docusaurus/core": "3.6.0", - "@docusaurus/preset-classic": "3.6.0", + "@docusaurus/core": "3.7.0", + "@docusaurus/preset-classic": "3.7.0", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^19.0.0", + "react-dom": "^19.0.0" }, "devDependencies": { - "@docusaurus/module-type-aliases": "3.6.0", - "@docusaurus/tsconfig": "3.6.0", - "@docusaurus/types": "3.6.0", + "@docusaurus/module-type-aliases": "3.7.0", + "@docusaurus/tsconfig": "3.7.0", + "@docusaurus/types": "3.7.0", "typescript": "~5.6.2" }, "browserslist": { diff --git a/examples/classic-typescript/src/components/HomepageFeatures/index.tsx b/examples/classic-typescript/src/components/HomepageFeatures/index.tsx index 50a9e6f4c7..c2551fb9b8 100644 --- a/examples/classic-typescript/src/components/HomepageFeatures/index.tsx +++ b/examples/classic-typescript/src/components/HomepageFeatures/index.tsx @@ -1,3 +1,4 @@ +import type {ReactNode} from 'react'; import clsx from 'clsx'; import Heading from '@theme/Heading'; import styles from './styles.module.css'; @@ -5,7 +6,7 @@ import styles from './styles.module.css'; type FeatureItem = { title: string; Svg: React.ComponentType>; - description: JSX.Element; + description: ReactNode; }; const FeatureList: FeatureItem[] = [ @@ -55,7 +56,7 @@ function Feature({title, Svg, description}: FeatureItem) { ); } -export default function HomepageFeatures(): JSX.Element { +export default function HomepageFeatures(): ReactNode { return (
diff --git a/examples/classic-typescript/src/pages/index.tsx b/examples/classic-typescript/src/pages/index.tsx index 400a3e19a8..2e006d153b 100644 --- a/examples/classic-typescript/src/pages/index.tsx +++ b/examples/classic-typescript/src/pages/index.tsx @@ -1,3 +1,4 @@ +import type {ReactNode} from 'react'; import clsx from 'clsx'; import Link from '@docusaurus/Link'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; @@ -28,7 +29,7 @@ function HomepageHeader() { ); } -export default function Home(): JSX.Element { +export default function Home(): ReactNode { const {siteConfig} = useDocusaurusContext(); return ( yarn deploy ``` diff --git a/examples/classic/package.json b/examples/classic/package.json index 55e226e131..5b2695049f 100644 --- a/examples/classic/package.json +++ b/examples/classic/package.json @@ -15,17 +15,17 @@ "dev": "docusaurus start" }, "dependencies": { - "@docusaurus/core": "3.6.0", - "@docusaurus/preset-classic": "3.6.0", + "@docusaurus/core": "3.7.0", + "@docusaurus/preset-classic": "3.7.0", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^19.0.0", + "react-dom": "^19.0.0" }, "devDependencies": { - "@docusaurus/module-type-aliases": "3.6.0", - "@docusaurus/types": "3.6.0" + "@docusaurus/module-type-aliases": "3.7.0", + "@docusaurus/types": "3.7.0" }, "browserslist": { "production": [ diff --git a/examples/classic/yarn.lock b/examples/classic/yarn.lock index 04083776dc..34076fcaa6 100644 --- a/examples/classic/yarn.lock +++ b/examples/classic/yarn.lock @@ -2,279 +2,153 @@ # yarn lockfile v1 -"@algolia/autocomplete-core@1.9.3": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz#1d56482a768c33aae0868c8533049e02e8961be7" - integrity sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw== +"@algolia/autocomplete-core@1.17.7": + version "1.17.7" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.17.7.tgz#2c410baa94a47c5c5f56ed712bb4a00ebe24088b" + integrity sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q== dependencies: - "@algolia/autocomplete-plugin-algolia-insights" "1.9.3" - "@algolia/autocomplete-shared" "1.9.3" + "@algolia/autocomplete-plugin-algolia-insights" "1.17.7" + "@algolia/autocomplete-shared" "1.17.7" -"@algolia/autocomplete-plugin-algolia-insights@1.9.3": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz#9b7f8641052c8ead6d66c1623d444cbe19dde587" - integrity sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg== +"@algolia/autocomplete-plugin-algolia-insights@1.17.7": + version "1.17.7" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.7.tgz#7d2b105f84e7dd8f0370aa4c4ab3b704e6760d82" + integrity sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A== dependencies: - "@algolia/autocomplete-shared" "1.9.3" + "@algolia/autocomplete-shared" "1.17.7" -"@algolia/autocomplete-preset-algolia@1.17.6": - version "1.17.6" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.6.tgz#465b652bff5c262aad4da2488d78629cfa906be6" - integrity sha512-Cvg5JENdSCMuClwhJ1ON1/jSuojaYMiUW2KePm18IkdCzPJj/NXojaOxw58RFtQFpJgfVW8h2E8mEoDtLlMdeA== +"@algolia/autocomplete-preset-algolia@1.17.7": + version "1.17.7" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.7.tgz#c9badc0d73d62db5bf565d839d94ec0034680ae9" + integrity sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA== dependencies: - "@algolia/autocomplete-shared" "1.17.6" + "@algolia/autocomplete-shared" "1.17.7" -"@algolia/autocomplete-shared@1.17.6": - version "1.17.6" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.6.tgz#ad951632b6d477d4ba9a68a347e1702d26009d58" - integrity sha512-aq/3V9E00Tw2GC/PqgyPGXtqJUlVc17v4cn1EUhSc+O/4zd04Uwb3UmPm8KDaYQQOrkt1lwvCj2vG2wRE5IKhw== +"@algolia/autocomplete-shared@1.17.7": + version "1.17.7" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz#105e84ad9d1a31d3fb86ba20dc890eefe1a313a0" + integrity sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg== -"@algolia/autocomplete-shared@1.9.3": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz#2e22e830d36f0a9cf2c0ccd3c7f6d59435b77dfa" - integrity sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ== - -"@algolia/cache-browser-local-storage@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz#97bc6d067a9fd932b9c922faa6b7fd6e546e1348" - integrity sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww== +"@algolia/client-abtesting@5.18.0": + version "5.18.0" + resolved "https://registry.yarnpkg.com/@algolia/client-abtesting/-/client-abtesting-5.18.0.tgz#1bc368444d08b6e48ce56f1d5c935bfb9f658a98" + integrity sha512-DLIrAukjsSrdMNNDx1ZTks72o4RH/1kOn8Wx5zZm8nnqFexG+JzY4SANnCNEjnFQPJTTvC+KpgiNW/CP2lumng== dependencies: - "@algolia/cache-common" "4.24.0" + "@algolia/client-common" "5.18.0" + "@algolia/requester-browser-xhr" "5.18.0" + "@algolia/requester-fetch" "5.18.0" + "@algolia/requester-node-http" "5.18.0" -"@algolia/cache-common@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.24.0.tgz#81a8d3a82ceb75302abb9b150a52eba9960c9744" - integrity sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g== - -"@algolia/cache-in-memory@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz#ffcf8872f3a10cb85c4f4641bdffd307933a6e44" - integrity sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w== +"@algolia/client-analytics@5.18.0": + version "5.18.0" + resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-5.18.0.tgz#de0dc80011fdbaa9853adbdb836e0a80f08f53df" + integrity sha512-0VpGG2uQW+h2aejxbG8VbnMCQ9ary9/ot7OASXi6OjE0SRkYQ/+pkW+q09+IScif3pmsVVYggmlMPtAsmYWHng== dependencies: - "@algolia/cache-common" "4.24.0" + "@algolia/client-common" "5.18.0" + "@algolia/requester-browser-xhr" "5.18.0" + "@algolia/requester-fetch" "5.18.0" + "@algolia/requester-node-http" "5.18.0" -"@algolia/client-abtesting@5.12.0": - version "5.12.0" - resolved "https://registry.yarnpkg.com/@algolia/client-abtesting/-/client-abtesting-5.12.0.tgz#45175422ee85d505ff6a16d1634a739478a6ad0b" - integrity sha512-hx4eVydkm3yrFCFxmcBtSzI/ykt0cZ6sDWch+v3JTgKpD2WtosMJU3Upv1AjQ4B6COSHCOWEX3vfFxW6OoH6aA== +"@algolia/client-common@5.18.0": + version "5.18.0" + resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-5.18.0.tgz#8de3991b25ff3c9bbf5ef06c19f6a4a4fa64f328" + integrity sha512-X1WMSC+1ve2qlMsemyTF5bIjwipOT+m99Ng1Tyl36ZjQKTa54oajBKE0BrmM8LD8jGdtukAgkUhFoYOaRbMcmQ== + +"@algolia/client-insights@5.18.0": + version "5.18.0" + resolved "https://registry.yarnpkg.com/@algolia/client-insights/-/client-insights-5.18.0.tgz#2c6f158e57265fd0888f5b84fe7302d6d659c0ff" + integrity sha512-FAJRNANUOSs/FgYOJ/Njqp+YTe4TMz2GkeZtfsw1TMiA5mVNRS/nnMpxas9771aJz7KTEWvK9GwqPs0K6RMYWg== dependencies: - "@algolia/client-common" "5.12.0" - "@algolia/requester-browser-xhr" "5.12.0" - "@algolia/requester-fetch" "5.12.0" - "@algolia/requester-node-http" "5.12.0" + "@algolia/client-common" "5.18.0" + "@algolia/requester-browser-xhr" "5.18.0" + "@algolia/requester-fetch" "5.18.0" + "@algolia/requester-node-http" "5.18.0" -"@algolia/client-account@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.24.0.tgz#eba7a921d828e7c8c40a32d4add21206c7fe12f1" - integrity sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA== +"@algolia/client-personalization@5.18.0": + version "5.18.0" + resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-5.18.0.tgz#26128f6a1aef523ae32f29ef9afd18fd2f159b98" + integrity sha512-I2dc94Oiwic3SEbrRp8kvTZtYpJjGtg5y5XnqubgnA15AgX59YIY8frKsFG8SOH1n2rIhUClcuDkxYQNXJLg+w== dependencies: - "@algolia/client-common" "4.24.0" - "@algolia/client-search" "4.24.0" - "@algolia/transporter" "4.24.0" + "@algolia/client-common" "5.18.0" + "@algolia/requester-browser-xhr" "5.18.0" + "@algolia/requester-fetch" "5.18.0" + "@algolia/requester-node-http" "5.18.0" -"@algolia/client-analytics@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.24.0.tgz#9d2576c46a9093a14e668833c505ea697a1a3e30" - integrity sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg== +"@algolia/client-query-suggestions@5.18.0": + version "5.18.0" + resolved "https://registry.yarnpkg.com/@algolia/client-query-suggestions/-/client-query-suggestions-5.18.0.tgz#9911560aa2dd26984a6d3f9803f14aecc2f1d10e" + integrity sha512-x6XKIQgKFTgK/bMasXhghoEjHhmgoP61pFPb9+TaUJ32aKOGc65b12usiGJ9A84yS73UDkXS452NjyP50Knh/g== dependencies: - "@algolia/client-common" "4.24.0" - "@algolia/client-search" "4.24.0" - "@algolia/requester-common" "4.24.0" - "@algolia/transporter" "4.24.0" + "@algolia/client-common" "5.18.0" + "@algolia/requester-browser-xhr" "5.18.0" + "@algolia/requester-fetch" "5.18.0" + "@algolia/requester-node-http" "5.18.0" -"@algolia/client-analytics@5.12.0": - version "5.12.0" - resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-5.12.0.tgz#e387f4de01f4fb549b7506762003bef335be2927" - integrity sha512-EpTsSv6IW8maCfXCDIptgT7+mQJj7pImEkcNUnxR8yUKAHzTogTXv9yGm2WXOZFVuwstd2i0sImhQ1Vz8RH/hA== +"@algolia/client-search@5.18.0": + version "5.18.0" + resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-5.18.0.tgz#26a3b55b6783cf7eaa8c28b48b891ed245c7e708" + integrity sha512-qI3LcFsVgtvpsBGR7aNSJYxhsR+Zl46+958ODzg8aCxIcdxiK7QEVLMJMZAR57jGqW0Lg/vrjtuLFDMfSE53qA== dependencies: - "@algolia/client-common" "5.12.0" - "@algolia/requester-browser-xhr" "5.12.0" - "@algolia/requester-fetch" "5.12.0" - "@algolia/requester-node-http" "5.12.0" - -"@algolia/client-common@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.24.0.tgz#77c46eee42b9444a1d1c1583a83f7df4398a649d" - integrity sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA== - dependencies: - "@algolia/requester-common" "4.24.0" - "@algolia/transporter" "4.24.0" - -"@algolia/client-common@5.12.0": - version "5.12.0" - resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-5.12.0.tgz#e33b6fefb333beb56eb58ab7424fcd7ec11ac7d0" - integrity sha512-od3WmO8qxyfNhKc+K3D17tvun3IMs/xMNmxCG9MiElAkYVbPPTRUYMkRneCpmJyQI0hNx2/EA4kZgzVfQjO86Q== - -"@algolia/client-insights@5.12.0": - version "5.12.0" - resolved "https://registry.yarnpkg.com/@algolia/client-insights/-/client-insights-5.12.0.tgz#bb80c4227178b452dd93a649b9991b8140cba52d" - integrity sha512-8alajmsYUd+7vfX5lpRNdxqv3Xx9clIHLUItyQK0Z6gwGMbVEFe6YYhgDtwslMAP0y6b0WeJEIZJMLgT7VYpRw== - dependencies: - "@algolia/client-common" "5.12.0" - "@algolia/requester-browser-xhr" "5.12.0" - "@algolia/requester-fetch" "5.12.0" - "@algolia/requester-node-http" "5.12.0" - -"@algolia/client-personalization@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.24.0.tgz#8b47789fb1cb0f8efbea0f79295b7c5a3850f6ae" - integrity sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w== - dependencies: - "@algolia/client-common" "4.24.0" - "@algolia/requester-common" "4.24.0" - "@algolia/transporter" "4.24.0" - -"@algolia/client-personalization@5.12.0": - version "5.12.0" - resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-5.12.0.tgz#ad711245403754686efff6a65d6c83877e64ecfa" - integrity sha512-bUV9HtfkTBgpoVhxFrMkmVPG03ZN1Rtn51kiaEtukucdk3ggjR9Qu1YUfRSU2lFgxr9qJc8lTxwfvhjCeJRcqw== - dependencies: - "@algolia/client-common" "5.12.0" - "@algolia/requester-browser-xhr" "5.12.0" - "@algolia/requester-fetch" "5.12.0" - "@algolia/requester-node-http" "5.12.0" - -"@algolia/client-query-suggestions@5.12.0": - version "5.12.0" - resolved "https://registry.yarnpkg.com/@algolia/client-query-suggestions/-/client-query-suggestions-5.12.0.tgz#fc3bbf6d86e8989bb8487dc69ec49743fa75ceb4" - integrity sha512-Q5CszzGWfxbIDs9DJ/QJsL7bP6h+lJMg27KxieEnI9KGCu0Jt5iFA3GkREkgRZxRdzlHbZKkrIzhtHVbSHw/rg== - dependencies: - "@algolia/client-common" "5.12.0" - "@algolia/requester-browser-xhr" "5.12.0" - "@algolia/requester-fetch" "5.12.0" - "@algolia/requester-node-http" "5.12.0" - -"@algolia/client-search@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.24.0.tgz#75e6c02d33ef3e0f34afd9962c085b856fc4a55f" - integrity sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA== - dependencies: - "@algolia/client-common" "4.24.0" - "@algolia/requester-common" "4.24.0" - "@algolia/transporter" "4.24.0" - -"@algolia/client-search@5.12.0": - version "5.12.0" - resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-5.12.0.tgz#cd3eb4854664177d6e992bb2b942e2a12e4cb919" - integrity sha512-R3qzEytgVLHOGNri+bpta6NtTt7YtkvUe/QBcAmMDjW4Jk1P0eBYIPfvnzIPbINRsLxIq9fZs9uAYBgsrts4Zg== - dependencies: - "@algolia/client-common" "5.12.0" - "@algolia/requester-browser-xhr" "5.12.0" - "@algolia/requester-fetch" "5.12.0" - "@algolia/requester-node-http" "5.12.0" + "@algolia/client-common" "5.18.0" + "@algolia/requester-browser-xhr" "5.18.0" + "@algolia/requester-fetch" "5.18.0" + "@algolia/requester-node-http" "5.18.0" "@algolia/events@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@algolia/events/-/events-4.0.1.tgz#fd39e7477e7bc703d7f893b556f676c032af3950" integrity sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ== -"@algolia/ingestion@1.12.0": - version "1.12.0" - resolved "https://registry.yarnpkg.com/@algolia/ingestion/-/ingestion-1.12.0.tgz#01a297fb2a58019595e5d74e95939da033a18194" - integrity sha512-zpHo6qhR22tL8FsdSI4DvEraPDi/019HmMrCFB/TUX98yzh5ooAU7sNW0qPL1I7+S++VbBmNzJOEU9VI8tEC8A== +"@algolia/ingestion@1.18.0": + version "1.18.0" + resolved "https://registry.yarnpkg.com/@algolia/ingestion/-/ingestion-1.18.0.tgz#023e2fda366655b0e8f2cdddd98666412815429d" + integrity sha512-bGvJg7HnGGm+XWYMDruZXWgMDPVt4yCbBqq8DM6EoaMBK71SYC4WMfIdJaw+ABqttjBhe6aKNRkWf/bbvYOGyw== dependencies: - "@algolia/client-common" "5.12.0" - "@algolia/requester-browser-xhr" "5.12.0" - "@algolia/requester-fetch" "5.12.0" - "@algolia/requester-node-http" "5.12.0" + "@algolia/client-common" "5.18.0" + "@algolia/requester-browser-xhr" "5.18.0" + "@algolia/requester-fetch" "5.18.0" + "@algolia/requester-node-http" "5.18.0" -"@algolia/logger-common@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.24.0.tgz#28d439976019ec0a46ba7a1a739ef493d4ef8123" - integrity sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA== - -"@algolia/logger-console@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.24.0.tgz#c6ff486036cd90b81d07a95aaba04461da7e1c65" - integrity sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg== +"@algolia/monitoring@1.18.0": + version "1.18.0" + resolved "https://registry.yarnpkg.com/@algolia/monitoring/-/monitoring-1.18.0.tgz#e94a4c436be0d8c1e9d19c69aeff8e67d0237736" + integrity sha512-lBssglINIeGIR+8KyzH05NAgAmn1BCrm5D2T6pMtr/8kbTHvvrm1Zvcltc5dKUQEFyyx3J5+MhNc7kfi8LdjVw== dependencies: - "@algolia/logger-common" "4.24.0" + "@algolia/client-common" "5.18.0" + "@algolia/requester-browser-xhr" "5.18.0" + "@algolia/requester-fetch" "5.18.0" + "@algolia/requester-node-http" "5.18.0" -"@algolia/monitoring@1.12.0": - version "1.12.0" - resolved "https://registry.yarnpkg.com/@algolia/monitoring/-/monitoring-1.12.0.tgz#f510bfd9d09352b31ccce293d1fd84cdea59354c" - integrity sha512-i2AJZED/zf4uhxezAJUhMKoL5QoepCBp2ynOYol0N76+TSoohaMADdPnWCqOULF4RzOwrG8wWynAwBlXsAI1RQ== +"@algolia/recommend@5.18.0": + version "5.18.0" + resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-5.18.0.tgz#bd07d3057dd2030718c6707a4fe247b871f1834d" + integrity sha512-uSnkm0cdAuFwdMp4pGT5vHVQ84T6AYpTZ3I0b3k/M3wg4zXDhl3aCiY8NzokEyRLezz/kHLEEcgb/tTTobOYVw== dependencies: - "@algolia/client-common" "5.12.0" - "@algolia/requester-browser-xhr" "5.12.0" - "@algolia/requester-fetch" "5.12.0" - "@algolia/requester-node-http" "5.12.0" + "@algolia/client-common" "5.18.0" + "@algolia/requester-browser-xhr" "5.18.0" + "@algolia/requester-fetch" "5.18.0" + "@algolia/requester-node-http" "5.18.0" -"@algolia/recommend@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-4.24.0.tgz#8a3f78aea471ee0a4836b78fd2aad4e9abcaaf34" - integrity sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw== +"@algolia/requester-browser-xhr@5.18.0": + version "5.18.0" + resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.18.0.tgz#6e7e56bb687904a01c91988393f5c1969944ee3d" + integrity sha512-1XFjW0C3pV0dS/9zXbV44cKI+QM4ZIz9cpatXpsjRlq6SUCpLID3DZHsXyE6sTb8IhyPaUjk78GEJT8/3hviqg== dependencies: - "@algolia/cache-browser-local-storage" "4.24.0" - "@algolia/cache-common" "4.24.0" - "@algolia/cache-in-memory" "4.24.0" - "@algolia/client-common" "4.24.0" - "@algolia/client-search" "4.24.0" - "@algolia/logger-common" "4.24.0" - "@algolia/logger-console" "4.24.0" - "@algolia/requester-browser-xhr" "4.24.0" - "@algolia/requester-common" "4.24.0" - "@algolia/requester-node-http" "4.24.0" - "@algolia/transporter" "4.24.0" + "@algolia/client-common" "5.18.0" -"@algolia/recommend@5.12.0": - version "5.12.0" - resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-5.12.0.tgz#bc9f69c78c08ba9a3579e7fe2a0f4037b494cc55" - integrity sha512-0jmZyKvYnB/Bj5c7WKsKedOUjnr0UtXm0LVFUdQrxXfqOqvWv9n6Vpr65UjdYG4Q49kRQxhlwtal9WJYrYymXg== +"@algolia/requester-fetch@5.18.0": + version "5.18.0" + resolved "https://registry.yarnpkg.com/@algolia/requester-fetch/-/requester-fetch-5.18.0.tgz#fcccc76bd7d16fb54c56d15baa6b5f657b17ca71" + integrity sha512-0uodeNdAHz1YbzJh6C5xeQ4T6x5WGiUxUq3GOaT/R4njh5t78dq+Rb187elr7KtnjUmETVVuCvmEYaThfTHzNg== dependencies: - "@algolia/client-common" "5.12.0" - "@algolia/requester-browser-xhr" "5.12.0" - "@algolia/requester-fetch" "5.12.0" - "@algolia/requester-node-http" "5.12.0" + "@algolia/client-common" "5.18.0" -"@algolia/requester-browser-xhr@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz#313c5edab4ed73a052e75803855833b62dd19c16" - integrity sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA== +"@algolia/requester-node-http@5.18.0": + version "5.18.0" + resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-5.18.0.tgz#c5b16de53d83276067583e7b2f56b09eac938435" + integrity sha512-tZCqDrqJ2YE2I5ukCQrYN8oiF6u3JIdCxrtKq+eniuLkjkO78TKRnXrVcKZTmfFJyyDK8q47SfDcHzAA3nHi6w== dependencies: - "@algolia/requester-common" "4.24.0" - -"@algolia/requester-browser-xhr@5.12.0": - version "5.12.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.12.0.tgz#dba0072d5098a145e4724a723ea1c765b4af0cb6" - integrity sha512-KxwleraFuVoEGCoeW6Y1RAEbgBMS7SavqeyzWdtkJc6mXeCOJXn1iZitb8Tyn2FcpMNUKlSm0adrUTt7G47+Ow== - dependencies: - "@algolia/client-common" "5.12.0" - -"@algolia/requester-common@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.24.0.tgz#1c60c198031f48fcdb9e34c4057a3ea987b9a436" - integrity sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA== - -"@algolia/requester-fetch@5.12.0": - version "5.12.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-fetch/-/requester-fetch-5.12.0.tgz#4db2772b9b0699fdfadbcd7b87e0608a4acf8363" - integrity sha512-FuDZXUGU1pAg2HCnrt8+q1VGHKChV/LhvjvZlLOT7e56GJie6p+EuLu4/hMKPOVuQQ8XXtrTHKIU3Lw+7O5/bQ== - dependencies: - "@algolia/client-common" "5.12.0" - -"@algolia/requester-node-http@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz#4461593714031d02aa7da221c49df675212f482f" - integrity sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw== - dependencies: - "@algolia/requester-common" "4.24.0" - -"@algolia/requester-node-http@5.12.0": - version "5.12.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-5.12.0.tgz#6c6bb47df33351b819790f26346632196c97a3c7" - integrity sha512-ncDDY7CxZhMs6LIoPl+vHFQceIBhYPY5EfuGF1V7beO0U38xfsCYEyutEFB2kRzf4D9Gqppn3iWX71sNtrKcuw== - dependencies: - "@algolia/client-common" "5.12.0" - -"@algolia/transporter@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.24.0.tgz#226bb1f8af62430374c1972b2e5c8580ab275102" - integrity sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA== - dependencies: - "@algolia/cache-common" "4.24.0" - "@algolia/logger-common" "4.24.0" - "@algolia/requester-common" "4.24.0" + "@algolia/client-common" "5.18.0" "@ampproject/remapping@^2.2.0": version "2.3.0" @@ -284,7 +158,7 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0", "@babel/code-frame@^7.8.3": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0", "@babel/code-frame@^7.26.2", "@babel/code-frame@^7.8.3": version "7.26.2" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== @@ -294,9 +168,9 @@ picocolors "^1.0.0" "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.9", "@babel/compat-data@^7.26.0": - version "7.26.2" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.2.tgz#278b6b13664557de95b8f35b90d96785850bb56e" - integrity sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg== + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.3.tgz#99488264a56b2aded63983abd6a417f03b92ed02" + integrity sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g== "@babel/core@^7.21.3", "@babel/core@^7.25.9": version "7.26.0" @@ -319,13 +193,13 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.25.9", "@babel/generator@^7.26.0": - version "7.26.2" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.2.tgz#87b75813bec87916210e5e01939a4c823d6bb74f" - integrity sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw== +"@babel/generator@^7.25.9", "@babel/generator@^7.26.0", "@babel/generator@^7.26.3": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.3.tgz#ab8d4360544a425c90c248df7059881f4b2ce019" + integrity sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ== dependencies: - "@babel/parser" "^7.26.2" - "@babel/types" "^7.26.0" + "@babel/parser" "^7.26.3" + "@babel/types" "^7.26.3" "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" jsesc "^3.0.2" @@ -337,14 +211,6 @@ dependencies: "@babel/types" "^7.25.9" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz#f41752fe772a578e67286e6779a68a5a92de1ee9" - integrity sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g== - dependencies: - "@babel/traverse" "^7.25.9" - "@babel/types" "^7.25.9" - "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz#55af025ce365be3cdc0c1c1e56c6af617ce88875" @@ -370,18 +236,18 @@ semver "^6.3.1" "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz#3e8999db94728ad2b2458d7a470e7770b7764e26" - integrity sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw== + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz#5169756ecbe1d95f7866b90bb555b022595302a0" + integrity sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong== dependencies: "@babel/helper-annotate-as-pure" "^7.25.9" - regexpu-core "^6.1.1" + regexpu-core "^6.2.0" semver "^6.3.1" -"@babel/helper-define-polyfill-provider@^0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz#18594f789c3594acb24cfdb4a7f7b7d2e8bd912d" - integrity sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ== +"@babel/helper-define-polyfill-provider@^0.6.2", "@babel/helper-define-polyfill-provider@^0.6.3": + version "0.6.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz#f4f2792fae2ef382074bc2d713522cf24e6ddb21" + integrity sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg== dependencies: "@babel/helper-compilation-targets" "^7.22.6" "@babel/helper-plugin-utils" "^7.22.5" @@ -444,14 +310,6 @@ "@babel/helper-optimise-call-expression" "^7.25.9" "@babel/traverse" "^7.25.9" -"@babel/helper-simple-access@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz#6d51783299884a2c74618d6ef0f86820ec2e7739" - integrity sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q== - dependencies: - "@babel/traverse" "^7.25.9" - "@babel/types" "^7.25.9" - "@babel/helper-skip-transparent-expression-wrappers@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz#0b2e1b62d560d6b1954893fd2b705dc17c91f0c9" @@ -492,12 +350,12 @@ "@babel/template" "^7.25.9" "@babel/types" "^7.26.0" -"@babel/parser@^7.25.9", "@babel/parser@^7.26.0", "@babel/parser@^7.26.2": - version "7.26.2" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.2.tgz#fd7b6f487cfea09889557ef5d4eeb9ff9a5abd11" - integrity sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ== +"@babel/parser@^7.25.9", "@babel/parser@^7.26.0", "@babel/parser@^7.26.3": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.3.tgz#8c51c5db6ddf08134af1ddbacf16aaab48bac234" + integrity sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA== dependencies: - "@babel/types" "^7.26.0" + "@babel/types" "^7.26.3" "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.9": version "7.25.9" @@ -699,11 +557,10 @@ "@babel/helper-plugin-utils" "^7.25.9" "@babel/plugin-transform-exponentiation-operator@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz#ece47b70d236c1d99c263a1e22b62dc20a4c8b0f" - integrity sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA== + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz#e29f01b6de302c7c2c794277a48f04a9ca7f03bc" + integrity sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.25.9" "@babel/helper-plugin-utils" "^7.25.9" "@babel/plugin-transform-export-namespace-from@^7.25.9": @@ -767,13 +624,12 @@ "@babel/helper-plugin-utils" "^7.25.9" "@babel/plugin-transform-modules-commonjs@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz#d165c8c569a080baf5467bda88df6425fc060686" - integrity sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg== + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz#8f011d44b20d02c3de44d8850d971d8497f981fb" + integrity sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ== dependencies: - "@babel/helper-module-transforms" "^7.25.9" + "@babel/helper-module-transforms" "^7.26.0" "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-simple-access" "^7.25.9" "@babel/plugin-transform-modules-systemjs@^7.25.9": version "7.25.9" @@ -997,9 +853,9 @@ "@babel/helper-plugin-utils" "^7.25.9" "@babel/plugin-transform-typescript@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.9.tgz#69267905c2b33c2ac6d8fe765e9dc2ddc9df3849" - integrity sha512-7PbZQZP50tzv2KGGnhh82GSyMB01yKY9scIjf1a+GfZCtInOWqUH5+1EBU4t9fyR5Oykkkc9vFTs4OHrhHXljQ== + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.3.tgz#3d6add9c78735623317387ee26d5ada540eee3fd" + integrity sha512-6+5hpdr6mETwSKjmJUdYw0EIkATiQhnELWlE3kJFBwSg/BGIVwVaVbX+gOXBCdc7Ln1RXZxyWGecIXhUfnl7oA== dependencies: "@babel/helper-annotate-as-pure" "^7.25.9" "@babel/helper-create-class-features-plugin" "^7.25.9" @@ -1123,9 +979,9 @@ esutils "^2.0.2" "@babel/preset-react@^7.18.6", "@babel/preset-react@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.25.9.tgz#5f473035dc2094bcfdbc7392d0766bd42dce173e" - integrity sha512-D3to0uSPiWE7rBrdIICCd0tJSIGpLaaGptna2+w7Pft5xMqLpA1sz99DK5TZ1TjGbdQ/VI1eCSZ06dv3lT4JOw== + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.26.3.tgz#7c5e028d623b4683c1f83a0bd4713b9100560caa" + integrity sha512-Nl03d6T9ky516DGK2YMxrTqvnpUW63TnJMOMonj+Zae0JiPC5BC9xPMSL6L8fiSpA5vP88qfygavVQvnLp+6Cw== dependencies: "@babel/helper-plugin-utils" "^7.25.9" "@babel/helper-validator-option" "^7.25.9" @@ -1170,22 +1026,22 @@ "@babel/types" "^7.25.9" "@babel/traverse@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84" - integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw== + version "7.26.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.26.4.tgz#ac3a2a84b908dde6d463c3bfa2c5fdc1653574bd" + integrity sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w== dependencies: - "@babel/code-frame" "^7.25.9" - "@babel/generator" "^7.25.9" - "@babel/parser" "^7.25.9" + "@babel/code-frame" "^7.26.2" + "@babel/generator" "^7.26.3" + "@babel/parser" "^7.26.3" "@babel/template" "^7.25.9" - "@babel/types" "^7.25.9" + "@babel/types" "^7.26.3" debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.21.3", "@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.4.4": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.0.tgz#deabd08d6b753bc8e0f198f8709fb575e31774ff" - integrity sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA== +"@babel/types@^7.21.3", "@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.26.3", "@babel/types@^7.4.4": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.3.tgz#37e79830f04c2b5687acc77db97fbc75fb81f3c0" + integrity sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA== dependencies: "@babel/helper-string-parser" "^7.25.9" "@babel/helper-validator-identifier" "^7.25.9" @@ -1195,30 +1051,352 @@ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== +"@csstools/cascade-layer-name-parser@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.4.tgz#64d128529397aa1e1c986f685713363b262b81b1" + integrity sha512-7DFHlPuIxviKYZrOiwVU/PiHLm3lLUR23OMuEEtfEOQTOp9hzQ2JjdY6X5H18RVuUPJqSCI+qNnD5iOLMVE0bA== + +"@csstools/color-helpers@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@csstools/color-helpers/-/color-helpers-5.0.1.tgz#829f1c76f5800b79c51c709e2f36821b728e0e10" + integrity sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA== + +"@csstools/css-calc@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@csstools/css-calc/-/css-calc-2.1.1.tgz#a7dbc66627f5cf458d42aed14bda0d3860562383" + integrity sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag== + +"@csstools/css-color-parser@^3.0.7": + version "3.0.7" + resolved "https://registry.yarnpkg.com/@csstools/css-color-parser/-/css-color-parser-3.0.7.tgz#442d61d58e54ad258d52c309a787fceb33906484" + integrity sha512-nkMp2mTICw32uE5NN+EsJ4f5N+IGFeCFu4bGpiKgb2Pq/7J/MpyLBeQ5ry4KKtRFZaYs6sTmcMYrSRIyj5DFKA== + dependencies: + "@csstools/color-helpers" "^5.0.1" + "@csstools/css-calc" "^2.1.1" + +"@csstools/css-parser-algorithms@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz#74426e93bd1c4dcab3e441f5cc7ba4fb35d94356" + integrity sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A== + +"@csstools/css-tokenizer@^3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz#a5502c8539265fecbd873c1e395a890339f119c2" + integrity sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw== + +"@csstools/media-query-list-parser@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.2.tgz#e80e17eba1693fceafb8d6f2cfc68c0e7a9ab78a" + integrity sha512-EUos465uvVvMJehckATTlNqGj4UJWkTmdWuDMjqvSUkjGpmOyFZBVwb4knxCm/k2GMTXY+c/5RkdndzFYWeX5A== + +"@csstools/postcss-cascade-layers@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.1.tgz#9640313e64b5e39133de7e38a5aa7f40dc259597" + integrity sha512-XOfhI7GShVcKiKwmPAnWSqd2tBR0uxt+runAxttbSp/LY2U16yAVPmAf7e9q4JJ0d+xMNmpwNDLBXnmRCl3HMQ== + dependencies: + "@csstools/selector-specificity" "^5.0.0" + postcss-selector-parser "^7.0.0" + +"@csstools/postcss-color-function@^4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-4.0.7.tgz#d31d2044d8a4f8b3154ac54ac77014879eae9f56" + integrity sha512-aDHYmhNIHR6iLw4ElWhf+tRqqaXwKnMl0YsQ/X105Zc4dQwe6yJpMrTN6BwOoESrkDjOYMOfORviSSLeDTJkdQ== + dependencies: + "@csstools/css-color-parser" "^3.0.7" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-color-mix-function@^3.0.7": + version "3.0.7" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.7.tgz#39735bbc84dc173061e4c2842ec656bb9bc6ed2e" + integrity sha512-e68Nev4CxZYCLcrfWhHH4u/N1YocOfTmw67/kVX5Rb7rnguqqLyxPjhHWjSBX8o4bmyuukmNf3wrUSU3//kT7g== + dependencies: + "@csstools/css-color-parser" "^3.0.7" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-content-alt-text@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.4.tgz#76f4687fb15ed45bc1139bb71e5775779762897a" + integrity sha512-YItlZUOuZJCBlRaCf8Aucc1lgN41qYGALMly0qQllrxYJhiyzlI6RxOTMUvtWk+KhS8GphMDsDhKQ7KTPfEMSw== + dependencies: + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-exponential-functions@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.6.tgz#dcee86d22102576b13d8bea059125fbcf98e83cc" + integrity sha512-IgJA5DQsQLu/upA3HcdvC6xEMR051ufebBTIXZ5E9/9iiaA7juXWz1ceYj814lnDYP/7eWjZnw0grRJlX4eI6g== + dependencies: + "@csstools/css-calc" "^2.1.1" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + +"@csstools/postcss-font-format-keywords@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-4.0.0.tgz#6730836eb0153ff4f3840416cc2322f129c086e6" + integrity sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw== + dependencies: + "@csstools/utilities" "^2.0.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-gamut-mapping@^2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.7.tgz#8aaa4b6ffb6e2187379a83d253607f988533be25" + integrity sha512-gzFEZPoOkY0HqGdyeBXR3JP218Owr683u7KOZazTK7tQZBE8s2yhg06W1tshOqk7R7SWvw9gkw2TQogKpIW8Xw== + dependencies: + "@csstools/css-color-parser" "^3.0.7" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + +"@csstools/postcss-gradients-interpolation-method@^5.0.7": + version "5.0.7" + resolved "https://registry.yarnpkg.com/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.7.tgz#57e19d25e98aa028b98e22ef392ea24c3e61c568" + integrity sha512-WgEyBeg6glUeTdS2XT7qeTFBthTJuXlS9GFro/DVomj7W7WMTamAwpoP4oQCq/0Ki2gvfRYFi/uZtmRE14/DFA== + dependencies: + "@csstools/css-color-parser" "^3.0.7" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-hwb-function@^4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.7.tgz#d09528098c4b99c49c76de686a4ae35585acc691" + integrity sha512-LKYqjO+wGwDCfNIEllessCBWfR4MS/sS1WXO+j00KKyOjm7jDW2L6jzUmqASEiv/kkJO39GcoIOvTTfB3yeBUA== + dependencies: + "@csstools/css-color-parser" "^3.0.7" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-ic-unit@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.0.tgz#b60ec06500717c337447c39ae7fe7952eeb9d48f" + integrity sha512-9QT5TDGgx7wD3EEMN3BSUG6ckb6Eh5gSPT5kZoVtUuAonfPmLDJyPhqR4ntPpMYhUKAMVKAg3I/AgzqHMSeLhA== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/utilities" "^2.0.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-initial@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-initial/-/postcss-initial-2.0.0.tgz#a86f5fc59ab9f16f1422dade4c58bd941af5df22" + integrity sha512-dv2lNUKR+JV+OOhZm9paWzYBXOCi+rJPqJ2cJuhh9xd8USVrd0cBEPczla81HNOyThMQWeCcdln3gZkQV2kYxA== + +"@csstools/postcss-is-pseudo-class@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.1.tgz#12041448fedf01090dd4626022c28b7f7623f58e" + integrity sha512-JLp3POui4S1auhDR0n8wHd/zTOWmMsmK3nQd3hhL6FhWPaox5W7j1se6zXOG/aP07wV2ww0lxbKYGwbBszOtfQ== + dependencies: + "@csstools/selector-specificity" "^5.0.0" + postcss-selector-parser "^7.0.0" + +"@csstools/postcss-light-dark-function@^2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.7.tgz#807c170cd28eebb0c00e64dfc6ab0bf418f19209" + integrity sha512-ZZ0rwlanYKOHekyIPaU+sVm3BEHCe+Ha0/px+bmHe62n0Uc1lL34vbwrLYn6ote8PHlsqzKeTQdIejQCJ05tfw== + dependencies: + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-logical-float-and-clear@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-3.0.0.tgz#62617564182cf86ab5d4e7485433ad91e4c58571" + integrity sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ== + +"@csstools/postcss-logical-overflow@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-overflow/-/postcss-logical-overflow-2.0.0.tgz#c6de7c5f04e3d4233731a847f6c62819bcbcfa1d" + integrity sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA== + +"@csstools/postcss-logical-overscroll-behavior@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-overscroll-behavior/-/postcss-logical-overscroll-behavior-2.0.0.tgz#43c03eaecdf34055ef53bfab691db6dc97a53d37" + integrity sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w== + +"@csstools/postcss-logical-resize@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-resize/-/postcss-logical-resize-3.0.0.tgz#4df0eeb1a61d7bd85395e56a5cce350b5dbfdca6" + integrity sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-logical-viewport-units@^3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-3.0.3.tgz#f6cc63520ca2a6eb76b9cd946070c38dda66d733" + integrity sha512-OC1IlG/yoGJdi0Y+7duz/kU/beCwO+Gua01sD6GtOtLi7ByQUpcIqs7UE/xuRPay4cHgOMatWdnDdsIDjnWpPw== + dependencies: + "@csstools/css-tokenizer" "^3.0.3" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-media-minmax@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@csstools/postcss-media-minmax/-/postcss-media-minmax-2.0.6.tgz#427921c0f08033203810af16dfed0baedc538eab" + integrity sha512-J1+4Fr2W3pLZsfxkFazK+9kr96LhEYqoeBszLmFjb6AjYs+g9oDAw3J5oQignLKk3rC9XHW+ebPTZ9FaW5u5pg== + dependencies: + "@csstools/css-calc" "^2.1.1" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + "@csstools/media-query-list-parser" "^4.0.2" + +"@csstools/postcss-media-queries-aspect-ratio-number-values@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-3.0.4.tgz#d71102172c74baf3f892fac88cf1ea46a961600d" + integrity sha512-AnGjVslHMm5xw9keusQYvjVWvuS7KWK+OJagaG0+m9QnIjZsrysD2kJP/tr/UJIyYtMCtu8OkUd+Rajb4DqtIQ== + dependencies: + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + "@csstools/media-query-list-parser" "^4.0.2" + +"@csstools/postcss-nested-calc@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-nested-calc/-/postcss-nested-calc-4.0.0.tgz#754e10edc6958d664c11cde917f44ba144141c62" + integrity sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A== + dependencies: + "@csstools/utilities" "^2.0.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-normalize-display-values@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.0.tgz#ecdde2daf4e192e5da0c6fd933b6d8aff32f2a36" + integrity sha512-HlEoG0IDRoHXzXnkV4in47dzsxdsjdz6+j7MLjaACABX2NfvjFS6XVAnpaDyGesz9gK2SC7MbNwdCHusObKJ9Q== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-oklab-function@^4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.7.tgz#33b3322dfb27b0b5eb83a7ad36e67f08bc4e66cd" + integrity sha512-I6WFQIbEKG2IO3vhaMGZDkucbCaUSXMxvHNzDdnfsTCF5tc0UlV3Oe2AhamatQoKFjBi75dSEMrgWq3+RegsOQ== + dependencies: + "@csstools/css-color-parser" "^3.0.7" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-progressive-custom-properties@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.0.0.tgz#ecdb85bcdb1852d73970a214a376684a91f82bdc" + integrity sha512-XQPtROaQjomnvLUSy/bALTR5VCtTVUFwYs1SblvYgLSeTo2a/bMNwUwo2piXw5rTv/FEYiy5yPSXBqg9OKUx7Q== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-random-function@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-random-function/-/postcss-random-function-1.0.2.tgz#699702820f19bb6b9632966ff44d8957db6889d2" + integrity sha512-vBCT6JvgdEkvRc91NFoNrLjgGtkLWt47GKT6E2UDn3nd8ZkMBiziQ1Md1OiKoSsgzxsSnGKG3RVdhlbdZEkHjA== + dependencies: + "@csstools/css-calc" "^2.1.1" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + +"@csstools/postcss-relative-color-syntax@^3.0.7": + version "3.0.7" + resolved "https://registry.yarnpkg.com/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.7.tgz#862f8c6a2bbbab1a46aff8265b6a095fd267a3a6" + integrity sha512-apbT31vsJVd18MabfPOnE977xgct5B1I+Jpf+Munw3n6kKb1MMuUmGGH+PT9Hm/fFs6fe61Q/EWnkrb4bNoNQw== + dependencies: + "@csstools/css-color-parser" "^3.0.7" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-scope-pseudo-class@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-4.0.1.tgz#9fe60e9d6d91d58fb5fc6c768a40f6e47e89a235" + integrity sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q== + dependencies: + postcss-selector-parser "^7.0.0" + +"@csstools/postcss-sign-functions@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-sign-functions/-/postcss-sign-functions-1.1.1.tgz#eb8e4a5ac637982aeb9264cb99f85817612ad3e8" + integrity sha512-MslYkZCeMQDxetNkfmmQYgKCy4c+w9pPDfgOBCJOo/RI1RveEUdZQYtOfrC6cIZB7sD7/PHr2VGOcMXlZawrnA== + dependencies: + "@csstools/css-calc" "^2.1.1" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + +"@csstools/postcss-stepped-value-functions@^4.0.6": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-4.0.6.tgz#ee88c6122daf58a1b8641f462e8e33427c60b1f1" + integrity sha512-/dwlO9w8vfKgiADxpxUbZOWlL5zKoRIsCymYoh1IPuBsXODKanKnfuZRr32DEqT0//3Av1VjfNZU9yhxtEfIeA== + dependencies: + "@csstools/css-calc" "^2.1.1" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + +"@csstools/postcss-text-decoration-shorthand@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.1.tgz#251fab0939d50c6fd73bb2b830b2574188efa087" + integrity sha512-xPZIikbx6jyzWvhms27uugIc0I4ykH4keRvoa3rxX5K7lEhkbd54rjj/dv60qOCTisoS+3bmwJTeyV1VNBrXaw== + dependencies: + "@csstools/color-helpers" "^5.0.1" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-trigonometric-functions@^4.0.6": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-4.0.6.tgz#fc5c5f4c9bd0fd796b58b9a14d5d663be76d19fa" + integrity sha512-c4Y1D2Why/PeccaSouXnTt6WcNHJkoJRidV2VW9s5gJ97cNxnLgQ4Qj8qOqkIR9VmTQKJyNcbF4hy79ZQnWD7A== + dependencies: + "@csstools/css-calc" "^2.1.1" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + +"@csstools/postcss-unset-value@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-unset-value/-/postcss-unset-value-4.0.0.tgz#7caa981a34196d06a737754864baf77d64de4bba" + integrity sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA== + +"@csstools/selector-resolve-nested@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.0.0.tgz#704a9b637975680e025e069a4c58b3beb3e2752a" + integrity sha512-ZoK24Yku6VJU1gS79a5PFmC8yn3wIapiKmPgun0hZgEI5AOqgH2kiPRsPz1qkGv4HL+wuDLH83yQyk6inMYrJQ== + +"@csstools/selector-specificity@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz#037817b574262134cabd68fc4ec1a454f168407b" + integrity sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw== + +"@csstools/utilities@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@csstools/utilities/-/utilities-2.0.0.tgz#f7ff0fee38c9ffb5646d47b6906e0bc8868bde60" + integrity sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ== + "@discoveryjs/json-ext@0.5.7": version "0.5.7" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@docsearch/css@3.6.3": - version "3.6.3" - resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.6.3.tgz#d787cc9d27a7e67305fa47d668656eb2e64c4526" - integrity sha512-3uvbg8E7rhqE1C4oBAK3tGlS2qfhi9zpfZgH/yjDPF73vd9B41urVIKujF4rczcF4E3qs34SedhehiDJ4UdNBA== +"@docsearch/css@3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.8.2.tgz#7973ceb6892c30f154ba254cd05c562257a44977" + integrity sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ== -"@docsearch/react@^3.5.2": - version "3.6.3" - resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.6.3.tgz#326a0811306060bfb481df3cd0db51adaa9f737c" - integrity sha512-2munr4uBuZq1PG+Ge+F+ldIdxb3Wi8OmEIv2tQQb4RvEvvph+xtQkxwHzVIEnt5s+HecwucuXwB+3JhcZboFLg== +"@docsearch/react@^3.8.1": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.8.2.tgz#7b11d39b61c976c0aa9fbde66e6b73b30f3acd42" + integrity sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg== dependencies: - "@algolia/autocomplete-core" "1.9.3" - "@algolia/autocomplete-preset-algolia" "1.17.6" - "@docsearch/css" "3.6.3" - algoliasearch "^5.11.0" + "@algolia/autocomplete-core" "1.17.7" + "@algolia/autocomplete-preset-algolia" "1.17.7" + "@docsearch/css" "3.8.2" + algoliasearch "^5.14.2" -"@docusaurus/babel@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/babel/-/babel-3.6.0.tgz#735a003207925bd782dd08ffa5d8b3503c1f8d72" - integrity sha512-7CsoQFiadoq7AHSUIQNkI/lGfg9AQ2ZBzsf9BqfZGXkHwWDy6twuohEaG0PgQv1npSRSAB2dioVxhRSErnqKNA== +"@docusaurus/babel@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/babel/-/babel-3.7.0.tgz#770dd5da525a9d6a2fee7d3212ec62040327f776" + integrity sha512-0H5uoJLm14S/oKV3Keihxvh8RV+vrid+6Gv+2qhuzbqHanawga8tYnsdpjEyt36ucJjqlby2/Md2ObWjA02UXQ== dependencies: "@babel/core" "^7.25.9" "@babel/generator" "^7.25.9" @@ -1230,24 +1408,23 @@ "@babel/runtime" "^7.25.9" "@babel/runtime-corejs3" "^7.25.9" "@babel/traverse" "^7.25.9" - "@docusaurus/logger" "3.6.0" - "@docusaurus/utils" "3.6.0" + "@docusaurus/logger" "3.7.0" + "@docusaurus/utils" "3.7.0" babel-plugin-dynamic-import-node "^2.3.3" fs-extra "^11.1.1" tslib "^2.6.0" -"@docusaurus/bundler@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/bundler/-/bundler-3.6.0.tgz#bdd060ba4d009211348e4e973a3bf4861cf0996b" - integrity sha512-o5T9HXkPKH0OQAifTxEXaebcO8kaz3tU1+wlIShZ2DKJHlsyWX3N4rToWBHroWnV/ZCT2XN3kLRzXASqrnb9Tw== +"@docusaurus/bundler@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/bundler/-/bundler-3.7.0.tgz#d8e7867b3b2c43a1e320ed429f8dfe873c38506d" + integrity sha512-CUUT9VlSGukrCU5ctZucykvgCISivct+cby28wJwCC/fkQFgAHRp/GKv2tx38ZmXb7nacrKzFTcp++f9txUYGg== dependencies: "@babel/core" "^7.25.9" - "@docusaurus/babel" "3.6.0" - "@docusaurus/cssnano-preset" "3.6.0" - "@docusaurus/logger" "3.6.0" - "@docusaurus/types" "3.6.0" - "@docusaurus/utils" "3.6.0" - autoprefixer "^10.4.14" + "@docusaurus/babel" "3.7.0" + "@docusaurus/cssnano-preset" "3.7.0" + "@docusaurus/logger" "3.7.0" + "@docusaurus/types" "3.7.0" + "@docusaurus/utils" "3.7.0" babel-loader "^9.2.1" clean-css "^5.3.2" copy-webpack-plugin "^11.0.0" @@ -1260,6 +1437,7 @@ null-loader "^4.0.1" postcss "^8.4.26" postcss-loader "^7.3.3" + postcss-preset-env "^10.1.0" react-dev-utils "^12.0.1" terser-webpack-plugin "^5.3.9" tslib "^2.6.0" @@ -1267,18 +1445,18 @@ webpack "^5.95.0" webpackbar "^6.0.1" -"@docusaurus/core@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-3.6.0.tgz#b23fc7e253a49cc3e5ac9e091354f497cc0b101b" - integrity sha512-lvRgMoKJJSRDt9+HhAqFcICV4kp/mw1cJJrLxIw4Q2XZnFGM1XUuwcbuaqWmGog+NcOLZaPCcCtZbn60EMCtjQ== +"@docusaurus/core@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-3.7.0.tgz#e871586d099093723dfe6de81c1ce610aeb20292" + integrity sha512-b0fUmaL+JbzDIQaamzpAFpTviiaU4cX3Qz8cuo14+HGBCwa0evEK0UYCBFY3n4cLzL8Op1BueeroUD2LYAIHbQ== dependencies: - "@docusaurus/babel" "3.6.0" - "@docusaurus/bundler" "3.6.0" - "@docusaurus/logger" "3.6.0" - "@docusaurus/mdx-loader" "3.6.0" - "@docusaurus/utils" "3.6.0" - "@docusaurus/utils-common" "3.6.0" - "@docusaurus/utils-validation" "3.6.0" + "@docusaurus/babel" "3.7.0" + "@docusaurus/bundler" "3.7.0" + "@docusaurus/logger" "3.7.0" + "@docusaurus/mdx-loader" "3.7.0" + "@docusaurus/utils" "3.7.0" + "@docusaurus/utils-common" "3.7.0" + "@docusaurus/utils-validation" "3.7.0" boxen "^6.2.1" chalk "^4.1.2" chokidar "^3.5.3" @@ -1299,13 +1477,12 @@ p-map "^4.0.0" prompts "^2.4.2" react-dev-utils "^12.0.1" - react-helmet-async "^1.3.0" + react-helmet-async "npm:@slorber/react-helmet-async@1.3.0" react-loadable "npm:@docusaurus/react-loadable@6.0.0" react-loadable-ssr-addon-v5-slorber "^1.0.1" react-router "^5.3.4" react-router-config "^5.1.1" react-router-dom "^5.3.4" - rtl-detect "^1.0.4" semver "^7.5.4" serve-handler "^6.1.6" shelljs "^0.8.5" @@ -1316,32 +1493,32 @@ webpack-dev-server "^4.15.2" webpack-merge "^6.0.1" -"@docusaurus/cssnano-preset@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-3.6.0.tgz#02378e53e9568ed5fc8871d4fc158ea96fd7421c" - integrity sha512-h3jlOXqqzNSoU+C4CZLNpFtD+v2xr1UBf4idZpwMgqid9r6lb5GS7tWKnQnauio6OipacbHbDXEX3JyT1PlDkg== +"@docusaurus/cssnano-preset@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-3.7.0.tgz#8fe8f2c3acbd32384b69e14983b9a63c98cae34e" + integrity sha512-X9GYgruZBSOozg4w4dzv9uOz8oK/EpPVQXkp0MM6Tsgp/nRIU9hJzJ0Pxg1aRa3xCeEQTOimZHcocQFlLwYajQ== dependencies: cssnano-preset-advanced "^6.1.2" postcss "^8.4.38" postcss-sort-media-queries "^5.2.0" tslib "^2.6.0" -"@docusaurus/logger@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-3.6.0.tgz#c7349c2636087f55f573a60a3c7f69b87d59974d" - integrity sha512-BcQhoXilXW0607cH/kO6P5Gt5KxCGfoJ+QDKNf3yO2S09/RsITlW+0QljXPbI3DklTrHrhRDmgGk1yX4nUhWTA== +"@docusaurus/logger@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-3.7.0.tgz#07ecc2f460c4d2382df4991f9ce4e348e90af04c" + integrity sha512-z7g62X7bYxCYmeNNuO9jmzxLQG95q9QxINCwpboVcNff3SJiHJbGrarxxOVMVmAh1MsrSfxWkVGv4P41ktnFsA== dependencies: chalk "^4.1.2" tslib "^2.6.0" -"@docusaurus/mdx-loader@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-3.6.0.tgz#f8ba7af9d59473a7182f6a9307e0432f8dce905b" - integrity sha512-GhRzL1Af/AdSSrGesSPOU/iP/aXadTGmVKuysCxZDrQR2RtBtubQZ9aw+KvdFVV7R4K/CsbgD6J5oqrXlEPk3Q== +"@docusaurus/mdx-loader@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-3.7.0.tgz#5890c6e7a5b68cb1d066264ac5290cdcd59d4ecc" + integrity sha512-OFBG6oMjZzc78/U3WNPSHs2W9ZJ723ewAcvVJaqS0VgyeUfmzUV8f1sv+iUHA0DtwiR5T5FjOxj6nzEE8LY6VA== dependencies: - "@docusaurus/logger" "3.6.0" - "@docusaurus/utils" "3.6.0" - "@docusaurus/utils-validation" "3.6.0" + "@docusaurus/logger" "3.7.0" + "@docusaurus/utils" "3.7.0" + "@docusaurus/utils-validation" "3.7.0" "@mdx-js/mdx" "^3.0.0" "@slorber/remark-comment" "^1.0.0" escape-html "^1.0.3" @@ -1364,32 +1541,32 @@ vfile "^6.0.1" webpack "^5.88.1" -"@docusaurus/module-type-aliases@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/module-type-aliases/-/module-type-aliases-3.6.0.tgz#44083c34a53db1dde06364b4e7f2d144fa2d5394" - integrity sha512-szTrIN/6/fuk0xkf3XbRfdTFJzRQ8d1s3sQj5++58wltrT7v3yn1149oc9ryYjMpRcbsarGloQwMu7ofPe4XPg== +"@docusaurus/module-type-aliases@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/module-type-aliases/-/module-type-aliases-3.7.0.tgz#15c0745b829c6966c5b3b2c2527c72b54830b0e5" + integrity sha512-g7WdPqDNaqA60CmBrr0cORTrsOit77hbsTj7xE2l71YhBn79sxdm7WMK7wfhcaafkbpIh7jv5ef5TOpf1Xv9Lg== dependencies: - "@docusaurus/types" "3.6.0" + "@docusaurus/types" "3.7.0" "@types/history" "^4.7.11" "@types/react" "*" "@types/react-router-config" "*" "@types/react-router-dom" "*" - react-helmet-async "*" + react-helmet-async "npm:@slorber/react-helmet-async@*" react-loadable "npm:@docusaurus/react-loadable@6.0.0" -"@docusaurus/plugin-content-blog@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.6.0.tgz#9128175b4c3ce885d9090183d74c60813844ea8d" - integrity sha512-o4aT1/E0Ldpzs/hQff5uyoSriAhS/yqBhqSn+fvSw465AaqRsva6O7CZSYleuBq6x2bewyE3QJq2PcTiHhAd8g== +"@docusaurus/plugin-content-blog@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.7.0.tgz#7bd69de87a1f3adb652e1473ef5b7ccc9468f47e" + integrity sha512-EFLgEz6tGHYWdPU0rK8tSscZwx+AsyuBW/r+tNig2kbccHYGUJmZtYN38GjAa3Fda4NU+6wqUO5kTXQSRBQD3g== dependencies: - "@docusaurus/core" "3.6.0" - "@docusaurus/logger" "3.6.0" - "@docusaurus/mdx-loader" "3.6.0" - "@docusaurus/theme-common" "3.6.0" - "@docusaurus/types" "3.6.0" - "@docusaurus/utils" "3.6.0" - "@docusaurus/utils-common" "3.6.0" - "@docusaurus/utils-validation" "3.6.0" + "@docusaurus/core" "3.7.0" + "@docusaurus/logger" "3.7.0" + "@docusaurus/mdx-loader" "3.7.0" + "@docusaurus/theme-common" "3.7.0" + "@docusaurus/types" "3.7.0" + "@docusaurus/utils" "3.7.0" + "@docusaurus/utils-common" "3.7.0" + "@docusaurus/utils-validation" "3.7.0" cheerio "1.0.0-rc.12" feed "^4.2.2" fs-extra "^11.1.1" @@ -1401,20 +1578,20 @@ utility-types "^3.10.0" webpack "^5.88.1" -"@docusaurus/plugin-content-docs@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.6.0.tgz#15cae4bf81da0b0ddce09d53b10b7209116ea9c2" - integrity sha512-c5gZOxocJKO/Zev2MEZInli+b+VNswDGuKHE6QtFgidhAJonwjh2kwj967RvWFaMMk62HlLJLZ+IGK2XsVy4Aw== +"@docusaurus/plugin-content-docs@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.7.0.tgz#297a549e926ee2b1147b5242af6f21532c7b107c" + integrity sha512-GXg5V7kC9FZE4FkUZA8oo/NrlRb06UwuICzI6tcbzj0+TVgjq/mpUXXzSgKzMS82YByi4dY2Q808njcBCyy6tQ== dependencies: - "@docusaurus/core" "3.6.0" - "@docusaurus/logger" "3.6.0" - "@docusaurus/mdx-loader" "3.6.0" - "@docusaurus/module-type-aliases" "3.6.0" - "@docusaurus/theme-common" "3.6.0" - "@docusaurus/types" "3.6.0" - "@docusaurus/utils" "3.6.0" - "@docusaurus/utils-common" "3.6.0" - "@docusaurus/utils-validation" "3.6.0" + "@docusaurus/core" "3.7.0" + "@docusaurus/logger" "3.7.0" + "@docusaurus/mdx-loader" "3.7.0" + "@docusaurus/module-type-aliases" "3.7.0" + "@docusaurus/theme-common" "3.7.0" + "@docusaurus/types" "3.7.0" + "@docusaurus/utils" "3.7.0" + "@docusaurus/utils-common" "3.7.0" + "@docusaurus/utils-validation" "3.7.0" "@types/react-router-config" "^5.0.7" combine-promises "^1.1.0" fs-extra "^11.1.1" @@ -1424,115 +1601,130 @@ utility-types "^3.10.0" webpack "^5.88.1" -"@docusaurus/plugin-content-pages@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.6.0.tgz#5dd284bf063baaba1e0305c90b1dd0d5acc7e466" - integrity sha512-RKHhJrfkadHc7+tt1cP48NWifOrhkSRMPdXNYytzhoQrXlP6Ph+3tfQ4/n+nT0S3Y9+wwRxYqRqA380ZLt+QtQ== +"@docusaurus/plugin-content-pages@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.7.0.tgz#c4a8f7237872236aacb77665822c474c0a00e91a" + integrity sha512-YJSU3tjIJf032/Aeao8SZjFOrXJbz/FACMveSMjLyMH4itQyZ2XgUIzt4y+1ISvvk5zrW4DABVT2awTCqBkx0Q== dependencies: - "@docusaurus/core" "3.6.0" - "@docusaurus/mdx-loader" "3.6.0" - "@docusaurus/types" "3.6.0" - "@docusaurus/utils" "3.6.0" - "@docusaurus/utils-validation" "3.6.0" + "@docusaurus/core" "3.7.0" + "@docusaurus/mdx-loader" "3.7.0" + "@docusaurus/types" "3.7.0" + "@docusaurus/utils" "3.7.0" + "@docusaurus/utils-validation" "3.7.0" fs-extra "^11.1.1" tslib "^2.6.0" webpack "^5.88.1" -"@docusaurus/plugin-debug@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-3.6.0.tgz#0a6da9ba31a0acb176ae2762b4d6b96b1906c826" - integrity sha512-o8T1Rl94COLdSlKvjYLQpRJQRU8WWZ8EX1B0yV0dQLNN8reyH7MQW+6z1ig4sQFfH3pnjPWVGHfuEjcib5m7Eg== +"@docusaurus/plugin-debug@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-3.7.0.tgz#a4fd45132e40cffe96bb51f48e89982a1cb8e194" + integrity sha512-Qgg+IjG/z4svtbCNyTocjIwvNTNEwgRjSXXSJkKVG0oWoH0eX/HAPiu+TS1HBwRPQV+tTYPWLrUypYFepfujZA== dependencies: - "@docusaurus/core" "3.6.0" - "@docusaurus/types" "3.6.0" - "@docusaurus/utils" "3.6.0" + "@docusaurus/core" "3.7.0" + "@docusaurus/types" "3.7.0" + "@docusaurus/utils" "3.7.0" fs-extra "^11.1.1" react-json-view-lite "^1.2.0" tslib "^2.6.0" -"@docusaurus/plugin-google-analytics@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.6.0.tgz#9e8245eef1bee95e44ef2af92ce3e844a8e93e64" - integrity sha512-kgRFbfpi6Hshj75YUztKyEMtI/kw0trPRwoTN4g+W1NK99R/vh8phTvhBTIMnDbetU79795LkwfG0rZ/ce6zWQ== +"@docusaurus/plugin-google-analytics@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.7.0.tgz#d20f665e810fb2295d1c1bbfe13398c5ff42eb24" + integrity sha512-otIqiRV/jka6Snjf+AqB360XCeSv7lQC+DKYW+EUZf6XbuE8utz5PeUQ8VuOcD8Bk5zvT1MC4JKcd5zPfDuMWA== dependencies: - "@docusaurus/core" "3.6.0" - "@docusaurus/types" "3.6.0" - "@docusaurus/utils-validation" "3.6.0" + "@docusaurus/core" "3.7.0" + "@docusaurus/types" "3.7.0" + "@docusaurus/utils-validation" "3.7.0" tslib "^2.6.0" -"@docusaurus/plugin-google-gtag@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.6.0.tgz#bed8381fe3ab357d56a565f657e38d8ea6272703" - integrity sha512-nqu4IfjaO4UX+dojHL2BxHRS+sKj31CIMWYo49huQ3wTET0Oc3u/WGTaKd3ShTPDhkgiRhTOSTPUwJWrU55nHg== +"@docusaurus/plugin-google-gtag@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.7.0.tgz#a48638dfd132858060458b875a440b6cbda6bf8f" + integrity sha512-M3vrMct1tY65ModbyeDaMoA+fNJTSPe5qmchhAbtqhDD/iALri0g9LrEpIOwNaoLmm6lO88sfBUADQrSRSGSWA== dependencies: - "@docusaurus/core" "3.6.0" - "@docusaurus/types" "3.6.0" - "@docusaurus/utils-validation" "3.6.0" + "@docusaurus/core" "3.7.0" + "@docusaurus/types" "3.7.0" + "@docusaurus/utils-validation" "3.7.0" "@types/gtag.js" "^0.0.12" tslib "^2.6.0" -"@docusaurus/plugin-google-tag-manager@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.6.0.tgz#326382de05888ea4317837be736eabd635adbc71" - integrity sha512-OU6c5xI0nOVbEc9eImGvvsgNWe4vGm97t/W3aLHjWsHyNk3uwFNBQMHRvBUwAi9k/K3kyC5E7DWnc67REhdLOw== +"@docusaurus/plugin-google-tag-manager@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.7.0.tgz#0a4390f4b0e760d073bdb1905436bfa7bd71356b" + integrity sha512-X8U78nb8eiMiPNg3jb9zDIVuuo/rE1LjGDGu+5m5CX4UBZzjMy+klOY2fNya6x8ACyE/L3K2erO1ErheP55W/w== dependencies: - "@docusaurus/core" "3.6.0" - "@docusaurus/types" "3.6.0" - "@docusaurus/utils-validation" "3.6.0" + "@docusaurus/core" "3.7.0" + "@docusaurus/types" "3.7.0" + "@docusaurus/utils-validation" "3.7.0" tslib "^2.6.0" -"@docusaurus/plugin-sitemap@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.6.0.tgz#c7c93f75f03391ca9071da48563fc4faa84966bc" - integrity sha512-YB5XMdf9FjLhgbHY/cDbYhVxsgcpPIjxY9769HUgFOB7GVzItTLOR71W035R1BiR2CA5QAn3XOSg36WLRxlhQQ== +"@docusaurus/plugin-sitemap@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.7.0.tgz#2c1bf9de26aeda455df6f77748e5887ace39b2d7" + integrity sha512-bTRT9YLZ/8I/wYWKMQke18+PF9MV8Qub34Sku6aw/vlZ/U+kuEuRpQ8bTcNOjaTSfYsWkK4tTwDMHK2p5S86cA== dependencies: - "@docusaurus/core" "3.6.0" - "@docusaurus/logger" "3.6.0" - "@docusaurus/types" "3.6.0" - "@docusaurus/utils" "3.6.0" - "@docusaurus/utils-common" "3.6.0" - "@docusaurus/utils-validation" "3.6.0" + "@docusaurus/core" "3.7.0" + "@docusaurus/logger" "3.7.0" + "@docusaurus/types" "3.7.0" + "@docusaurus/utils" "3.7.0" + "@docusaurus/utils-common" "3.7.0" + "@docusaurus/utils-validation" "3.7.0" fs-extra "^11.1.1" sitemap "^7.1.1" tslib "^2.6.0" -"@docusaurus/preset-classic@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-3.6.0.tgz#71561f366a266be571022764eb8b9e5618f573eb" - integrity sha512-kpGNdQzr/Dpm7o3b1iaQrz4DMDx3WIeBbl4V4P4maa2zAQkTdlaP4CMgA5oKrRrpqPLnQFsUM/b+qf2glhl2Tw== +"@docusaurus/plugin-svgr@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-svgr/-/plugin-svgr-3.7.0.tgz#018e89efd615d5fde77b891a8c2aadf203013f5d" + integrity sha512-HByXIZTbc4GV5VAUkZ2DXtXv1Qdlnpk3IpuImwSnEzCDBkUMYcec5282hPjn6skZqB25M1TYCmWS91UbhBGxQg== dependencies: - "@docusaurus/core" "3.6.0" - "@docusaurus/plugin-content-blog" "3.6.0" - "@docusaurus/plugin-content-docs" "3.6.0" - "@docusaurus/plugin-content-pages" "3.6.0" - "@docusaurus/plugin-debug" "3.6.0" - "@docusaurus/plugin-google-analytics" "3.6.0" - "@docusaurus/plugin-google-gtag" "3.6.0" - "@docusaurus/plugin-google-tag-manager" "3.6.0" - "@docusaurus/plugin-sitemap" "3.6.0" - "@docusaurus/theme-classic" "3.6.0" - "@docusaurus/theme-common" "3.6.0" - "@docusaurus/theme-search-algolia" "3.6.0" - "@docusaurus/types" "3.6.0" + "@docusaurus/core" "3.7.0" + "@docusaurus/types" "3.7.0" + "@docusaurus/utils" "3.7.0" + "@docusaurus/utils-validation" "3.7.0" + "@svgr/core" "8.1.0" + "@svgr/webpack" "^8.1.0" + tslib "^2.6.0" + webpack "^5.88.1" -"@docusaurus/theme-classic@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-3.6.0.tgz#8f34b65c85f5082deb3633a893974d2eee309121" - integrity sha512-sAXNfwPL6uRD+BuHuKXZfAXud7SS7IK/JdrPuzyQxdO1gJKzI5GFfe1ED1QoJDNWJWJ01JHE5rSnwYLEADc2rQ== +"@docusaurus/preset-classic@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-3.7.0.tgz#f6656a04ae6a4877523dbd04f7c491632e4003b9" + integrity sha512-nPHj8AxDLAaQXs+O6+BwILFuhiWbjfQWrdw2tifOClQoNfuXDjfjogee6zfx6NGHWqshR23LrcN115DmkHC91Q== dependencies: - "@docusaurus/core" "3.6.0" - "@docusaurus/logger" "3.6.0" - "@docusaurus/mdx-loader" "3.6.0" - "@docusaurus/module-type-aliases" "3.6.0" - "@docusaurus/plugin-content-blog" "3.6.0" - "@docusaurus/plugin-content-docs" "3.6.0" - "@docusaurus/plugin-content-pages" "3.6.0" - "@docusaurus/theme-common" "3.6.0" - "@docusaurus/theme-translations" "3.6.0" - "@docusaurus/types" "3.6.0" - "@docusaurus/utils" "3.6.0" - "@docusaurus/utils-common" "3.6.0" - "@docusaurus/utils-validation" "3.6.0" + "@docusaurus/core" "3.7.0" + "@docusaurus/plugin-content-blog" "3.7.0" + "@docusaurus/plugin-content-docs" "3.7.0" + "@docusaurus/plugin-content-pages" "3.7.0" + "@docusaurus/plugin-debug" "3.7.0" + "@docusaurus/plugin-google-analytics" "3.7.0" + "@docusaurus/plugin-google-gtag" "3.7.0" + "@docusaurus/plugin-google-tag-manager" "3.7.0" + "@docusaurus/plugin-sitemap" "3.7.0" + "@docusaurus/plugin-svgr" "3.7.0" + "@docusaurus/theme-classic" "3.7.0" + "@docusaurus/theme-common" "3.7.0" + "@docusaurus/theme-search-algolia" "3.7.0" + "@docusaurus/types" "3.7.0" + +"@docusaurus/theme-classic@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-3.7.0.tgz#b483bd8e2923b6994b5f47238884b9f8984222c5" + integrity sha512-MnLxG39WcvLCl4eUzHr0gNcpHQfWoGqzADCly54aqCofQX6UozOS9Th4RK3ARbM9m7zIRv3qbhggI53dQtx/hQ== + dependencies: + "@docusaurus/core" "3.7.0" + "@docusaurus/logger" "3.7.0" + "@docusaurus/mdx-loader" "3.7.0" + "@docusaurus/module-type-aliases" "3.7.0" + "@docusaurus/plugin-content-blog" "3.7.0" + "@docusaurus/plugin-content-docs" "3.7.0" + "@docusaurus/plugin-content-pages" "3.7.0" + "@docusaurus/theme-common" "3.7.0" + "@docusaurus/theme-translations" "3.7.0" + "@docusaurus/types" "3.7.0" + "@docusaurus/utils" "3.7.0" + "@docusaurus/utils-common" "3.7.0" + "@docusaurus/utils-validation" "3.7.0" "@mdx-js/react" "^3.0.0" clsx "^2.0.0" copy-text-to-clipboard "^3.2.0" @@ -1547,15 +1739,15 @@ tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-common@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-3.6.0.tgz#9a061d278df76da0f70a9465cd0b7299c14d03d3" - integrity sha512-frjlYE5sRs+GuPs4XXlp9aMLI2O4H5FPpznDAXBrCm+8EpWRiIb443ePMxM3IyMCQ5bwFlki0PI9C+r4apstnw== +"@docusaurus/theme-common@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-3.7.0.tgz#18bf5c6b149a701f4bd865715ee8b595aa40b354" + integrity sha512-8eJ5X0y+gWDsURZnBfH0WabdNm8XMCXHv8ENy/3Z/oQKwaB/EHt5lP9VsTDTf36lKEp0V6DjzjFyFIB+CetL0A== dependencies: - "@docusaurus/mdx-loader" "3.6.0" - "@docusaurus/module-type-aliases" "3.6.0" - "@docusaurus/utils" "3.6.0" - "@docusaurus/utils-common" "3.6.0" + "@docusaurus/mdx-loader" "3.7.0" + "@docusaurus/module-type-aliases" "3.7.0" + "@docusaurus/utils" "3.7.0" + "@docusaurus/utils-common" "3.7.0" "@types/history" "^4.7.11" "@types/react" "*" "@types/react-router-config" "*" @@ -1565,21 +1757,21 @@ tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-search-algolia@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.6.0.tgz#47dcfca68f50163abce411dd9b181855a9ec9c83" - integrity sha512-4IwRUkxjrisR8LXBHeE4d2btraWdMficbgiVL3UHvJURmyvgzMBZQP8KrK8rjdXeu8SuRxSmeV6NSVomRvdbEg== +"@docusaurus/theme-search-algolia@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.7.0.tgz#2108ddf0b300b82de7c2b9ff9fcf62121b66ea37" + integrity sha512-Al/j5OdzwRU1m3falm+sYy9AaB93S1XF1Lgk9Yc6amp80dNxJVplQdQTR4cYdzkGtuQqbzUA8+kaoYYO0RbK6g== dependencies: - "@docsearch/react" "^3.5.2" - "@docusaurus/core" "3.6.0" - "@docusaurus/logger" "3.6.0" - "@docusaurus/plugin-content-docs" "3.6.0" - "@docusaurus/theme-common" "3.6.0" - "@docusaurus/theme-translations" "3.6.0" - "@docusaurus/utils" "3.6.0" - "@docusaurus/utils-validation" "3.6.0" - algoliasearch "^4.18.0" - algoliasearch-helper "^3.13.3" + "@docsearch/react" "^3.8.1" + "@docusaurus/core" "3.7.0" + "@docusaurus/logger" "3.7.0" + "@docusaurus/plugin-content-docs" "3.7.0" + "@docusaurus/theme-common" "3.7.0" + "@docusaurus/theme-translations" "3.7.0" + "@docusaurus/utils" "3.7.0" + "@docusaurus/utils-validation" "3.7.0" + algoliasearch "^5.17.1" + algoliasearch-helper "^3.22.6" clsx "^2.0.0" eta "^2.2.0" fs-extra "^11.1.1" @@ -1587,58 +1779,59 @@ tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-translations@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-translations/-/theme-translations-3.6.0.tgz#93994e931f340c1712c81ac80dbab5750c24634f" - integrity sha512-L555X8lWE3fv8VaF0Bc1VnAgi10UvRKFcvADHiYR7Gj37ItaWP5i7xLHsSw7fi/SHTXe5wfIeCFNqUYHyCOHAQ== +"@docusaurus/theme-translations@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-translations/-/theme-translations-3.7.0.tgz#0891aedc7c7040afcb3a1b34051d3a69096d0d25" + integrity sha512-Ewq3bEraWDmienM6eaNK7fx+/lHMtGDHQyd1O+4+3EsDxxUmrzPkV7Ct3nBWTuE0MsoZr3yNwQVKjllzCMuU3g== dependencies: fs-extra "^11.1.1" tslib "^2.6.0" -"@docusaurus/types@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-3.6.0.tgz#8fa82332a7c7b8093b5c55e1115f5854ce484978" - integrity sha512-jADLgoZGWhAzThr+mRiyuFD4OUzt6jHnb7NRArRKorgxckqUBaPyFOau9hhbcSTHtU6ceyeWjN7FDt7uG2Hplw== +"@docusaurus/types@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-3.7.0.tgz#3f5a68a60f80ecdcb085666da1d68f019afda943" + integrity sha512-kOmZg5RRqJfH31m+6ZpnwVbkqMJrPOG5t0IOl4i/+3ruXyNfWzZ0lVtVrD0u4ONc/0NOsS9sWYaxxWNkH1LdLQ== dependencies: "@mdx-js/mdx" "^3.0.0" "@types/history" "^4.7.11" "@types/react" "*" commander "^5.1.0" joi "^17.9.2" - react-helmet-async "^1.3.0" + react-helmet-async "npm:@slorber/react-helmet-async@1.3.0" utility-types "^3.10.0" webpack "^5.95.0" webpack-merge "^5.9.0" -"@docusaurus/utils-common@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-3.6.0.tgz#11855ea503132bbcaba6ca4d351293ff10a75d34" - integrity sha512-diUDNfbw33GaZMmKwdTckT2IBfVouXLXRD+zphH9ywswuaEIKqixvuf5g41H7MBBrlMsxhna3uTMoB4B/OPDcA== +"@docusaurus/utils-common@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-3.7.0.tgz#1bef52837d321db5dd2361fc07f3416193b5d029" + integrity sha512-IZeyIfCfXy0Mevj6bWNg7DG7B8G+S6o6JVpddikZtWyxJguiQ7JYr0SIZ0qWd8pGNuMyVwriWmbWqMnK7Y5PwA== dependencies: + "@docusaurus/types" "3.7.0" tslib "^2.6.0" -"@docusaurus/utils-validation@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-3.6.0.tgz#5557ca14fa64ac29e6f70e61006be721395ecde5" - integrity sha512-CRHiKKJEKA0GFlfOf71JWHl7PtwOyX0+Zg9ep9NFEZv6Lcx3RJ9nhl7p8HRjPL6deyYceavM//BsfW4pCI4BtA== +"@docusaurus/utils-validation@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-3.7.0.tgz#dc0786fb633ae5cef8e93337bf21c2a826c7ecbd" + integrity sha512-w8eiKk8mRdN+bNfeZqC4nyFoxNyI1/VExMKAzD9tqpJfLLbsa46Wfn5wcKH761g9WkKh36RtFV49iL9lh1DYBA== dependencies: - "@docusaurus/logger" "3.6.0" - "@docusaurus/utils" "3.6.0" - "@docusaurus/utils-common" "3.6.0" + "@docusaurus/logger" "3.7.0" + "@docusaurus/utils" "3.7.0" + "@docusaurus/utils-common" "3.7.0" fs-extra "^11.2.0" joi "^17.9.2" js-yaml "^4.1.0" lodash "^4.17.21" tslib "^2.6.0" -"@docusaurus/utils@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-3.6.0.tgz#192785da6fd62dfd83d6f1879c3aa45547f5df23" - integrity sha512-VKczAutI4mptiAw/WcYEu5WeVhQ6Q1zdIUl64SGw9K++9lziH+Kt10Ee8l2dMpRkiUk6zzK20kMNlX2WCUwXYQ== +"@docusaurus/utils@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-3.7.0.tgz#dfdebd63524c52b498f36b2907a3b2261930b9bb" + integrity sha512-e7zcB6TPnVzyUaHMJyLSArKa2AG3h9+4CfvKXKKWNx6hRs+p0a+u7HHTJBgo6KW2m+vqDnuIHK4X+bhmoghAFA== dependencies: - "@docusaurus/logger" "3.6.0" - "@docusaurus/utils-common" "3.6.0" - "@svgr/webpack" "^8.1.0" + "@docusaurus/logger" "3.7.0" + "@docusaurus/types" "3.7.0" + "@docusaurus/utils-common" "3.7.0" escape-string-regexp "^4.0.0" file-loader "^6.2.0" fs-extra "^11.1.1" @@ -1689,9 +1882,9 @@ chalk "^4.0.0" "@jridgewell/gen-mapping@^0.3.5": - version "0.3.5" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" - integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + version "0.3.8" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" + integrity sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA== dependencies: "@jridgewell/set-array" "^1.2.1" "@jridgewell/sourcemap-codec" "^1.4.10" @@ -1720,7 +1913,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== -"@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": +"@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== @@ -2049,9 +2242,9 @@ integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^5.0.0": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.0.1.tgz#3c9997ae9d00bc236e45c6374e84f2596458d9db" - integrity sha512-CRICJIl0N5cXDONAdlTv5ShATZ4HEwk6kDDIW2/w9qOWKg+NU/5F8wYRWCrONad0/UKkloNSmmyN/wX4rtpbVA== + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.0.3.tgz#04174d3f0836863467b7fbcbbbcd69441d205715" + integrity sha512-JEhMNwUJt7bw728CydvYzntD0XJeTmDnvwLlbfbAhE7Tbslm/ax6bdIiUwTgeVlZTsJQPwZwKpAkyDtIjsvx3g== dependencies: "@types/node" "*" "@types/qs" "*" @@ -2181,11 +2374,11 @@ "@types/node" "*" "@types/node@*": - version "22.8.7" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.8.7.tgz#04ab7a073d95b4a6ee899f235d43f3c320a976f4" - integrity sha512-LidcG+2UeYIWcMuMUpBKOnryBWG/rnmOHQR5apjn8myTQcx3rinFRn7DcIFhMnS0PPFSC6OafdIKEad0lj6U0Q== + version "22.10.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.10.5.tgz#95af89a3fb74a2bb41ef9927f206e6472026e48b" + integrity sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ== dependencies: - undici-types "~6.19.8" + undici-types "~6.20.0" "@types/node@^17.0.5": version "17.0.45" @@ -2202,15 +2395,10 @@ resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.5.tgz#72499abbb4c4ec9982446509d2f14fb8483869d6" integrity sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ== -"@types/prop-types@*": - version "15.7.13" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.13.tgz#2af91918ee12d9d32914feb13f5326658461b451" - integrity sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA== - "@types/qs@*": - version "6.9.16" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.16.tgz#52bba125a07c0482d26747d5d4947a64daf8f794" - integrity sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A== + version "6.9.17" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.17.tgz#fc560f60946d0aeff2f914eb41679659d3310e1a" + integrity sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ== "@types/range-parser@*": version "1.2.7" @@ -2244,11 +2432,10 @@ "@types/react" "*" "@types/react@*": - version "18.3.12" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.12.tgz#99419f182ccd69151813b7ee24b792fe08774f60" - integrity sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw== + version "19.0.2" + resolved "https://registry.yarnpkg.com/@types/react/-/react-19.0.2.tgz#9363e6b3ef898c471cb182dd269decc4afc1b4f6" + integrity sha512-USU8ZI/xyKJwFTpjSVIrSeHBVAGagkHQKPNbxeWwql/vDmnTIBgx+TJnhFnj1NXgz8XfprU0egV2dROLGpsBEg== dependencies: - "@types/prop-types" "*" csstype "^3.0.2" "@types/retry@0.12.0": @@ -2324,129 +2511,129 @@ "@types/yargs-parser" "*" "@ungap/structured-clone@^1.0.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" - integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + version "1.2.1" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.1.tgz#28fa185f67daaf7b7a1a8c1d445132c5d979f8bd" + integrity sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA== -"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" - integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== +"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6" + integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ== dependencies: - "@webassemblyjs/helper-numbers" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-numbers" "1.13.2" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" -"@webassemblyjs/floating-point-hex-parser@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" - integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== +"@webassemblyjs/floating-point-hex-parser@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz#fcca1eeddb1cc4e7b6eed4fc7956d6813b21b9fb" + integrity sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA== -"@webassemblyjs/helper-api-error@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" - integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== +"@webassemblyjs/helper-api-error@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz#e0a16152248bc38daee76dd7e21f15c5ef3ab1e7" + integrity sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ== -"@webassemblyjs/helper-buffer@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" - integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== +"@webassemblyjs/helper-buffer@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz#822a9bc603166531f7d5df84e67b5bf99b72b96b" + integrity sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA== -"@webassemblyjs/helper-numbers@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" - integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== +"@webassemblyjs/helper-numbers@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz#dbd932548e7119f4b8a7877fd5a8d20e63490b2d" + integrity sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA== dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.6" - "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/floating-point-hex-parser" "1.13.2" + "@webassemblyjs/helper-api-error" "1.13.2" "@xtuc/long" "4.2.2" -"@webassemblyjs/helper-wasm-bytecode@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" - integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== +"@webassemblyjs/helper-wasm-bytecode@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz#e556108758f448aae84c850e593ce18a0eb31e0b" + integrity sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA== -"@webassemblyjs/helper-wasm-section@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" - integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== +"@webassemblyjs/helper-wasm-section@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz#9629dda9c4430eab54b591053d6dc6f3ba050348" + integrity sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw== dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-buffer" "1.12.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/wasm-gen" "1.14.1" -"@webassemblyjs/ieee754@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" - integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== +"@webassemblyjs/ieee754@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz#1c5eaace1d606ada2c7fd7045ea9356c59ee0dba" + integrity sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" - integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== +"@webassemblyjs/leb128@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz#57c5c3deb0105d02ce25fa3fd74f4ebc9fd0bbb0" + integrity sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" - integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== +"@webassemblyjs/utf8@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz#917a20e93f71ad5602966c2d685ae0c6c21f60f1" + integrity sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ== -"@webassemblyjs/wasm-edit@^1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" - integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== +"@webassemblyjs/wasm-edit@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz#ac6689f502219b59198ddec42dcd496b1004d597" + integrity sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ== dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-buffer" "1.12.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/helper-wasm-section" "1.12.1" - "@webassemblyjs/wasm-gen" "1.12.1" - "@webassemblyjs/wasm-opt" "1.12.1" - "@webassemblyjs/wasm-parser" "1.12.1" - "@webassemblyjs/wast-printer" "1.12.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/helper-wasm-section" "1.14.1" + "@webassemblyjs/wasm-gen" "1.14.1" + "@webassemblyjs/wasm-opt" "1.14.1" + "@webassemblyjs/wasm-parser" "1.14.1" + "@webassemblyjs/wast-printer" "1.14.1" -"@webassemblyjs/wasm-gen@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" - integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== +"@webassemblyjs/wasm-gen@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz#991e7f0c090cb0bb62bbac882076e3d219da9570" + integrity sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg== dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/ieee754" "1.11.6" - "@webassemblyjs/leb128" "1.11.6" - "@webassemblyjs/utf8" "1.11.6" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/ieee754" "1.13.2" + "@webassemblyjs/leb128" "1.13.2" + "@webassemblyjs/utf8" "1.13.2" -"@webassemblyjs/wasm-opt@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" - integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== +"@webassemblyjs/wasm-opt@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz#e6f71ed7ccae46781c206017d3c14c50efa8106b" + integrity sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw== dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-buffer" "1.12.1" - "@webassemblyjs/wasm-gen" "1.12.1" - "@webassemblyjs/wasm-parser" "1.12.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/wasm-gen" "1.14.1" + "@webassemblyjs/wasm-parser" "1.14.1" -"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" - integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== +"@webassemblyjs/wasm-parser@1.14.1", "@webassemblyjs/wasm-parser@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz#b3e13f1893605ca78b52c68e54cf6a865f90b9fb" + integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ== dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-api-error" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/ieee754" "1.11.6" - "@webassemblyjs/leb128" "1.11.6" - "@webassemblyjs/utf8" "1.11.6" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-api-error" "1.13.2" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/ieee754" "1.13.2" + "@webassemblyjs/leb128" "1.13.2" + "@webassemblyjs/utf8" "1.13.2" -"@webassemblyjs/wast-printer@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" - integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== +"@webassemblyjs/wast-printer@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz#3bb3e9638a8ae5fdaf9610e7a06b4d9f9aa6fe07" + integrity sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw== dependencies: - "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/ast" "1.14.1" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -2536,52 +2723,31 @@ ajv@^8.0.0, ajv@^8.9.0: json-schema-traverse "^1.0.0" require-from-string "^2.0.2" -algoliasearch-helper@^3.13.3: - version "3.22.5" - resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.22.5.tgz#2fcc26814e10a121a2c2526a1b05c754061c56c0" - integrity sha512-lWvhdnc+aKOKx8jyA3bsdEgHzm/sglC4cYdMG4xSQyRiPLJVJtH/IVYZG3Hp6PkTEhQqhyVYkeP9z2IlcHJsWw== +algoliasearch-helper@^3.22.6: + version "3.22.6" + resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.22.6.tgz#6a31c67d277a32f3f7ae1b8a6e57ca73f1e1a0b0" + integrity sha512-F2gSb43QHyvZmvH/2hxIjbk/uFdO2MguQYTFP7J+RowMW1csjIODMobEnpLI8nbLQuzZnGZdIxl5Bpy1k9+CFQ== dependencies: "@algolia/events" "^4.0.1" -algoliasearch@^4.18.0: - version "4.24.0" - resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.24.0.tgz#b953b3e2309ef8f25da9de311b95b994ac918275" - integrity sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g== +algoliasearch@^5.14.2, algoliasearch@^5.17.1: + version "5.18.0" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-5.18.0.tgz#2023232151f2ee9a580ea84d4a36676871979ce4" + integrity sha512-/tfpK2A4FpS0o+S78o3YSdlqXr0MavJIDlFK3XZrlXLy7vaRXJvW5jYg3v5e/wCaF8y0IpMjkYLhoV6QqfpOgw== dependencies: - "@algolia/cache-browser-local-storage" "4.24.0" - "@algolia/cache-common" "4.24.0" - "@algolia/cache-in-memory" "4.24.0" - "@algolia/client-account" "4.24.0" - "@algolia/client-analytics" "4.24.0" - "@algolia/client-common" "4.24.0" - "@algolia/client-personalization" "4.24.0" - "@algolia/client-search" "4.24.0" - "@algolia/logger-common" "4.24.0" - "@algolia/logger-console" "4.24.0" - "@algolia/recommend" "4.24.0" - "@algolia/requester-browser-xhr" "4.24.0" - "@algolia/requester-common" "4.24.0" - "@algolia/requester-node-http" "4.24.0" - "@algolia/transporter" "4.24.0" - -algoliasearch@^5.11.0: - version "5.12.0" - resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-5.12.0.tgz#2e822a7916d691e55058ea7dba277d5110969dd0" - integrity sha512-psGBRYdGgik8I6m28iAB8xpubvjEt7UQU+w5MAJUA2324WHiGoHap5BPkkjB14rMaXeRts6pmOsrVIglGyOVwg== - dependencies: - "@algolia/client-abtesting" "5.12.0" - "@algolia/client-analytics" "5.12.0" - "@algolia/client-common" "5.12.0" - "@algolia/client-insights" "5.12.0" - "@algolia/client-personalization" "5.12.0" - "@algolia/client-query-suggestions" "5.12.0" - "@algolia/client-search" "5.12.0" - "@algolia/ingestion" "1.12.0" - "@algolia/monitoring" "1.12.0" - "@algolia/recommend" "5.12.0" - "@algolia/requester-browser-xhr" "5.12.0" - "@algolia/requester-fetch" "5.12.0" - "@algolia/requester-node-http" "5.12.0" + "@algolia/client-abtesting" "5.18.0" + "@algolia/client-analytics" "5.18.0" + "@algolia/client-common" "5.18.0" + "@algolia/client-insights" "5.18.0" + "@algolia/client-personalization" "5.18.0" + "@algolia/client-query-suggestions" "5.18.0" + "@algolia/client-search" "5.18.0" + "@algolia/ingestion" "1.18.0" + "@algolia/monitoring" "1.18.0" + "@algolia/recommend" "5.18.0" + "@algolia/requester-browser-xhr" "5.18.0" + "@algolia/requester-fetch" "5.18.0" + "@algolia/requester-node-http" "5.18.0" ansi-align@^3.0.1: version "3.0.1" @@ -2669,7 +2835,7 @@ at-least-node@^1.0.0: resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== -autoprefixer@^10.4.14, autoprefixer@^10.4.19: +autoprefixer@^10.4.19: version "10.4.20" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.20.tgz#5caec14d43976ef42e32dcb4bd62878e96be5b3b" integrity sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g== @@ -2697,12 +2863,12 @@ babel-plugin-dynamic-import-node@^2.3.3: object.assign "^4.1.0" babel-plugin-polyfill-corejs2@^0.4.10: - version "0.4.11" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz#30320dfe3ffe1a336c15afdcdafd6fd615b25e33" - integrity sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q== + version "0.4.12" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz#ca55bbec8ab0edeeef3d7b8ffd75322e210879a9" + integrity sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og== dependencies: "@babel/compat-data" "^7.22.6" - "@babel/helper-define-polyfill-provider" "^0.6.2" + "@babel/helper-define-polyfill-provider" "^0.6.3" semver "^6.3.1" babel-plugin-polyfill-corejs3@^0.10.6: @@ -2714,11 +2880,11 @@ babel-plugin-polyfill-corejs3@^0.10.6: core-js-compat "^3.38.0" babel-plugin-polyfill-regenerator@^0.6.1: - version "0.6.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz#addc47e240edd1da1058ebda03021f382bba785e" - integrity sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg== + version "0.6.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz#abeb1f3f1c762eace37587f42548b08b57789bc8" + integrity sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q== dependencies: - "@babel/helper-define-polyfill-provider" "^0.6.2" + "@babel/helper-define-polyfill-provider" "^0.6.3" bail@^2.0.0: version "2.0.2" @@ -2764,9 +2930,9 @@ body-parser@1.20.3: unpipe "1.0.0" bonjour-service@^1.0.11: - version "1.2.1" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.2.1.tgz#eb41b3085183df3321da1264719fbada12478d02" - integrity sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw== + version "1.3.0" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.3.0.tgz#80d867430b5a0da64e82a8047fc1e355bdb71722" + integrity sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA== dependencies: fast-deep-equal "^3.1.3" multicast-dns "^7.2.5" @@ -2819,14 +2985,14 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.23.0, browserslist@^4.23.3, browserslist@^4.24.0, browserslist@^4.24.2: - version "4.24.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580" - integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg== +browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.23.0, browserslist@^4.23.1, browserslist@^4.23.3, browserslist@^4.24.0, browserslist@^4.24.2: + version "4.24.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.3.tgz#5fc2725ca8fb3c1432e13dac278c7cc103e026d2" + integrity sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA== dependencies: - caniuse-lite "^1.0.30001669" - electron-to-chromium "^1.5.41" - node-releases "^2.0.18" + caniuse-lite "^1.0.30001688" + electron-to-chromium "^1.5.73" + node-releases "^2.0.19" update-browserslist-db "^1.1.1" buffer-from@^1.0.0: @@ -2862,16 +3028,31 @@ cacheable-request@^10.2.8: normalize-url "^8.0.0" responselike "^3.0.0" -call-bind@^1.0.5, call-bind@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" - integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== +call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz#32e5892e6361b29b0b545ba6f7763378daca2840" + integrity sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g== dependencies: - es-define-property "^1.0.0" es-errors "^1.3.0" function-bind "^1.1.2" + +call-bind@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c" + integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== + dependencies: + call-bind-apply-helpers "^1.0.0" + es-define-property "^1.0.0" get-intrinsic "^1.2.4" - set-function-length "^1.2.1" + set-function-length "^1.2.2" + +call-bound@^1.0.2, call-bound@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.3.tgz#41cfd032b593e39176a71533ab4f384aa04fd681" + integrity sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA== + dependencies: + call-bind-apply-helpers "^1.0.1" + get-intrinsic "^1.2.6" callsites@^3.0.0: version "3.1.0" @@ -2906,10 +3087,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001669: - version "1.0.30001677" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz#27c2e2c637e007cfa864a16f7dfe7cde66b38b5f" - integrity sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001688: + version "1.0.30001690" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz#f2d15e3aaf8e18f76b2b8c1481abde063b8104c8" + integrity sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w== ccount@^2.0.0: version "2.0.1" @@ -2925,9 +3106,9 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: supports-color "^7.1.0" chalk@^5.0.1, chalk@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" - integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== + version "5.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.4.1.tgz#1b48bf0963ec158dce2aacf69c093ae2dd2092d8" + integrity sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w== char-regex@^1.0.2: version "1.0.2" @@ -3161,9 +3342,9 @@ connect-history-api-fallback@^2.0.0: integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== consola@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/consola/-/consola-3.2.3.tgz#0741857aa88cfa0d6fd53f1cff0375136e98502f" - integrity sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ== + version "3.3.3" + resolved "https://registry.yarnpkg.com/consola/-/consola-3.3.3.tgz#0dd8a2314b0f7bf18a49064138ad685f3346543d" + integrity sha512-Qil5KwghMzlqd51UXM0b6fyaGHtOC22scxrwrz4A2882LyUMwQjnvaedN1HAeXzphspQ6CpHkzMAWxBTUruDLg== content-disposition@0.5.2: version "0.5.2" @@ -3258,9 +3439,9 @@ cosmiconfig@^8.1.3, cosmiconfig@^8.3.5: path-type "^4.0.0" cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" @@ -3273,11 +3454,27 @@ crypto-random-string@^4.0.0: dependencies: type-fest "^1.0.1" +css-blank-pseudo@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-7.0.1.tgz#32020bff20a209a53ad71b8675852b49e8d57e46" + integrity sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag== + dependencies: + postcss-selector-parser "^7.0.0" + css-declaration-sorter@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz#6dec1c9523bc4a643e088aab8f09e67a54961024" integrity sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow== +css-has-pseudo@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-7.0.2.tgz#fb42e8de7371f2896961e1f6308f13c2c7019b72" + integrity sha512-nzol/h+E0bId46Kn2dQH5VElaknX2Sr0hFuB/1EomdC7j+OISt2ZzK7EHX9DZDY53WbIVAR7FYKSO2XnSf07MQ== + dependencies: + "@csstools/selector-specificity" "^5.0.0" + postcss-selector-parser "^7.0.0" + postcss-value-parser "^4.2.0" + css-loader@^6.8.1: version "6.11.0" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.11.0.tgz#33bae3bf6363d0a7c2cf9031c96c744ff54d85ba" @@ -3304,6 +3501,11 @@ css-minimizer-webpack-plugin@^5.0.1: schema-utils "^4.0.1" serialize-javascript "^6.0.1" +css-prefers-color-scheme@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-10.0.0.tgz#ba001b99b8105b8896ca26fc38309ddb2278bd3c" + integrity sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ== + css-select@^4.1.3: version "4.3.0" resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" @@ -3347,6 +3549,11 @@ css-what@^6.0.1, css-what@^6.1.0: resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== +cssdb@^8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-8.2.3.tgz#7e6980bb5a785a9b4eb2a21bd38d50624b56cb46" + integrity sha512-9BDG5XmJrJQQnJ51VFxXCAtpZ5ebDlAREmO8sxMOVU0aSxN/gocbctjIG5LMh3WBUq+xTlb/jw2LoljBEqraTA== + cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" @@ -3439,9 +3646,9 @@ debug@2.6.9, debug@^2.6.0: ms "2.0.0" debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: - version "4.3.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" - integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + version "4.4.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" + integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== dependencies: ms "^2.1.3" @@ -3634,9 +3841,9 @@ domutils@^2.5.2, domutils@^2.8.0: domhandler "^4.2.0" domutils@^3.0.1: - version "3.1.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" - integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + version "3.2.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.2.1.tgz#b39f4c390a1ae6f6a2c56a5f5a16d6438b6bce28" + integrity sha512-xWXmuRnN9OMP6ptPd2+H0cCbcYBULa5YDTbMm/2lvkWvNA3O4wcW+GvzooqBuNM8yy6pl3VIAeJTUUWUbfI5Fw== dependencies: dom-serializer "^2.0.0" domelementtype "^2.3.0" @@ -3657,6 +3864,15 @@ dot-prop@^6.0.1: dependencies: is-obj "^2.0.0" +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" + duplexer@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" @@ -3672,10 +3888,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.5.41: - version "1.5.50" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.50.tgz#d9ba818da7b2b5ef1f3dd32bce7046feb7e93234" - integrity sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw== +electron-to-chromium@^1.5.73: + version "1.5.76" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.76.tgz#db20295c5061b68f07c8ea4dfcbd701485d94a3d" + integrity sha512-CjVQyG7n7Sr+eBXE86HIulnL5N8xZY1sgmOPGuq/F0Rr0FJq63lg0kEtOIDfZBk44FnDLf6FUJ+dsJcuiUDdDQ== emoji-regex@^8.0.0: version "8.0.0" @@ -3713,9 +3929,9 @@ encodeurl@~2.0.0: integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== enhanced-resolve@^5.17.1: - version "5.17.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" - integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== + version "5.18.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz#91eb1db193896b9801251eeff1c6980278b1e404" + integrity sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -3737,12 +3953,10 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" - integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== - dependencies: - get-intrinsic "^1.2.4" +es-define-property@^1.0.0, es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== es-errors@^1.3.0: version "1.3.0" @@ -3750,9 +3964,16 @@ es-errors@^1.3.0: integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== es-module-lexer@^1.2.1: - version "1.5.4" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.5.4.tgz#a8efec3a3da991e60efa6b633a7cad6ab8d26b78" - integrity sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw== + version "1.6.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.6.0.tgz#da49f587fd9e68ee2404fe4e256c0c7d3a81be21" + integrity sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ== + +es-object-atoms@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.0.0.tgz#ddb55cd47ac2e240701260bc2a8e31ecb643d941" + integrity sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw== + dependencies: + es-errors "^1.3.0" esast-util-from-estree@^2.0.0: version "2.0.0" @@ -3944,9 +4165,9 @@ execa@^5.0.0: strip-final-newline "^2.0.0" express@^4.17.3: - version "4.21.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.21.1.tgz#9dae5dda832f16b4eec941a4e44aa89ec481b281" - integrity sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ== + version "4.21.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.21.2.tgz#cf250e48362174ead6cea4a566abef0162c1ec32" + integrity sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA== dependencies: accepts "~1.3.8" array-flatten "1.1.1" @@ -3967,7 +4188,7 @@ express@^4.17.3: methods "~1.1.2" on-finished "2.4.1" parseurl "~1.3.3" - path-to-regexp "0.1.10" + path-to-regexp "0.1.12" proxy-addr "~2.0.7" qs "6.13.0" range-parser "~1.2.1" @@ -4019,9 +4240,9 @@ fast-uri@^3.0.1: integrity sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw== fastq@^1.6.0: - version "1.17.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" - integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== + version "1.18.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.18.0.tgz#d631d7e25faffea81887fe5ea8c9010e1b36fee0" + integrity sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw== dependencies: reusify "^1.0.4" @@ -4215,22 +4436,35 @@ gensync@^1.0.0-beta.2: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== -get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" - integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== +get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.2.6: + version "1.2.7" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.7.tgz#dcfcb33d3272e15f445d15124bc0a216189b9044" + integrity sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA== dependencies: + call-bind-apply-helpers "^1.0.1" + es-define-property "^1.0.1" es-errors "^1.3.0" + es-object-atoms "^1.0.0" function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" + get-proto "^1.0.0" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== +get-proto@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== + dependencies: + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" + get-stream@^6.0.0, get-stream@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" @@ -4323,12 +4557,10 @@ globby@^13.1.1: merge2 "^1.4.1" slash "^4.0.0" -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" +gopd@^1.0.1, gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== got@^12.1.0: version "12.6.1" @@ -4391,22 +4623,17 @@ has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: dependencies: es-define-property "^1.0.0" -has-proto@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" - integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== - -has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== has-yarn@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-3.0.0.tgz#c3c21e559730d1d3b57e28af1f30d06fac38147d" integrity sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA== -hasown@^2.0.0, hasown@^2.0.2: +hasown@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== @@ -4414,14 +4641,14 @@ hasown@^2.0.0, hasown@^2.0.2: function-bind "^1.1.2" hast-util-from-parse5@^8.0.0: - version "8.0.1" - resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz#654a5676a41211e14ee80d1b1758c399a0327651" - integrity sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ== + version "8.0.2" + resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-8.0.2.tgz#29b42758ba96535fd6021f0f533c000886c0f00f" + integrity sha512-SfMzfdAi/zAoZ1KkFEyyeXBn7u/ShQrfd675ZEE9M3qj+PMFX05xubzRyF76CCSJu8au9jgVxDV1+okFvgZU4A== dependencies: "@types/hast" "^3.0.0" "@types/unist" "^3.0.0" devlop "^1.0.0" - hastscript "^8.0.0" + hastscript "^9.0.0" property-information "^6.0.0" vfile "^6.0.0" vfile-location "^5.0.0" @@ -4435,9 +4662,9 @@ hast-util-parse-selector@^4.0.0: "@types/hast" "^3.0.0" hast-util-raw@^9.0.0: - version "9.0.4" - resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-9.0.4.tgz#2da03e37c46eb1a6f1391f02f9b84ae65818f7ed" - integrity sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA== + version "9.1.0" + resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-9.1.0.tgz#79b66b26f6f68fb50dfb4716b2cdca90d92adf2e" + integrity sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw== dependencies: "@types/hast" "^3.0.0" "@types/unist" "^3.0.0" @@ -4454,9 +4681,9 @@ hast-util-raw@^9.0.0: zwitch "^2.0.0" hast-util-to-estree@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz#f2afe5e869ddf0cf690c75f9fc699f3180b51b19" - integrity sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw== + version "3.1.1" + resolved "https://registry.yarnpkg.com/hast-util-to-estree/-/hast-util-to-estree-3.1.1.tgz#b7f0b247d9f62127bb5db34e3a86c93d17279071" + integrity sha512-IWtwwmPskfSmma9RpzCappDUitC8t5jhAynHhc1m2+5trOgsrp7txscUSavc5Ic8PATyAjfrCK1wgtxh2cICVQ== dependencies: "@types/estree" "^1.0.0" "@types/estree-jsx" "^1.0.0" @@ -4471,7 +4698,7 @@ hast-util-to-estree@^3.0.0: mdast-util-mdxjs-esm "^2.0.0" property-information "^6.0.0" space-separated-tokens "^2.0.0" - style-to-object "^0.4.0" + style-to-object "^1.0.0" unist-util-position "^5.0.0" zwitch "^2.0.0" @@ -4516,10 +4743,10 @@ hast-util-whitespace@^3.0.0: dependencies: "@types/hast" "^3.0.0" -hastscript@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-8.0.0.tgz#4ef795ec8dee867101b9f23cc830d4baf4fd781a" - integrity sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw== +hastscript@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-9.0.0.tgz#2b76b9aa3cba8bf6d5280869f6f6f7165c230763" + integrity sha512-jzaLBGavEDKHrc5EfFImKN7nZKKBdSLIdGvCwDZ9TfzbF2ffXiov8CKE445L2Z1Ek2t/m4SKQ2j6Ipv7NyUolw== dependencies: "@types/hast" "^3.0.0" comma-separated-tokens "^2.0.0" @@ -4725,9 +4952,9 @@ ignore@^5.2.0, ignore@^5.2.4: integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== image-size@^1.0.2: - version "1.1.1" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.1.1.tgz#ddd67d4dc340e52ac29ce5f546a09f4e29e840ac" - integrity sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ== + version "1.2.0" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.2.0.tgz#312af27a2ff4ff58595ad00b9344dd684c910df6" + integrity sha512-4S8fwbO6w3GeCVN6OPtA9I5IGKkcDMPcKndtUlpJuCwu7JLjtj7JZpwqLuyY2nrmQT3AWsCJLSKPsc2mPBSl3w== dependencies: queue "6.0.2" @@ -4792,11 +5019,6 @@ ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -inline-style-parser@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" - integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== - inline-style-parser@0.2.4: version "0.2.4" resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.2.4.tgz#f4af5fe72e612839fcd453d989a586566d695f22" @@ -4856,10 +5078,10 @@ is-ci@^3.0.1: dependencies: ci-info "^3.2.0" -is-core-module@^2.13.0: - version "2.15.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37" - integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ== +is-core-module@^2.16.0: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" + integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== dependencies: hasown "^2.0.2" @@ -5039,9 +5261,9 @@ jest-worker@^29.4.3: supports-color "^8.0.0" jiti@^1.20.0: - version "1.21.6" - resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" - integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== + version "1.21.7" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.7.tgz#9dd81043424a3d28458b193d965f0d18a2300ba9" + integrity sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A== joi@^17.9.2: version "17.13.3" @@ -5074,7 +5296,12 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -jsesc@^3.0.2, jsesc@~3.0.2: +jsesc@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" + integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== + +jsesc@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== @@ -5151,9 +5378,9 @@ leven@^3.1.0: integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== lilconfig@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.2.tgz#e4a7c3cb549e3a606c8dcc32e5ae1005e62c05cb" - integrity sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow== + version "3.1.3" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.3.tgz#a1bcfd6257f9585bf5ae14ceeebb7b559025e4c4" + integrity sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw== lines-and-columns@^1.1.6: version "1.2.4" @@ -5226,7 +5453,7 @@ longest-streak@^3.0.0: resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4" integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -5269,6 +5496,11 @@ markdown-table@^3.0.0: resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.4.tgz#fe44d6d410ff9d6f2ea1797a3f60aa4d2b631c2a" integrity sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw== +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== + mdast-util-directive@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz#3fb1764e705bbdf0afb0d3f889e4404c3e82561f" @@ -5284,9 +5516,9 @@ mdast-util-directive@^3.0.0: unist-util-visit-parents "^6.0.0" mdast-util-find-and-replace@^3.0.0, mdast-util-find-and-replace@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz#a6fc7b62f0994e973490e45262e4bc07607b04e0" - integrity sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA== + version "3.0.2" + resolved "https://registry.yarnpkg.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz#70a3174c894e14df722abf43bc250cbae44b11df" + integrity sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg== dependencies: "@types/mdast" "^4.0.0" escape-string-regexp "^5.0.0" @@ -5529,9 +5761,9 @@ methods@~1.1.2: integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== micromark-core-commonmark@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz#9a45510557d068605c6e9a80f282b2bb8581e43d" - integrity sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA== + version "2.0.2" + resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-2.0.2.tgz#6a45bbb139e126b3f8b361a10711ccc7c6e15e93" + integrity sha512-FKjQKbxd1cibWMM1P9N+H8TwlgGgSkWZMmfuVucLCHaYqeSvJ0hFeHsIa65pA2nYbes0f8LDHPMrd9X7Ujxg9w== dependencies: decode-named-character-reference "^1.0.0" devlop "^1.0.0" @@ -5720,18 +5952,18 @@ micromark-extension-mdxjs@^3.0.0: micromark-util-types "^2.0.0" micromark-factory-destination@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz#857c94debd2c873cba34e0445ab26b74f6a6ec07" - integrity sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz#8fef8e0f7081f0474fbdd92deb50c990a0264639" + integrity sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA== dependencies: micromark-util-character "^2.0.0" micromark-util-symbol "^2.0.0" micromark-util-types "^2.0.0" micromark-factory-label@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz#17c5c2e66ce39ad6f4fc4cbf40d972f9096f726a" - integrity sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz#5267efa97f1e5254efc7f20b459a38cb21058ba1" + integrity sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg== dependencies: devlop "^1.0.0" micromark-util-character "^2.0.0" @@ -5762,17 +5994,17 @@ micromark-factory-space@^1.0.0: micromark-util-types "^1.0.0" micromark-factory-space@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz#5e7afd5929c23b96566d0e1ae018ae4fcf81d030" - integrity sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz#36d0212e962b2b3121f8525fc7a3c7c029f334fc" + integrity sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg== dependencies: micromark-util-character "^2.0.0" micromark-util-types "^2.0.0" micromark-factory-title@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz#726140fc77892af524705d689e1cf06c8a83ea95" - integrity sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz#237e4aa5d58a95863f01032d9ee9b090f1de6e94" + integrity sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw== dependencies: micromark-factory-space "^2.0.0" micromark-util-character "^2.0.0" @@ -5780,9 +6012,9 @@ micromark-factory-title@^2.0.0: micromark-util-types "^2.0.0" micromark-factory-whitespace@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz#9e92eb0f5468083381f923d9653632b3cfb5f763" - integrity sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz#06b26b2983c4d27bfcc657b33e25134d4868b0b1" + integrity sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ== dependencies: micromark-factory-space "^2.0.0" micromark-util-character "^2.0.0" @@ -5798,48 +6030,48 @@ micromark-util-character@^1.0.0, micromark-util-character@^1.1.0: micromark-util-types "^1.0.0" micromark-util-character@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-2.1.0.tgz#31320ace16b4644316f6bf057531689c71e2aee1" - integrity sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ== + version "2.1.1" + resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-2.1.1.tgz#2f987831a40d4c510ac261e89852c4e9703ccda6" + integrity sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q== dependencies: micromark-util-symbol "^2.0.0" micromark-util-types "^2.0.0" micromark-util-chunked@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz#e51f4db85fb203a79dbfef23fd41b2f03dc2ef89" - integrity sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz#47fbcd93471a3fccab86cff03847fc3552db1051" + integrity sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA== dependencies: micromark-util-symbol "^2.0.0" micromark-util-classify-character@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz#8c7537c20d0750b12df31f86e976d1d951165f34" - integrity sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz#d399faf9c45ca14c8b4be98b1ea481bced87b629" + integrity sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q== dependencies: micromark-util-character "^2.0.0" micromark-util-symbol "^2.0.0" micromark-util-types "^2.0.0" micromark-util-combine-extensions@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz#75d6ab65c58b7403616db8d6b31315013bfb7ee5" - integrity sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz#2a0f490ab08bff5cc2fd5eec6dd0ca04f89b30a9" + integrity sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg== dependencies: micromark-util-chunked "^2.0.0" micromark-util-types "^2.0.0" micromark-util-decode-numeric-character-reference@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz#2698bbb38f2a9ba6310e359f99fcb2b35a0d2bd5" - integrity sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ== + version "2.0.2" + resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz#fcf15b660979388e6f118cdb6bf7d79d73d26fe5" + integrity sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw== dependencies: micromark-util-symbol "^2.0.0" micromark-util-decode-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz#7dfa3a63c45aecaa17824e656bcdb01f9737154a" - integrity sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz#6cb99582e5d271e84efca8e61a807994d7161eb2" + integrity sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ== dependencies: decode-named-character-reference "^1.0.0" micromark-util-character "^2.0.0" @@ -5847,9 +6079,9 @@ micromark-util-decode-string@^2.0.0: micromark-util-symbol "^2.0.0" micromark-util-encode@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz#0921ac7953dc3f1fd281e3d1932decfdb9382ab1" - integrity sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz#0d51d1c095551cfaac368326963cf55f15f540b8" + integrity sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw== micromark-util-events-to-acorn@^2.0.0: version "2.0.2" @@ -5866,37 +6098,37 @@ micromark-util-events-to-acorn@^2.0.0: vfile-message "^4.0.0" micromark-util-html-tag-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz#ae34b01cbe063363847670284c6255bb12138ec4" - integrity sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz#e40403096481986b41c106627f98f72d4d10b825" + integrity sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA== micromark-util-normalize-identifier@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz#91f9a4e65fe66cc80c53b35b0254ad67aa431d8b" - integrity sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz#c30d77b2e832acf6526f8bf1aa47bc9c9438c16d" + integrity sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q== dependencies: micromark-util-symbol "^2.0.0" micromark-util-resolve-all@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz#189656e7e1a53d0c86a38a652b284a252389f364" - integrity sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz#e1a2d62cdd237230a2ae11839027b19381e31e8b" + integrity sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg== dependencies: micromark-util-types "^2.0.0" micromark-util-sanitize-uri@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz#ec8fbf0258e9e6d8f13d9e4770f9be64342673de" - integrity sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz#ab89789b818a58752b73d6b55238621b7faa8fd7" + integrity sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ== dependencies: micromark-util-character "^2.0.0" micromark-util-encode "^2.0.0" micromark-util-symbol "^2.0.0" micromark-util-subtokenize@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz#76129c49ac65da6e479c09d0ec4b5f29ec6eace5" - integrity sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q== + version "2.0.3" + resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.3.tgz#70ffb99a454bd8c913c8b709c3dc97baefb65f96" + integrity sha512-VXJJuNxYWSoYL6AJ6OQECCFGhIU2GGHMw8tahogePBrjkG8aCCas3ibkp7RnVOSTClg2is05/R7maAhF1XyQMg== dependencies: devlop "^1.0.0" micromark-util-chunked "^2.0.0" @@ -5909,9 +6141,9 @@ micromark-util-symbol@^1.0.0, micromark-util-symbol@^1.0.1: integrity sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag== micromark-util-symbol@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz#12225c8f95edf8b17254e47080ce0862d5db8044" - integrity sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz#e5da494e8eb2b071a0d08fb34f6cefec6c0a19b8" + integrity sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q== micromark-util-types@^1.0.0: version "1.1.0" @@ -5919,14 +6151,14 @@ micromark-util-types@^1.0.0: integrity sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg== micromark-util-types@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-2.0.0.tgz#63b4b7ffeb35d3ecf50d1ca20e68fc7caa36d95e" - integrity sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w== + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-2.0.1.tgz#a3edfda3022c6c6b55bfb049ef5b75d70af50709" + integrity sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ== micromark@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/micromark/-/micromark-4.0.0.tgz#84746a249ebd904d9658cfabc1e8e5f32cbc6249" - integrity sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ== + version "4.0.1" + resolved "https://registry.yarnpkg.com/micromark/-/micromark-4.0.1.tgz#294c2f12364759e5f9e925a767ae3dfde72223ff" + integrity sha512-eBPdkcoCNvYcxQOAKAlceo5SNdzZWfF+FcSupREAzdAh9rRmE239CEQAiTwIgblwnoM8zzj35sZ5ZwvSEOF6Kw== dependencies: "@types/debug" "^4.0.0" debug "^4.0.0" @@ -6052,9 +6284,9 @@ multicast-dns@^7.2.5: thunky "^1.0.2" nanoid@^3.3.7: - version "3.3.7" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" - integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + version "3.3.8" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf" + integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w== negotiator@0.6.3: version "0.6.3" @@ -6080,9 +6312,9 @@ no-case@^3.0.4: tslib "^2.0.3" node-emoji@^2.1.0: - version "2.1.3" - resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-2.1.3.tgz#93cfabb5cc7c3653aa52f29d6ffb7927d8047c06" - integrity sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA== + version "2.2.0" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-2.2.0.tgz#1d000e3c76e462577895be1b436f4aa2d6760eb0" + integrity sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw== dependencies: "@sindresorhus/is" "^4.6.0" char-regex "^1.0.2" @@ -6094,10 +6326,10 @@ node-forge@^1: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== -node-releases@^2.0.18: - version "2.0.18" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" - integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== +node-releases@^2.0.19: + version "2.0.19" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" + integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -6146,10 +6378,10 @@ object-assign@^4.1.1: resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-inspect@^1.13.1: - version "1.13.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" - integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== +object-inspect@^1.13.3: + version "1.13.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.3.tgz#f14c183de51130243d6d18ae149375ff50ea488a" + integrity sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA== object-keys@^1.1.1: version "1.1.1" @@ -6157,13 +6389,15 @@ object-keys@^1.1.1: integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== object.assign@^4.1.0: - version "4.1.5" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" - integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== + version "4.1.7" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.7.tgz#8c14ca1a424c6a561b0bb2a22f66f5049a945d3d" + integrity sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw== dependencies: - call-bind "^1.0.5" + call-bind "^1.0.8" + call-bound "^1.0.3" define-properties "^1.2.1" - has-symbols "^1.0.3" + es-object-atoms "^1.0.0" + has-symbols "^1.1.0" object-keys "^1.1.1" obuf@^1.0.0, obuf@^1.1.2: @@ -6304,12 +6538,11 @@ parent-module@^1.0.0: callsites "^3.0.0" parse-entities@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-4.0.1.tgz#4e2a01111fb1c986549b944af39eeda258fc9e4e" - integrity sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w== + version "4.0.2" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-4.0.2.tgz#61d46f5ed28e4ee62e9ddc43d6b010188443f159" + integrity sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw== dependencies: "@types/unist" "^2.0.0" - character-entities "^2.0.0" character-entities-legacy "^3.0.0" character-reference-invalid "^2.0.0" decode-named-character-reference "^1.0.0" @@ -6395,10 +6628,10 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-to-regexp@0.1.10: - version "0.1.10" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b" - integrity sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w== +path-to-regexp@0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7" + integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== path-to-regexp@3.3.0: version "3.3.0" @@ -6417,7 +6650,7 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0: +picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0, picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== @@ -6441,6 +6674,13 @@ pkg-up@^3.1.0: dependencies: find-up "^3.0.0" +postcss-attribute-case-insensitive@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-7.0.1.tgz#0c4500e3bcb2141848e89382c05b5a31c23033a3" + integrity sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw== + dependencies: + postcss-selector-parser "^7.0.0" + postcss-calc@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-9.0.1.tgz#a744fd592438a93d6de0f1434c572670361eb6c6" @@ -6449,6 +6689,40 @@ postcss-calc@^9.0.1: postcss-selector-parser "^6.0.11" postcss-value-parser "^4.2.0" +postcss-clamp@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-clamp/-/postcss-clamp-4.1.0.tgz#7263e95abadd8c2ba1bd911b0b5a5c9c93e02363" + integrity sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-functional-notation@^7.0.7: + version "7.0.7" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.7.tgz#c5362df010926f902ce4e7fb3da2a46cff175d1b" + integrity sha512-EZvAHsvyASX63vXnyXOIynkxhaHRSsdb7z6yiXKIovGXAolW4cMZ3qoh7k3VdTsLBS6VGdksGfIo3r6+waLoOw== + dependencies: + "@csstools/css-color-parser" "^3.0.7" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/utilities" "^2.0.0" + +postcss-color-hex-alpha@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-10.0.0.tgz#5dd3eba1f8facb4ea306cba6e3f7712e876b0c76" + integrity sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w== + dependencies: + "@csstools/utilities" "^2.0.0" + postcss-value-parser "^4.2.0" + +postcss-color-rebeccapurple@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-10.0.0.tgz#5ada28406ac47e0796dff4056b0a9d5a6ecead98" + integrity sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ== + dependencies: + "@csstools/utilities" "^2.0.0" + postcss-value-parser "^4.2.0" + postcss-colormin@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-6.1.0.tgz#076e8d3fb291fbff7b10e6b063be9da42ff6488d" @@ -6467,6 +6741,44 @@ postcss-convert-values@^6.1.0: browserslist "^4.23.0" postcss-value-parser "^4.2.0" +postcss-custom-media@^11.0.5: + version "11.0.5" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-11.0.5.tgz#2fcd88a9b1d4da41c67dac6f2def903063a3377d" + integrity sha512-SQHhayVNgDvSAdX9NQ/ygcDQGEY+aSF4b/96z7QUX6mqL5yl/JgG/DywcF6fW9XbnCRE+aVYk+9/nqGuzOPWeQ== + dependencies: + "@csstools/cascade-layer-name-parser" "^2.0.4" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + "@csstools/media-query-list-parser" "^4.0.2" + +postcss-custom-properties@^14.0.4: + version "14.0.4" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-14.0.4.tgz#de9c663285a98833a946d7003a34369d3ce373a9" + integrity sha512-QnW8FCCK6q+4ierwjnmXF9Y9KF8q0JkbgVfvQEMa93x1GT8FvOiUevWCN2YLaOWyByeDX8S6VFbZEeWoAoXs2A== + dependencies: + "@csstools/cascade-layer-name-parser" "^2.0.4" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + "@csstools/utilities" "^2.0.0" + postcss-value-parser "^4.2.0" + +postcss-custom-selectors@^8.0.4: + version "8.0.4" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-8.0.4.tgz#95ef8268fdbbbd84f34cf84a4517c9d99d419c5a" + integrity sha512-ASOXqNvDCE0dAJ/5qixxPeL1aOVGHGW2JwSy7HyjWNbnWTQCl+fDc968HY1jCmZI0+BaYT5CxsOiUhavpG/7eg== + dependencies: + "@csstools/cascade-layer-name-parser" "^2.0.4" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + postcss-selector-parser "^7.0.0" + +postcss-dir-pseudo-class@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-9.0.1.tgz#80d9e842c9ae9d29f6bf5fd3cf9972891d6cc0ca" + integrity sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA== + dependencies: + postcss-selector-parser "^7.0.0" + postcss-discard-comments@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz#e768dcfdc33e0216380623652b0a4f69f4678b6c" @@ -6494,6 +6806,58 @@ postcss-discard-unused@^6.0.5: dependencies: postcss-selector-parser "^6.0.16" +postcss-double-position-gradients@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.0.tgz#eddd424ec754bb543d057d4d2180b1848095d4d2" + integrity sha512-JkIGah3RVbdSEIrcobqj4Gzq0h53GG4uqDPsho88SgY84WnpkTpI0k50MFK/sX7XqVisZ6OqUfFnoUO6m1WWdg== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/utilities" "^2.0.0" + postcss-value-parser "^4.2.0" + +postcss-focus-visible@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-10.0.1.tgz#1f7904904368a2d1180b220595d77b6f8a957868" + integrity sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA== + dependencies: + postcss-selector-parser "^7.0.0" + +postcss-focus-within@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-9.0.1.tgz#ac01ce80d3f2e8b2b3eac4ff84f8e15cd0057bc7" + integrity sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw== + dependencies: + postcss-selector-parser "^7.0.0" + +postcss-font-variant@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz#efd59b4b7ea8bb06127f2d031bfbb7f24d32fa66" + integrity sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA== + +postcss-gap-properties@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-6.0.0.tgz#d5ff0bdf923c06686499ed2b12e125fe64054fed" + integrity sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw== + +postcss-image-set-function@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-7.0.0.tgz#538e94e16716be47f9df0573b56bbaca86e1da53" + integrity sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA== + dependencies: + "@csstools/utilities" "^2.0.0" + postcss-value-parser "^4.2.0" + +postcss-lab-function@^7.0.7: + version "7.0.7" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-7.0.7.tgz#9c87c21ce5132c55824190b75d7d7adede9c2fac" + integrity sha512-+ONj2bpOQfsCKZE2T9VGMyVVdGcGUpr7u3SVfvkJlvhTRmDCfY25k4Jc8fubB9DclAPR4+w8uVtDZmdRgdAHig== + dependencies: + "@csstools/css-color-parser" "^3.0.7" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/utilities" "^2.0.0" + postcss-loader@^7.3.3: version "7.3.4" resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-7.3.4.tgz#aed9b79ce4ed7e9e89e56199d25ad1ec8f606209" @@ -6503,6 +6867,13 @@ postcss-loader@^7.3.3: jiti "^1.20.0" semver "^7.5.4" +postcss-logical@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-8.0.0.tgz#0db0b90c2dc53b485a8074a4b7a906297544f58d" + integrity sha512-HpIdsdieClTjXLOyYdUPAX/XQASNIwdKt5hoZW08ZOAiI+tbV0ta1oclkpVkW5ANU+xJvk3KkA0FejkjGLXUkg== + dependencies: + postcss-value-parser "^4.2.0" + postcss-merge-idents@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz#7b9c31c7bc823c94bec50f297f04e3c2b838ea65" @@ -6567,20 +6938,20 @@ postcss-modules-extract-imports@^3.1.0: integrity sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q== postcss-modules-local-by-default@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz#f1b9bd757a8edf4d8556e8d0f4f894260e3df78f" - integrity sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw== + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz#d150f43837831dae25e4085596e84f6f5d6ec368" + integrity sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw== dependencies: icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" + postcss-selector-parser "^7.0.0" postcss-value-parser "^4.1.0" postcss-modules-scope@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz#a43d28289a169ce2c15c00c4e64c0858e43457d5" - integrity sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ== + version "3.2.1" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz#1bbccddcb398f1d7a511e0a2d1d047718af4078c" + integrity sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA== dependencies: - postcss-selector-parser "^6.0.4" + postcss-selector-parser "^7.0.0" postcss-modules-values@^4.0.0: version "4.0.0" @@ -6589,6 +6960,15 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" +postcss-nesting@^13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-13.0.1.tgz#c405796d7245a3e4c267a9956cacfe9670b5d43e" + integrity sha512-VbqqHkOBOt4Uu3G8Dm8n6lU5+9cJFxiuty9+4rcoyRPO9zZS1JIs6td49VIoix3qYqELHlJIn46Oih9SAKo+yQ== + dependencies: + "@csstools/selector-resolve-nested" "^3.0.0" + "@csstools/selector-specificity" "^5.0.0" + postcss-selector-parser "^7.0.0" + postcss-normalize-charset@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz#1ec25c435057a8001dac942942a95ffe66f721e1" @@ -6651,6 +7031,11 @@ postcss-normalize-whitespace@^6.0.2: dependencies: postcss-value-parser "^4.2.0" +postcss-opacity-percentage@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-opacity-percentage/-/postcss-opacity-percentage-3.0.0.tgz#0b0db5ed5db5670e067044b8030b89c216e1eb0a" + integrity sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ== + postcss-ordered-values@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz#366bb663919707093451ab70c3f99c05672aaae5" @@ -6659,6 +7044,101 @@ postcss-ordered-values@^6.0.2: cssnano-utils "^4.0.2" postcss-value-parser "^4.2.0" +postcss-overflow-shorthand@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-6.0.0.tgz#f5252b4a2ee16c68cd8a9029edb5370c4a9808af" + integrity sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-page-break@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-3.0.4.tgz#7fbf741c233621622b68d435babfb70dd8c1ee5f" + integrity sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ== + +postcss-place@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-10.0.0.tgz#ba36ee4786ca401377ced17a39d9050ed772e5a9" + integrity sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-preset-env@^10.1.0: + version "10.1.3" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-10.1.3.tgz#7d07adef2237a643162e751b00eb1e339aa3b82e" + integrity sha512-9qzVhcMFU/MnwYHyYpJz4JhGku/4+xEiPTmhn0hj3IxnUYlEF9vbh7OC1KoLAnenS6Fgg43TKNp9xcuMeAi4Zw== + dependencies: + "@csstools/postcss-cascade-layers" "^5.0.1" + "@csstools/postcss-color-function" "^4.0.7" + "@csstools/postcss-color-mix-function" "^3.0.7" + "@csstools/postcss-content-alt-text" "^2.0.4" + "@csstools/postcss-exponential-functions" "^2.0.6" + "@csstools/postcss-font-format-keywords" "^4.0.0" + "@csstools/postcss-gamut-mapping" "^2.0.7" + "@csstools/postcss-gradients-interpolation-method" "^5.0.7" + "@csstools/postcss-hwb-function" "^4.0.7" + "@csstools/postcss-ic-unit" "^4.0.0" + "@csstools/postcss-initial" "^2.0.0" + "@csstools/postcss-is-pseudo-class" "^5.0.1" + "@csstools/postcss-light-dark-function" "^2.0.7" + "@csstools/postcss-logical-float-and-clear" "^3.0.0" + "@csstools/postcss-logical-overflow" "^2.0.0" + "@csstools/postcss-logical-overscroll-behavior" "^2.0.0" + "@csstools/postcss-logical-resize" "^3.0.0" + "@csstools/postcss-logical-viewport-units" "^3.0.3" + "@csstools/postcss-media-minmax" "^2.0.6" + "@csstools/postcss-media-queries-aspect-ratio-number-values" "^3.0.4" + "@csstools/postcss-nested-calc" "^4.0.0" + "@csstools/postcss-normalize-display-values" "^4.0.0" + "@csstools/postcss-oklab-function" "^4.0.7" + "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/postcss-random-function" "^1.0.2" + "@csstools/postcss-relative-color-syntax" "^3.0.7" + "@csstools/postcss-scope-pseudo-class" "^4.0.1" + "@csstools/postcss-sign-functions" "^1.1.1" + "@csstools/postcss-stepped-value-functions" "^4.0.6" + "@csstools/postcss-text-decoration-shorthand" "^4.0.1" + "@csstools/postcss-trigonometric-functions" "^4.0.6" + "@csstools/postcss-unset-value" "^4.0.0" + autoprefixer "^10.4.19" + browserslist "^4.23.1" + css-blank-pseudo "^7.0.1" + css-has-pseudo "^7.0.2" + css-prefers-color-scheme "^10.0.0" + cssdb "^8.2.3" + postcss-attribute-case-insensitive "^7.0.1" + postcss-clamp "^4.1.0" + postcss-color-functional-notation "^7.0.7" + postcss-color-hex-alpha "^10.0.0" + postcss-color-rebeccapurple "^10.0.0" + postcss-custom-media "^11.0.5" + postcss-custom-properties "^14.0.4" + postcss-custom-selectors "^8.0.4" + postcss-dir-pseudo-class "^9.0.1" + postcss-double-position-gradients "^6.0.0" + postcss-focus-visible "^10.0.1" + postcss-focus-within "^9.0.1" + postcss-font-variant "^5.0.0" + postcss-gap-properties "^6.0.0" + postcss-image-set-function "^7.0.0" + postcss-lab-function "^7.0.7" + postcss-logical "^8.0.0" + postcss-nesting "^13.0.1" + postcss-opacity-percentage "^3.0.0" + postcss-overflow-shorthand "^6.0.0" + postcss-page-break "^3.0.4" + postcss-place "^10.0.0" + postcss-pseudo-class-any-link "^10.0.1" + postcss-replace-overflow-wrap "^4.0.0" + postcss-selector-not "^8.0.1" + +postcss-pseudo-class-any-link@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-10.0.1.tgz#06455431171bf44b84d79ebaeee9fd1c05946544" + integrity sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q== + dependencies: + postcss-selector-parser "^7.0.0" + postcss-reduce-idents@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz#b0d9c84316d2a547714ebab523ec7d13704cd486" @@ -6681,7 +7161,19 @@ postcss-reduce-transforms@^6.0.2: dependencies: postcss-value-parser "^4.2.0" -postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.16, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: +postcss-replace-overflow-wrap@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz#d2df6bed10b477bf9c52fab28c568b4b29ca4319" + integrity sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw== + +postcss-selector-not@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-8.0.1.tgz#f2df9c6ac9f95e9fe4416ca41a957eda16130172" + integrity sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA== + dependencies: + postcss-selector-parser "^7.0.0" + +postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.16: version "6.1.2" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de" integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== @@ -6689,6 +7181,14 @@ postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.16, postcss-select cssesc "^3.0.0" util-deprecate "^1.0.2" +postcss-selector-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz#41bd8b56f177c093ca49435f65731befe25d6b9c" + integrity sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + postcss-sort-media-queries@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz#4556b3f982ef27d3bac526b99b6c0d3359a6cf97" @@ -6722,12 +7222,12 @@ postcss-zindex@^6.0.2: integrity sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg== postcss@^8.4.21, postcss@^8.4.24, postcss@^8.4.26, postcss@^8.4.33, postcss@^8.4.38: - version "8.4.47" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" - integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ== + version "8.4.49" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19" + integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA== dependencies: nanoid "^3.3.7" - picocolors "^1.1.0" + picocolors "^1.1.1" source-map-js "^1.2.1" pretty-error@^4.0.0: @@ -6744,9 +7244,9 @@ pretty-time@^1.1.0: integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA== prism-react-renderer@^2.3.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-2.4.0.tgz#c5ea692029c2f8b3fd04f63662d04ffd4eaf10a0" - integrity sha512-327BsVCD/unU4CNLZTWVHyUHKnsqcvj2qbPlQ8MiBE2eq2rgctjigPA1Gp9HLF83kZ20zNN6jgizHJeEsyFYOw== + version "2.4.1" + resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-2.4.1.tgz#ac63b7f78e56c8f2b5e76e823a976d5ede77e35f" + integrity sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig== dependencies: "@types/prismjs" "^1.26.0" clsx "^2.0.0" @@ -6899,37 +7399,27 @@ react-dev-utils@^12.0.1: strip-ansi "^6.0.1" text-table "^0.2.0" -react-dom@^18.0.0: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" - integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== +react-dom@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.0.0.tgz#43446f1f01c65a4cd7f7588083e686a6726cfb57" + integrity sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ== dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.2" + scheduler "^0.25.0" react-error-overlay@^6.0.11: version "6.0.11" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb" integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== -react-fast-compare@^3.2.0, react-fast-compare@^3.2.2: +react-fast-compare@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== -react-helmet-async@*: - version "2.0.5" - resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-2.0.5.tgz#cfc70cd7bb32df7883a8ed55502a1513747223ec" - integrity sha512-rYUYHeus+i27MvFE+Jaa4WsyBKGkL6qVgbJvSBoX8mbsWoABJXdEO0bZyi0F6i+4f0NuIb8AvqPMj3iXFHkMwg== - dependencies: - invariant "^2.2.4" - react-fast-compare "^3.2.2" - shallowequal "^1.1.0" - -react-helmet-async@^1.3.0: +"react-helmet-async@npm:@slorber/react-helmet-async@*", "react-helmet-async@npm:@slorber/react-helmet-async@1.3.0": version "1.3.0" - resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-1.3.0.tgz#7bd5bf8c5c69ea9f02f6083f14ce33ef545c222e" - integrity sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg== + resolved "https://registry.yarnpkg.com/@slorber/react-helmet-async/-/react-helmet-async-1.3.0.tgz#11fbc6094605cf60aa04a28c17e0aab894b4ecff" + integrity sha512-e9/OK8VhwUSc67diWI8Rb3I0YgI9/SBQtnhe9aEuK6MhZm7ntZZimXgwXnd8W96YTmSOb9M4d8LwhRZyhWr/1A== dependencies: "@babel/runtime" "^7.12.5" invariant "^2.2.4" @@ -6996,12 +7486,10 @@ react-router@5.3.4, react-router@^5.3.4: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react@^18.0.0: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" - integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== - dependencies: - loose-envify "^1.1.0" +react@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/react/-/react-19.0.0.tgz#6e1969251b9f108870aa4bff37a0ce9ddfaaabdd" + integrity sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ== readable-stream@^2.0.1: version "2.3.8" @@ -7115,22 +7603,22 @@ regenerator-transform@^0.15.2: dependencies: "@babel/runtime" "^7.8.4" -regexpu-core@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.1.1.tgz#b469b245594cb2d088ceebc6369dceb8c00becac" - integrity sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw== +regexpu-core@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.2.0.tgz#0e5190d79e542bf294955dccabae04d3c7d53826" + integrity sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA== dependencies: regenerate "^1.4.2" regenerate-unicode-properties "^10.2.0" regjsgen "^0.8.0" - regjsparser "^0.11.0" + regjsparser "^0.12.0" unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.1.0" registry-auth-token@^5.0.1: - version "5.0.2" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-5.0.2.tgz#8b026cc507c8552ebbe06724136267e63302f756" - integrity sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ== + version "5.0.3" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-5.0.3.tgz#417d758c8164569de8cf5cabff16cc937902dcc6" + integrity sha512-1bpc9IyC+e+CNFRaWyn77tk4xGG4PPUyfakSmA6F6cvUDjrm58dfyJ3II+9yb10EDkHoy1LaPSmHaWLOH3m6HA== dependencies: "@pnpm/npm-conf" "^2.1.0" @@ -7146,10 +7634,10 @@ regjsgen@^0.8.0: resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.8.0.tgz#df23ff26e0c5b300a6470cad160a9d090c3a37ab" integrity sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q== -regjsparser@^0.11.0: - version "0.11.2" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.11.2.tgz#7404ad42be00226d72bcf1f003f1f441861913d8" - integrity sha512-3OGZZ4HoLJkkAZx/48mTXJNlmqTGOzc0o9OWQPuWpkOlXXPbyN6OafCcoXUnBqE2D3f/T5L+pWc1kdEmnfnRsA== +regjsparser@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.12.0.tgz#0e846df6c6530586429377de56e0475583b088dc" + integrity sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ== dependencies: jsesc "~3.0.2" @@ -7304,11 +7792,11 @@ resolve-pathname@^3.0.0: integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== resolve@^1.1.6, resolve@^1.14.2: - version "1.22.8" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" - integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + version "1.22.10" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" + integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== dependencies: - is-core-module "^2.13.0" + is-core-module "^2.16.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -7336,11 +7824,6 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -rtl-detect@^1.0.4: - version "1.1.2" - resolved "https://registry.yarnpkg.com/rtl-detect/-/rtl-detect-1.1.2.tgz#ca7f0330af5c6bb626c15675c642ba85ad6273c6" - integrity sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ== - rtlcss@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/rtlcss/-/rtlcss-4.3.0.tgz#f8efd4d5b64f640ec4af8fa25b65bacd9e07cc97" @@ -7378,12 +7861,10 @@ sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.1.tgz#44cc8988377f126304d3b3fc1010c733b929ef0f" integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg== -scheduler@^0.23.2: - version "0.23.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" - integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== - dependencies: - loose-envify "^1.1.0" +scheduler@^0.25.0: + version "0.25.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.25.0.tgz#336cd9768e8cceebf52d3c80e3dcf5de23e7e015" + integrity sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA== schema-utils@2.7.0: version "2.7.0" @@ -7394,7 +7875,7 @@ schema-utils@2.7.0: ajv "^6.12.2" ajv-keywords "^3.4.1" -schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: +schema-utils@^3.0.0, schema-utils@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== @@ -7403,10 +7884,10 @@ schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: ajv "^6.12.5" ajv-keywords "^3.5.2" -schema-utils@^4.0.0, schema-utils@^4.0.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" - integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw== +schema-utils@^4.0.0, schema-utils@^4.0.1, schema-utils@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.0.tgz#3b669f04f71ff2dfb5aba7ce2d5a9d79b35622c0" + integrity sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g== dependencies: "@types/json-schema" "^7.0.9" ajv "^8.9.0" @@ -7470,7 +7951,7 @@ send@0.19.0: range-parser "~1.2.1" statuses "2.0.1" -serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: +serialize-javascript@^6.0.0, serialize-javascript@^6.0.1, serialize-javascript@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== @@ -7513,7 +7994,7 @@ serve-static@1.16.2: parseurl "~1.3.3" send "0.19.0" -set-function-length@^1.2.1: +set-function-length@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== @@ -7560,9 +8041,9 @@ shebang-regex@^3.0.0: integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@^1.7.3, shell-quote@^1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" - integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== + version "1.8.2" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.2.tgz#d2d83e057959d53ec261311e9e9b8f51dcb2934a" + integrity sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA== shelljs@^0.8.5: version "0.8.5" @@ -7573,15 +8054,45 @@ shelljs@^0.8.5: interpret "^1.0.0" rechoir "^0.6.2" -side-channel@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" - integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== +side-channel-list@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" + integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== dependencies: - call-bind "^1.0.7" es-errors "^1.3.0" - get-intrinsic "^1.2.4" - object-inspect "^1.13.1" + object-inspect "^1.13.3" + +side-channel-map@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" + integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + +side-channel-weakmap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" + integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + side-channel-map "^1.0.1" + +side-channel@^1.0.6: + version "1.1.0" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" + integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.3" + side-channel-list "^1.0.0" + side-channel-map "^1.0.1" + side-channel-weakmap "^1.0.2" signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.7" @@ -7723,9 +8234,9 @@ statuses@2.0.1: integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== std-env@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.7.0.tgz#c9f7386ced6ecf13360b6c6c55b8aaa4ef7481d2" - integrity sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg== + version "3.8.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.8.0.tgz#b56ffc1baf1a29dcc80a3bdf11d7fca7c315e7d5" + integrity sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w== string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" @@ -7810,13 +8321,6 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== -style-to-object@^0.4.0: - version "0.4.4" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.4.tgz#266e3dfd56391a7eefb7770423612d043c3f33ec" - integrity sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg== - dependencies: - inline-style-parser "0.1.1" - style-to-object@^1.0.0: version "1.0.8" resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-1.0.8.tgz#67a29bca47eaa587db18118d68f9d95955e81292" @@ -7880,20 +8384,20 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== terser-webpack-plugin@^5.3.10, terser-webpack-plugin@^5.3.9: - version "5.3.10" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" - integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== + version "5.3.11" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz#93c21f44ca86634257cac176f884f942b7ba3832" + integrity sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ== dependencies: - "@jridgewell/trace-mapping" "^0.3.20" + "@jridgewell/trace-mapping" "^0.3.25" jest-worker "^27.4.5" - schema-utils "^3.1.1" - serialize-javascript "^6.0.1" - terser "^5.26.0" + schema-utils "^4.3.0" + serialize-javascript "^6.0.2" + terser "^5.31.1" -terser@^5.10.0, terser@^5.15.1, terser@^5.26.0: - version "5.36.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.36.0.tgz#8b0dbed459ac40ff7b4c9fd5a3a2029de105180e" - integrity sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w== +terser@^5.10.0, terser@^5.15.1, terser@^5.31.1: + version "5.37.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.37.0.tgz#38aa66d1cfc43d0638fab54e43ff8a4f72a21ba3" + integrity sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -7982,10 +8486,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -undici-types@~6.19.8: - version "6.19.8" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" - integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== +undici-types@~6.20.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433" + integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg== unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.1" @@ -8302,15 +8806,15 @@ webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5.88.1, webpack@^5.95.0: - version "5.96.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.96.1.tgz#3676d1626d8312b6b10d0c18cc049fba7ac01f0c" - integrity sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA== + version "5.97.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.97.1.tgz#972a8320a438b56ff0f1d94ade9e82eac155fa58" + integrity sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg== dependencies: "@types/eslint-scope" "^3.7.7" "@types/estree" "^1.0.6" - "@webassemblyjs/ast" "^1.12.1" - "@webassemblyjs/wasm-edit" "^1.12.1" - "@webassemblyjs/wasm-parser" "^1.12.1" + "@webassemblyjs/ast" "^1.14.1" + "@webassemblyjs/wasm-edit" "^1.14.1" + "@webassemblyjs/wasm-parser" "^1.14.1" acorn "^8.14.0" browserslist "^4.24.0" chrome-trace-event "^1.0.2" diff --git a/lerna.json b/lerna.json index 02c4922b17..522fca1495 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "3.6.2", + "version": "3.7.0", "npmClient": "yarn", "useWorkspaces": true, "useNx": false, diff --git a/package.json b/package.json index 5f5385c56d..457201472b 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "canary:bumpVersion": "yarn lerna version `yarn --silent canary:version` --exact --no-push --yes", "canary:publish": "yarn lerna publish from-package --dist-tag canary --yes --no-verify-access", "changelog": "lerna-changelog", - "postinstall": "yarn lock:update && yarn build:packages", + "postinstall": "patch-package && yarn lock:update && yarn build:packages", "prepare": "husky install", "format": "prettier --write .", "format:diff": "prettier --list-different .", @@ -112,10 +112,11 @@ "lint-staged": "~13.2.3", "lockfile-lint": "^4.14.0", "npm-run-all": "^4.1.5", + "patch-package": "^8.0.0", + "postinstall-postinstall": "^2.1.0", "prettier": "^2.8.8", "react": "^18.0.0", "react-dom": "^18.0.0", - "react-helmet-async": "^1.3.0", "react-test-renderer": "^18.0.0", "rimraf": "^3.0.2", "sharp": "^0.32.3", @@ -123,6 +124,7 @@ "stylelint": "^14.16.1", "stylelint-config-prettier": "^9.0.5", "stylelint-config-standard": "^29.0.0", - "typescript": "~5.6.2" - } + "typescript": "~5.7.2" + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/packages/create-docusaurus/package.json b/packages/create-docusaurus/package.json index eef80b30bc..3d1399ae1d 100755 --- a/packages/create-docusaurus/package.json +++ b/packages/create-docusaurus/package.json @@ -1,6 +1,6 @@ { "name": "create-docusaurus", - "version": "3.6.2", + "version": "3.7.0", "description": "Create Docusaurus apps easily.", "type": "module", "repository": { @@ -22,8 +22,8 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/logger": "3.6.2", - "@docusaurus/utils": "3.6.2", + "@docusaurus/logger": "3.7.0", + "@docusaurus/utils": "3.7.0", "commander": "^5.1.0", "fs-extra": "^11.1.1", "lodash": "^4.17.21", diff --git a/packages/create-docusaurus/templates/classic-typescript/docusaurus.config.ts b/packages/create-docusaurus/templates/classic-typescript/docusaurus.config.ts index 344c456720..95cb36ccd7 100644 --- a/packages/create-docusaurus/templates/classic-typescript/docusaurus.config.ts +++ b/packages/create-docusaurus/templates/classic-typescript/docusaurus.config.ts @@ -9,6 +9,11 @@ const config: Config = { tagline: 'Dinosaurs are cool', favicon: 'img/favicon.ico', + // Future flags, see https://docusaurus.io/docs/api/docusaurus-config#future + future: { + v4: true, // Improve compatibility with the upcoming Docusaurus v4 + }, + // Set the production url of your site here url: 'https://your-docusaurus-site.example.com', // Set the // pathname under which your site is served diff --git a/packages/create-docusaurus/templates/classic-typescript/package.json b/packages/create-docusaurus/templates/classic-typescript/package.json index 5e942bb1ed..ef3910ac2b 100644 --- a/packages/create-docusaurus/templates/classic-typescript/package.json +++ b/packages/create-docusaurus/templates/classic-typescript/package.json @@ -1,6 +1,6 @@ { "name": "docusaurus-2-classic-typescript-template", - "version": "3.6.2", + "version": "3.7.0", "private": true, "scripts": { "docusaurus": "docusaurus", @@ -15,18 +15,18 @@ "typecheck": "tsc" }, "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/preset-classic": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/preset-classic": "3.7.0", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^19.0.0", + "react-dom": "^19.0.0" }, "devDependencies": { - "@docusaurus/module-type-aliases": "3.6.2", - "@docusaurus/tsconfig": "3.6.2", - "@docusaurus/types": "3.6.2", + "@docusaurus/module-type-aliases": "3.7.0", + "@docusaurus/tsconfig": "3.7.0", + "@docusaurus/types": "3.7.0", "typescript": "~5.6.2" }, "browserslist": { diff --git a/packages/create-docusaurus/templates/classic-typescript/src/components/HomepageFeatures/index.tsx b/packages/create-docusaurus/templates/classic-typescript/src/components/HomepageFeatures/index.tsx index 50a9e6f4c7..c2551fb9b8 100644 --- a/packages/create-docusaurus/templates/classic-typescript/src/components/HomepageFeatures/index.tsx +++ b/packages/create-docusaurus/templates/classic-typescript/src/components/HomepageFeatures/index.tsx @@ -1,3 +1,4 @@ +import type {ReactNode} from 'react'; import clsx from 'clsx'; import Heading from '@theme/Heading'; import styles from './styles.module.css'; @@ -5,7 +6,7 @@ import styles from './styles.module.css'; type FeatureItem = { title: string; Svg: React.ComponentType>; - description: JSX.Element; + description: ReactNode; }; const FeatureList: FeatureItem[] = [ @@ -55,7 +56,7 @@ function Feature({title, Svg, description}: FeatureItem) { ); } -export default function HomepageFeatures(): JSX.Element { +export default function HomepageFeatures(): ReactNode { return (
diff --git a/packages/create-docusaurus/templates/classic-typescript/src/pages/index.tsx b/packages/create-docusaurus/templates/classic-typescript/src/pages/index.tsx index 400a3e19a8..2e006d153b 100644 --- a/packages/create-docusaurus/templates/classic-typescript/src/pages/index.tsx +++ b/packages/create-docusaurus/templates/classic-typescript/src/pages/index.tsx @@ -1,3 +1,4 @@ +import type {ReactNode} from 'react'; import clsx from 'clsx'; import Link from '@docusaurus/Link'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; @@ -28,7 +29,7 @@ function HomepageHeader() { ); } -export default function Home(): JSX.Element { +export default function Home(): ReactNode { const {siteConfig} = useDocusaurusContext(); return ( / pathname under which your site is served diff --git a/packages/create-docusaurus/templates/classic/package.json b/packages/create-docusaurus/templates/classic/package.json index fd0f320fa9..0d00157488 100644 --- a/packages/create-docusaurus/templates/classic/package.json +++ b/packages/create-docusaurus/templates/classic/package.json @@ -1,6 +1,6 @@ { "name": "docusaurus-2-classic-template", - "version": "3.6.2", + "version": "3.7.0", "private": true, "scripts": { "docusaurus": "docusaurus", @@ -14,17 +14,17 @@ "write-heading-ids": "docusaurus write-heading-ids" }, "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/preset-classic": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/preset-classic": "3.7.0", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^19.0.0", + "react-dom": "^19.0.0" }, "devDependencies": { - "@docusaurus/module-type-aliases": "3.6.2", - "@docusaurus/types": "3.6.2" + "@docusaurus/module-type-aliases": "3.7.0", + "@docusaurus/types": "3.7.0" }, "browserslist": { "production": [ diff --git a/packages/create-docusaurus/templates/shared/README.md b/packages/create-docusaurus/templates/shared/README.md index 0c6c2c27be..35ad92cc2a 100644 --- a/packages/create-docusaurus/templates/shared/README.md +++ b/packages/create-docusaurus/templates/shared/README.md @@ -4,13 +4,13 @@ This website is built using [Docusaurus](https://docusaurus.io/), a modern stati ### Installation -``` +```bash $ yarn ``` ### Local Development -``` +```bash $ yarn start ``` @@ -18,7 +18,7 @@ This command starts a local development server and opens up a browser window. Mo ### Build -``` +```bash $ yarn build ``` @@ -28,13 +28,13 @@ This command generates static content into the `build` directory and can be serv Using SSH: -``` +```bash $ USE_SSH=true yarn deploy ``` Not using SSH: -``` +```bash $ GIT_USER= yarn deploy ``` diff --git a/packages/create-docusaurus/templates/shared/blog/authors.yml b/packages/create-docusaurus/templates/shared/blog/authors.yml index 8bfa5c7c4b..0fd398733b 100644 --- a/packages/create-docusaurus/templates/shared/blog/authors.yml +++ b/packages/create-docusaurus/templates/shared/blog/authors.yml @@ -1,12 +1,14 @@ yangshun: name: Yangshun Tay - title: Front End Engineer @ Facebook - url: https://github.com/yangshun + title: Ex-Meta Staff Engineer, Co-founder GreatFrontEnd + url: https://linkedin.com/in/yangshun image_url: https://github.com/yangshun.png page: true socials: x: yangshunz + linkedin: yangshun github: yangshun + newsletter: https://www.greatfrontend.com slorber: name: Sébastien Lorber diff --git a/packages/docusaurus-babel/package.json b/packages/docusaurus-babel/package.json index 470477cd04..2e03c6a502 100644 --- a/packages/docusaurus-babel/package.json +++ b/packages/docusaurus-babel/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/babel", - "version": "3.6.2", + "version": "3.7.0", "description": "Docusaurus package for Babel-related utils.", "main": "./lib/index.js", "types": "./lib/index.d.ts", @@ -38,8 +38,8 @@ "@babel/runtime": "^7.25.9", "@babel/runtime-corejs3": "^7.25.9", "@babel/traverse": "^7.25.9", - "@docusaurus/logger": "3.6.2", - "@docusaurus/utils": "3.6.2", + "@docusaurus/logger": "3.7.0", + "@docusaurus/utils": "3.7.0", "babel-plugin-dynamic-import-node": "^2.3.3", "fs-extra": "^11.1.1", "tslib": "^2.6.0" diff --git a/packages/docusaurus-bundler/package.json b/packages/docusaurus-bundler/package.json index 55a5294100..80b6cf91ce 100644 --- a/packages/docusaurus-bundler/package.json +++ b/packages/docusaurus-bundler/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/bundler", - "version": "3.6.2", + "version": "3.7.0", "description": "Docusaurus util package to abstract the current bundler.", "main": "./lib/index.js", "types": "./lib/index.d.ts", @@ -19,11 +19,11 @@ "license": "MIT", "dependencies": { "@babel/core": "^7.25.9", - "@docusaurus/babel": "3.6.2", - "@docusaurus/cssnano-preset": "3.6.2", - "@docusaurus/logger": "3.6.2", - "@docusaurus/types": "3.6.2", - "@docusaurus/utils": "3.6.2", + "@docusaurus/babel": "3.7.0", + "@docusaurus/cssnano-preset": "3.7.0", + "@docusaurus/logger": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils": "3.7.0", "babel-loader": "^9.2.1", "clean-css": "^5.3.2", "copy-webpack-plugin": "^11.0.0", diff --git a/packages/docusaurus-bundler/src/minifyHtml.ts b/packages/docusaurus-bundler/src/minifyHtml.ts index 4a029d83c1..d9dc29135f 100644 --- a/packages/docusaurus-bundler/src/minifyHtml.ts +++ b/packages/docusaurus-bundler/src/minifyHtml.ts @@ -47,9 +47,13 @@ async function getTerserMinifier(): Promise { minify: async function minifyHtmlWithTerser(html) { try { const code = await terserHtmlMinifier(html, { + // When enabled => React hydration errors removeComments: false, - removeRedundantAttributes: true, - removeEmptyAttributes: true, + removeRedundantAttributes: false, + removeEmptyAttributes: false, + sortAttributes: false, + sortClassName: false, + removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true, useShortDoctype: true, @@ -84,8 +88,13 @@ async function getSwcMinifier(): Promise { sortSpaceSeparatedAttributeValues: false, sortAttributes: false, - removeRedundantAttributes: 'all', - removeEmptyAttributes: true, + // When enabled => hydration error for className={"yt-lite "} + normalizeAttributes: false, + // When enabled => hydration error for className="" + removeEmptyAttributes: false, + // When enabled => hydration error for + removeRedundantAttributes: 'none', + minifyJs: true, minifyJson: true, minifyCss: true, diff --git a/packages/docusaurus-cssnano-preset/package.json b/packages/docusaurus-cssnano-preset/package.json index 825ed1e05d..e78e45c54c 100644 --- a/packages/docusaurus-cssnano-preset/package.json +++ b/packages/docusaurus-cssnano-preset/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/cssnano-preset", - "version": "3.6.2", + "version": "3.7.0", "description": "Advanced cssnano preset for maximum optimization.", "main": "lib/index.js", "license": "MIT", diff --git a/packages/docusaurus-faster/package.json b/packages/docusaurus-faster/package.json index 616ba22702..cd99577359 100644 --- a/packages/docusaurus-faster/package.json +++ b/packages/docusaurus-faster/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/faster", - "version": "3.6.2", + "version": "3.7.0", "description": "Docusaurus experimental package exposing new modern dependencies to make the build faster.", "main": "./lib/index.js", "types": "./lib/index.d.ts", @@ -18,8 +18,8 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/types": "3.6.2", - "@rspack/core": "^1.1.1", + "@docusaurus/types": "3.7.0", + "@rspack/core": "^1.2.5", "@swc/core": "^1.7.39", "@swc/html": "^1.7.39", "browserslist": "^4.24.2", diff --git a/packages/docusaurus-logger/package.json b/packages/docusaurus-logger/package.json index 1f6ac902d6..468f5c5bc8 100644 --- a/packages/docusaurus-logger/package.json +++ b/packages/docusaurus-logger/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/logger", - "version": "3.6.2", + "version": "3.7.0", "description": "An encapsulated logger for semantically formatting console messages.", "main": "./lib/index.js", "repository": { diff --git a/packages/docusaurus-logger/src/perfLogger.ts b/packages/docusaurus-logger/src/perfLogger.ts index 77b911dd94..7f9575c18c 100644 --- a/packages/docusaurus-logger/src/perfLogger.ts +++ b/packages/docusaurus-logger/src/perfLogger.ts @@ -114,12 +114,24 @@ function createPerfLogger(): PerfLoggerAPI { }, }); - const end: PerfLoggerAPI['end'] = (label) => { - const { - duration, - detail: {memoryUsage}, - } = performance.measure(label); + const readMark = (label: string) => { + const startMark = performance.getEntriesByName( + label, + 'mark', + )?.[0] as PerformanceMark; + if (!startMark) { + throw new Error(`No performance start mark for label=${label}`); + } performance.clearMarks(label); + return startMark; + }; + + const end: PerfLoggerAPI['end'] = (label) => { + const startMark = readMark(label); + const duration = performance.now() - startMark.startTime; + const { + detail: {memoryUsage}, + } = startMark; printPerfLog({ label: applyParentPrefix(label), duration, diff --git a/packages/docusaurus-mdx-loader/package.json b/packages/docusaurus-mdx-loader/package.json index 59a7de3e92..fa135a39f1 100644 --- a/packages/docusaurus-mdx-loader/package.json +++ b/packages/docusaurus-mdx-loader/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/mdx-loader", - "version": "3.6.2", + "version": "3.7.0", "description": "Docusaurus Loader for MDX", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -18,9 +18,9 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/logger": "3.6.2", - "@docusaurus/utils": "3.6.2", - "@docusaurus/utils-validation": "3.6.2", + "@docusaurus/logger": "3.7.0", + "@docusaurus/utils": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", "@mdx-js/mdx": "^3.0.0", "@slorber/remark-comment": "^1.0.0", "escape-html": "^1.0.3", @@ -44,7 +44,7 @@ "webpack": "^5.88.1" }, "devDependencies": { - "@docusaurus/types": "3.6.2", + "@docusaurus/types": "3.7.0", "@types/escape-html": "^1.0.2", "@types/mdast": "^4.0.2", "@types/stringify-object": "^3.3.1", @@ -58,8 +58,8 @@ "unist-util-remove-position": "^5.0.0" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "engines": { "node": ">=18.0" diff --git a/packages/docusaurus-mdx-loader/src/index.ts b/packages/docusaurus-mdx-loader/src/index.ts index 59f2ad1915..4df3cc0274 100644 --- a/packages/docusaurus-mdx-loader/src/index.ts +++ b/packages/docusaurus-mdx-loader/src/index.ts @@ -5,6 +5,8 @@ * LICENSE file in the root directory of this source tree. */ +import type {ReactNode} from 'react'; + import {mdxLoader} from './loader'; import type {TOCItem as TOCItemImported} from './remark/toc/types'; @@ -34,7 +36,7 @@ export type LoadedMDXContent = { * in priority. */ readonly assets: Assets; - (): JSX.Element; + (): ReactNode; }; export type {MDXPlugin} from './loader'; diff --git a/packages/docusaurus-mdx-loader/src/loader.ts b/packages/docusaurus-mdx-loader/src/loader.ts index f87a19e487..3aa7fc35ba 100644 --- a/packages/docusaurus-mdx-loader/src/loader.ts +++ b/packages/docusaurus-mdx-loader/src/loader.ts @@ -218,6 +218,7 @@ export async function mdxLoader( const compilerName = getWebpackLoaderCompilerName(this); const callback = this.async(); const options: Options = this.getOptions(); + options.dependencies?.forEach(this.addDependency); try { const result = await loadMDXWithCaching({ resource: this.resource, diff --git a/packages/docusaurus-mdx-loader/src/options.ts b/packages/docusaurus-mdx-loader/src/options.ts index ed199dc4af..5190953b0a 100644 --- a/packages/docusaurus-mdx-loader/src/options.ts +++ b/packages/docusaurus-mdx-loader/src/options.ts @@ -11,6 +11,8 @@ import type {ResolveMarkdownLink} from './remark/resolveMarkdownLinks'; import type {PromiseWithResolvers} from './utils'; export type Options = Partial & { + dependencies?: string[]; + markdownConfig: MarkdownConfig; staticDirs: string[]; siteDir: string; diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/img.md b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/img.md index 61b961202c..aeae06879e 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/img.md +++ b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/img.md @@ -29,3 +29,13 @@ in paragraph ![img](static/img.png) ```md ![img](./static/img.png) ``` + +## Images with spaces + +![img]() + +![img](<@site/static/img with spaces.png>) + +![img]() + +![img](<@site/static/img with one encoded%2520space.png>) diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/static/img with one encoded%20space.png b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/static/img with one encoded%20space.png new file mode 100644 index 0000000000..f458149e3c Binary files /dev/null and b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/static/img with one encoded%20space.png differ diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/static/img with spaces.png b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/static/img with spaces.png new file mode 100644 index 0000000000..f458149e3c Binary files /dev/null and b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/static/img with spaces.png differ diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__snapshots__/index.test.ts.snap index 4745422c1e..8572403706 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__snapshots__/index.test.ts.snap @@ -48,5 +48,15 @@ in paragraph img/node_modules/url-loade \`\`\`md ![img](./static/img.png) \`\`\` + +## Images with spaces + +img/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/img with spaces.png").default} width="200" height="200" /> + +img/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/img with spaces.png").default} width="200" height="200" /> + +img/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/img with one encoded%20space.png").default} width="200" height="200" /> + +img/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/img with one encoded%20space.png").default} width="200" height="200" /> " `; diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts b/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts index 5ae25e5e30..b3196df88a 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts @@ -98,6 +98,7 @@ async function toImageRequireNode( }); } } catch (err) { + console.error(err); // Workaround for https://github.com/yarnpkg/berry/pull/3889#issuecomment-1034469784 // TODO remove this check once fixed in Yarn PnP if (!process.versions.pnp) { @@ -152,10 +153,7 @@ async function getImageAbsolutePath( return imageFilePath; } // relative paths are resolved against the source file's folder - const imageFilePath = path.join( - path.dirname(filePath), - decodeURIComponent(imagePath), - ); + const imageFilePath = path.join(path.dirname(filePath), imagePath); await ensureImageFileExist(imageFilePath, filePath); return imageFilePath; } @@ -180,9 +178,14 @@ async function processImageNode(target: Target, context: Context) { return; } + // We decode it first because Node Url.pathname is always encoded + // while the image file-system path are not. + // See https://github.com/facebook/docusaurus/discussions/10720 + const decodedPathname = decodeURIComponent(parsedUrl.pathname); + // We try to convert image urls without protocol to images with require calls // going through webpack ensures that image assets exist at build time - const imagePath = await getImageAbsolutePath(parsedUrl.pathname, context); + const imagePath = await getImageAbsolutePath(decodedPathname, context); await toImageRequireNode(target, imagePath, context); } diff --git a/packages/docusaurus-module-type-aliases/package.json b/packages/docusaurus-module-type-aliases/package.json index 0dc2881f88..43fdebdcbf 100644 --- a/packages/docusaurus-module-type-aliases/package.json +++ b/packages/docusaurus-module-type-aliases/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/module-type-aliases", - "version": "3.6.2", + "version": "3.7.0", "description": "Docusaurus module type aliases.", "types": "./src/index.d.ts", "publishConfig": { @@ -12,12 +12,12 @@ "directory": "packages/docusaurus-module-type-aliases" }, "dependencies": { - "@docusaurus/types": "3.6.2", + "@docusaurus/types": "3.7.0", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", "@types/react-router-dom": "*", - "react-helmet-async": "*", + "react-helmet-async": "npm:@slorber/react-helmet-async@*", "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" }, "peerDependencies": { diff --git a/packages/docusaurus-module-type-aliases/src/index.d.ts b/packages/docusaurus-module-type-aliases/src/index.d.ts index 7fb78549f1..176ca2ec52 100644 --- a/packages/docusaurus-module-type-aliases/src/index.d.ts +++ b/packages/docusaurus-module-type-aliases/src/index.d.ts @@ -84,10 +84,11 @@ declare module '@theme-original/*'; declare module '@theme-init/*'; declare module '@theme/Error' { + import type {ReactNode} from 'react'; import type {FallbackParams} from '@docusaurus/ErrorBoundary'; export interface Props extends FallbackParams {} - export default function Error(props: Props): JSX.Element; + export default function Error(props: Props): ReactNode; } declare module '@theme/Layout' { @@ -96,17 +97,20 @@ declare module '@theme/Layout' { export interface Props { readonly children?: ReactNode; } - export default function Layout(props: Props): JSX.Element; + export default function Layout(props: Props): ReactNode; } declare module '@theme/Loading' { + import type {ReactNode} from 'react'; import type {LoadingComponentProps} from 'react-loadable'; - export default function Loading(props: LoadingComponentProps): JSX.Element; + export default function Loading(props: LoadingComponentProps): ReactNode; } declare module '@theme/NotFound' { - export default function NotFound(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function NotFound(): ReactNode; } declare module '@theme/Root' { @@ -115,11 +119,13 @@ declare module '@theme/Root' { export interface Props { readonly children: ReactNode; } - export default function Root({children}: Props): JSX.Element; + export default function Root({children}: Props): ReactNode; } declare module '@theme/SiteMetadata' { - export default function SiteMetadata(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function SiteMetadata(): ReactNode; } declare module '@docusaurus/constants' { @@ -134,13 +140,13 @@ declare module '@docusaurus/ErrorBoundary' { readonly tryAgain: () => void; }; - export type FallbackFunction = (params: FallbackParams) => JSX.Element; + export type FallbackFunction = (params: FallbackParams) => ReactNode; export interface Props { readonly fallback?: FallbackFunction; readonly children: ReactNode; } - export default function ErrorBoundary(props: Props): JSX.Element; + export default function ErrorBoundary(props: Props): ReactNode; } declare module '@docusaurus/Head' { @@ -149,11 +155,11 @@ declare module '@docusaurus/Head' { export type Props = HelmetProps & {children: ReactNode}; - export default function Head(props: Props): JSX.Element; + export default function Head(props: Props): ReactNode; } declare module '@docusaurus/Link' { - import type {CSSProperties, ComponentProps} from 'react'; + import type {CSSProperties, ComponentProps, ReactNode} from 'react'; import type {NavLinkProps as RRNavLinkProps} from 'react-router-dom'; type NavLinkProps = Partial; @@ -169,7 +175,7 @@ declare module '@docusaurus/Link' { /** Escape hatch in case broken links check doesn't make sense. */ readonly 'data-noBrokenLinkCheck'?: boolean; }; - export default function Link(props: Props): JSX.Element; + export default function Link(props: Props): ReactNode; } declare module '@docusaurus/Interpolate' { @@ -203,7 +209,7 @@ declare module '@docusaurus/Interpolate' { export default function Interpolate( props: InterpolateProps, - ): JSX.Element; + ): ReactNode; } declare module '@docusaurus/Translate' { @@ -241,7 +247,7 @@ declare module '@docusaurus/Translate' { export default function Translate( props: TranslateProps, - ): JSX.Element; + ): ReactNode; } declare module '@docusaurus/router' { @@ -318,11 +324,13 @@ declare module '@docusaurus/ComponentCreator' { } declare module '@docusaurus/BrowserOnly' { + import type {ReactNode} from 'react'; + export interface Props { - readonly children?: () => JSX.Element; - readonly fallback?: JSX.Element; + readonly children?: () => ReactNode; + readonly fallback?: ReactNode; } - export default function BrowserOnly(props: Props): JSX.Element | null; + export default function BrowserOnly(props: Props): ReactNode | null; } declare module '@docusaurus/isInternalUrl' { @@ -369,6 +377,9 @@ declare module '@docusaurus/useGlobalData' { export default function useGlobalData(): GlobalData; } +// TODO find a way to move this ambient type to the SVGR plugin? +// unfortunately looks complicated in practice +// see https://x.com/sebastienlorber/status/1859543512661832053 declare module '*.svg' { import type {ComponentType, SVGProps} from 'react'; diff --git a/packages/docusaurus-plugin-client-redirects/package.json b/packages/docusaurus-plugin-client-redirects/package.json index 071b3dbfeb..fb3cc10bc2 100644 --- a/packages/docusaurus-plugin-client-redirects/package.json +++ b/packages/docusaurus-plugin-client-redirects/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/plugin-client-redirects", - "version": "3.6.2", + "version": "3.7.0", "description": "Client redirects plugin for Docusaurus.", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -18,22 +18,22 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/logger": "3.6.2", - "@docusaurus/utils": "3.6.2", - "@docusaurus/utils-common": "3.6.2", - "@docusaurus/utils-validation": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/logger": "3.7.0", + "@docusaurus/utils": "3.7.0", + "@docusaurus/utils-common": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", "eta": "^2.2.0", "fs-extra": "^11.1.1", "lodash": "^4.17.21", "tslib": "^2.6.0" }, "devDependencies": { - "@docusaurus/types": "3.6.2" + "@docusaurus/types": "3.7.0" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "engines": { "node": ">=18.0" diff --git a/packages/docusaurus-plugin-content-blog/package.json b/packages/docusaurus-plugin-content-blog/package.json index ac25274783..8d7e3c1179 100644 --- a/packages/docusaurus-plugin-content-blog/package.json +++ b/packages/docusaurus-plugin-content-blog/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/plugin-content-blog", - "version": "3.6.2", + "version": "3.7.0", "description": "Blog plugin for Docusaurus.", "main": "lib/index.js", "types": "src/plugin-content-blog.d.ts", @@ -31,19 +31,20 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/logger": "3.6.2", - "@docusaurus/mdx-loader": "3.6.2", - "@docusaurus/theme-common": "3.6.2", - "@docusaurus/types": "3.6.2", - "@docusaurus/utils": "3.6.2", - "@docusaurus/utils-common": "3.6.2", - "@docusaurus/utils-validation": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/logger": "3.7.0", + "@docusaurus/mdx-loader": "3.7.0", + "@docusaurus/theme-common": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils": "3.7.0", + "@docusaurus/utils-common": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", "cheerio": "1.0.0-rc.12", "feed": "^4.2.2", "fs-extra": "^11.1.1", "lodash": "^4.17.21", "reading-time": "^1.5.0", + "schema-dts": "^1.1.2", "srcset": "^4.0.0", "tslib": "^2.6.0", "unist-util-visit": "^5.0.0", @@ -52,8 +53,8 @@ }, "peerDependencies": { "@docusaurus/plugin-content-docs": "*", - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "engines": { "node": ">=18.0" diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts index af408e3ded..9a1a256587 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts @@ -15,14 +15,27 @@ describe('normalizeSocials', () => { linkedin: 'ozakione', github: 'ozakione', stackoverflow: 'ozakione', + threads: 'gingergeekuk', + bluesky: 'gingergeek.co.uk', + instagram: 'thisweekinreact', + twitch: 'gingergeek', + youtube: 'gingergeekuk', + mastodon: 'Mastodon', }; + // eslint-disable-next-line jest/no-large-snapshots expect(normalizeSocials(socials)).toMatchInlineSnapshot(` { + "bluesky": "https://bsky.app/profile/gingergeek.co.uk", "github": "https://github.com/ozakione", + "instagram": "https://www.instagram.com/thisweekinreact", "linkedin": "https://www.linkedin.com/in/ozakione/", + "mastodon": "https://mastodon.social/@Mastodon", "stackoverflow": "https://stackoverflow.com/users/ozakione", + "threads": "https://www.threads.net/@gingergeekuk", + "twitch": "https://twitch.tv/gingergeek", "twitter": "https://twitter.com/ozakione", + "youtube": "https://youtube.com/@gingergeekuk", } `); }); @@ -33,13 +46,19 @@ describe('normalizeSocials', () => { linkedIn: 'ozakione', gitHub: 'ozakione', STACKoverflow: 'ozakione', + instaGRam: 'thisweekinreact', + BLUESKY: 'gingergeek.co.uk', + tHrEaDs: 'gingergeekuk', }; expect(normalizeSocials(socials)).toMatchInlineSnapshot(` { + "bluesky": "https://bsky.app/profile/gingergeek.co.uk", "github": "https://github.com/ozakione", + "instagram": "https://www.instagram.com/thisweekinreact", "linkedin": "https://www.linkedin.com/in/ozakione/", "stackoverflow": "https://stackoverflow.com/users/ozakione", + "threads": "https://www.threads.net/@gingergeekuk", "twitter": "https://twitter.com/ozakione", } `); @@ -62,12 +81,14 @@ describe('normalizeSocials', () => { linkedin: 'ozakione', github: 'https://github.com/ozakione', stackoverflow: 'https://stackoverflow.com/ozakione', + mastodon: 'https://hachyderm.io/@hachyderm', }; expect(normalizeSocials(socials)).toMatchInlineSnapshot(` { "github": "https://github.com/ozakione", "linkedin": "https://www.linkedin.com/in/ozakione/", + "mastodon": "https://hachyderm.io/@hachyderm", "stackoverflow": "https://stackoverflow.com/ozakione", "twitter": "https://twitter.com/ozakione", } diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/frontMatter.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/frontMatter.test.ts index f5ca63694c..2ef1184ead 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/frontMatter.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/frontMatter.test.ts @@ -79,6 +79,7 @@ describe('validateBlogPostFrontMatter description', () => { prefix: 'description', validFrontMatters: [ // See https://github.com/facebook/docusaurus/issues/4591#issuecomment-822372398 + {description: undefined}, {description: ''}, {description: 'description'}, ], @@ -90,6 +91,7 @@ describe('validateBlogPostFrontMatter title', () => { prefix: 'title', validFrontMatters: [ // See https://github.com/facebook/docusaurus/issues/4591#issuecomment-822372398 + {title: undefined}, {title: ''}, {title: 'title'}, ], @@ -103,7 +105,11 @@ describe('validateBlogPostFrontMatter title', () => { describe('validateBlogPostFrontMatter title_meta', () => { testField({ prefix: 'title_meta', - validFrontMatters: [{title: ''}, {title_meta: 'title'}], + validFrontMatters: [ + {title_meta: undefined}, + {title_meta: ''}, + {title_meta: 'title'}, + ], invalidFrontMatters: [ [{title_meta: null}, 'must be a string'], [{title_meta: false}, 'must be a string'], @@ -111,6 +117,21 @@ describe('validateBlogPostFrontMatter title_meta', () => { }); }); +describe('validateBlogPostFrontMatter sidebar_label', () => { + testField({ + prefix: 'title_meta', + validFrontMatters: [ + {sidebar_label: undefined}, + {sidebar_label: ''}, + {sidebar_label: 'title'}, + ], + invalidFrontMatters: [ + [{sidebar_label: null}, 'must be a string'], + [{sidebar_label: false}, 'must be a string'], + ], + }); +}); + describe('validateBlogPostFrontMatter id', () => { testField({ prefix: 'id', diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/props.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/props.test.ts index 4bd03a56cb..b0267b8a43 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/props.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/props.test.ts @@ -94,7 +94,7 @@ describe('toBlogSidebarProp', () => { permalink: '/blog/blog-2', unlisted: true, date: '2024-01-01', - frontMatter: {hello: 'world'}, + frontMatter: {hello: 'world', sidebar_label: 'title 2 (custom)'}, tags: [{label: 'tag1', permalink: '/tag1', inline: false}], }, }), @@ -117,7 +117,7 @@ describe('toBlogSidebarProp', () => { { "date": "2024-01-01", "permalink": "/blog/blog-2", - "title": "title 2", + "title": "title 2 (custom)", "unlisted": true, }, ], diff --git a/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts index b190e3e09d..80bb3c5864 100644 --- a/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts +++ b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts @@ -21,6 +21,12 @@ export const AuthorSocialsSchema = Joi.object({ .try(Joi.number(), Joi.string()) .custom((val) => String(val)), x: Joi.string(), + bluesky: Joi.string(), + instagram: Joi.string(), + threads: Joi.string(), + mastodon: Joi.string(), + twitch: Joi.string(), + youtube: Joi.string(), }).unknown(); type PredefinedPlatformNormalizer = (value: string) => string; @@ -35,6 +41,12 @@ const PredefinedPlatformNormalizers: Record< linkedin: (handle: string) => `https://www.linkedin.com/in/${handle}/`, stackoverflow: (userId: string) => `https://stackoverflow.com/users/${userId}`, + bluesky: (handle: string) => `https://bsky.app/profile/${handle}`, + instagram: (handle: string) => `https://www.instagram.com/${handle}`, + threads: (handle: string) => `https://www.threads.net/@${handle}`, + mastodon: (handle: string) => `https://mastodon.social/@${handle}`, // can be in format user@other.server and it will redirect if needed + twitch: (handle: string) => `https://twitch.tv/${handle}`, + youtube: (handle: string) => `https://youtube.com/@${handle}`, // https://support.google.com/youtube/answer/6180214?hl=en }; type SocialEntry = [string, string]; diff --git a/packages/docusaurus-plugin-content-blog/src/client/contexts.tsx b/packages/docusaurus-plugin-content-blog/src/client/contexts.tsx index 2493deb643..7c96f28860 100644 --- a/packages/docusaurus-plugin-content-blog/src/client/contexts.tsx +++ b/packages/docusaurus-plugin-content-blog/src/client/contexts.tsx @@ -74,7 +74,7 @@ export function BlogPostProvider({ children: ReactNode; content: PropBlogPostContent; isBlogPostPage?: boolean; -}): JSX.Element { +}): ReactNode { const contextValue = useContextValue({content, isBlogPostPage}); return {children}; } diff --git a/packages/docusaurus-plugin-content-blog/src/frontMatter.ts b/packages/docusaurus-plugin-content-blog/src/frontMatter.ts index 0e82225829..244eb565f9 100644 --- a/packages/docusaurus-plugin-content-blog/src/frontMatter.ts +++ b/packages/docusaurus-plugin-content-blog/src/frontMatter.ts @@ -33,7 +33,8 @@ const FrontMatterAuthorErrorMessage = const BlogFrontMatterSchema = Joi.object({ id: Joi.string(), title: Joi.string().allow(''), - title_meta: Joi.string(), + title_meta: Joi.string().allow(''), + sidebar_label: Joi.string().allow(''), description: Joi.string().allow(''), tags: FrontMatterTagsSchema, date: Joi.date().raw(), diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index 1606aaa5f5..a3056261cf 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -16,7 +16,12 @@ declare module '@docusaurus/plugin-content-blog' { FrontMatterLastUpdate, TagsPluginOptions, } from '@docusaurus/utils'; - import type {DocusaurusConfig, Plugin, LoadContext} from '@docusaurus/types'; + import type { + DocusaurusConfig, + Plugin, + LoadContext, + OptionValidationContext, + } from '@docusaurus/types'; import type {Item as FeedItem} from 'feed'; import type {Overwrite} from 'utility-types'; @@ -46,7 +51,13 @@ declare module '@docusaurus/plugin-content-blog' { | 'github' | 'linkedin' | 'stackoverflow' - | 'x'; + | 'x' + | 'bluesky' + | 'instagram' + | 'threads' + | 'mastodon' + | 'youtube' + | 'twitch'; /** * Social platforms of the author. @@ -145,7 +156,6 @@ declare module '@docusaurus/plugin-content-blog' { title?: string; /** * Will be used for SEO page metadata and override BlogPostMetadata.title. - * @see {@link BlogPostMetadata.title_meta} */ title_meta?: string; /** @@ -153,6 +163,10 @@ declare module '@docusaurus/plugin-content-blog' { * @see {@link BlogPostMetadata.description} */ description?: string; + /** + * Will override the default excerpt. + */ + sidebar_label?: string; /** * Front matter tags, unnormalized. * @see {@link BlogPostMetadata.tags} @@ -657,9 +671,14 @@ declare module '@docusaurus/plugin-content-blog' { context: LoadContext, options: PluginOptions, ): Promise>; + + export function validateOptions( + args: OptionValidationContext, + ): PluginOptions; } declare module '@theme/BlogPostPage' { + import type {ReactNode} from 'react'; import type { BlogPostFrontMatter, BlogSidebar, @@ -680,18 +699,23 @@ declare module '@theme/BlogPostPage' { readonly blogMetadata: BlogMetadata; } - export default function BlogPostPage(props: Props): JSX.Element; + export default function BlogPostPage(props: Props): ReactNode; } declare module '@theme/BlogPostPage/Metadata' { - export default function BlogPostPageMetadata(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function BlogPostPageMetadata(): ReactNode; } declare module '@theme/BlogPostPage/StructuredData' { - export default function BlogPostStructuredData(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function BlogPostStructuredData(): ReactNode; } declare module '@theme/BlogListPage' { + import type {ReactNode} from 'react'; import type {Content} from '@theme/BlogPostPage'; import type { BlogSidebar, @@ -710,10 +734,11 @@ declare module '@theme/BlogListPage' { readonly items: readonly {readonly content: Content}[]; } - export default function BlogListPage(props: Props): JSX.Element; + export default function BlogListPage(props: Props): ReactNode; } declare module '@theme/BlogListPage/StructuredData' { + import type {ReactNode} from 'react'; import type {Content} from '@theme/BlogPostPage'; import type { BlogSidebar, @@ -732,10 +757,11 @@ declare module '@theme/BlogListPage/StructuredData' { readonly items: readonly {readonly content: Content}[]; } - export default function BlogListPageStructuredData(props: Props): JSX.Element; + export default function BlogListPageStructuredData(props: Props): ReactNode; } declare module '@theme/BlogTagsListPage' { + import type {ReactNode} from 'react'; import type {BlogSidebar} from '@docusaurus/plugin-content-blog'; import type {TagsListItem} from '@docusaurus/utils'; @@ -746,10 +772,11 @@ declare module '@theme/BlogTagsListPage' { readonly tags: TagsListItem[]; } - export default function BlogTagsListPage(props: Props): JSX.Element; + export default function BlogTagsListPage(props: Props): ReactNode; } declare module '@theme/Blog/Pages/BlogAuthorsListPage' { + import type {ReactNode} from 'react'; import type { AuthorItemProp, BlogSidebar, @@ -762,10 +789,11 @@ declare module '@theme/Blog/Pages/BlogAuthorsListPage' { readonly authors: AuthorItemProp[]; } - export default function BlogAuthorsListPage(props: Props): JSX.Element; + export default function BlogAuthorsListPage(props: Props): ReactNode; } declare module '@theme/Blog/Pages/BlogAuthorsPostsPage' { + import type {ReactNode} from 'react'; import type {Content} from '@theme/BlogPostPage'; import type { AuthorItemProp, @@ -787,10 +815,11 @@ declare module '@theme/Blog/Pages/BlogAuthorsPostsPage' { readonly items: readonly {readonly content: Content}[]; } - export default function BlogAuthorsPostsPage(props: Props): JSX.Element; + export default function BlogAuthorsPostsPage(props: Props): ReactNode; } declare module '@theme/BlogTagsPostsPage' { + import type {ReactNode} from 'react'; import type {Content} from '@theme/BlogPostPage'; import type { BlogSidebar, @@ -812,10 +841,11 @@ declare module '@theme/BlogTagsPostsPage' { readonly items: readonly {readonly content: Content}[]; } - export default function BlogTagsPostsPage(props: Props): JSX.Element; + export default function BlogTagsPostsPage(props: Props): ReactNode; } declare module '@theme/BlogArchivePage' { + import type {ReactNode} from 'react'; import type {Content} from '@theme/BlogPostPage'; /** We may add extra metadata or prune some metadata from here */ @@ -829,5 +859,5 @@ declare module '@theme/BlogArchivePage' { }; } - export default function BlogArchivePage(props: Props): JSX.Element; + export default function BlogArchivePage(props: Props): ReactNode; } diff --git a/packages/docusaurus-plugin-content-blog/src/props.ts b/packages/docusaurus-plugin-content-blog/src/props.ts index df7afbb425..b8fac4d192 100644 --- a/packages/docusaurus-plugin-content-blog/src/props.ts +++ b/packages/docusaurus-plugin-content-blog/src/props.ts @@ -65,7 +65,8 @@ export function toBlogSidebarProp({ return { title: blogSidebarTitle, items: blogPosts.map((blogPost) => ({ - title: blogPost.metadata.title, + title: + blogPost.metadata.frontMatter.sidebar_label ?? blogPost.metadata.title, permalink: blogPost.metadata.permalink, unlisted: blogPost.metadata.unlisted, date: blogPost.metadata.date, diff --git a/packages/docusaurus-plugin-content-docs/package.json b/packages/docusaurus-plugin-content-docs/package.json index 33574c3a9d..bbfdd49432 100644 --- a/packages/docusaurus-plugin-content-docs/package.json +++ b/packages/docusaurus-plugin-content-docs/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/plugin-content-docs", - "version": "3.6.2", + "version": "3.7.0", "description": "Docs plugin for Docusaurus.", "main": "lib/index.js", "sideEffects": false, @@ -35,20 +35,21 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/logger": "3.6.2", - "@docusaurus/mdx-loader": "3.6.2", - "@docusaurus/module-type-aliases": "3.6.2", - "@docusaurus/theme-common": "3.6.2", - "@docusaurus/types": "3.6.2", - "@docusaurus/utils": "3.6.2", - "@docusaurus/utils-common": "3.6.2", - "@docusaurus/utils-validation": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/logger": "3.7.0", + "@docusaurus/mdx-loader": "3.7.0", + "@docusaurus/module-type-aliases": "3.7.0", + "@docusaurus/theme-common": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils": "3.7.0", + "@docusaurus/utils-common": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", "@types/react-router-config": "^5.0.7", "combine-promises": "^1.1.0", "fs-extra": "^11.1.1", "js-yaml": "^4.1.0", "lodash": "^4.17.21", + "schema-dts": "^1.1.2", "tslib": "^2.6.0", "utility-types": "^3.10.0", "webpack": "^5.88.1" @@ -61,8 +62,8 @@ "shelljs": "^0.8.5" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "engines": { "node": ">=18.0" diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-site/i18n/zh-Hans/docusaurus-plugin-content-docs/current.json b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-site/i18n/zh-Hans/docusaurus-plugin-content-docs/current.json new file mode 100644 index 0000000000..4f3fcbcf07 --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-site/i18n/zh-Hans/docusaurus-plugin-content-docs/current.json @@ -0,0 +1,3 @@ +{ + "some.key": "some translation" +} diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts index baa3481694..c8c28dfca3 100644 Binary files a/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts and b/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts differ diff --git a/packages/docusaurus-plugin-content-docs/src/cli.ts b/packages/docusaurus-plugin-content-docs/src/cli.ts index ed5b46e29a..e66e910ebc 100644 --- a/packages/docusaurus-plugin-content-docs/src/cli.ts +++ b/packages/docusaurus-plugin-content-docs/src/cli.ts @@ -14,6 +14,7 @@ import { getVersionDocsDirPath, getVersionSidebarsPath, getDocsDirPathLocalized, + getPluginDirPathLocalized, readVersionsFile, } from './versions/files'; import {validateVersionName} from './versions/validation'; @@ -123,6 +124,23 @@ async function cliDocsVersionCommand( versionName: version, }); await fs.copy(docsDir, newVersionDir); + + // Copy version JSON translation file for this locale + // i18n//docusaurus-plugin-content-docs/current.json => version-v1.json + // See https://docusaurus.io/docs/next/api/plugins/@docusaurus/plugin-content-docs#translation-files-location + if (locale !== i18n.defaultLocale) { + const dir = getPluginDirPathLocalized({ + localizationDir, + pluginId, + }); + const sourceFile = path.join(dir, 'current.json'); + const dest = path.join(dir, `version-${version}.json`); + if (await fs.pathExists(sourceFile)) { + await fs.copy(sourceFile, dest); + } else { + logger.warn`${pluginIdLogPrefix}: i18n translation file does not exist in path=${sourceFile}. Skipping.`; + } + } }), ); diff --git a/packages/docusaurus-plugin-content-docs/src/client/__tests__/docsUtils.test.tsx b/packages/docusaurus-plugin-content-docs/src/client/__tests__/docsUtils.test.tsx index 974eca6ce2..00263ad590 100644 --- a/packages/docusaurus-plugin-content-docs/src/client/__tests__/docsUtils.test.tsx +++ b/packages/docusaurus-plugin-content-docs/src/client/__tests__/docsUtils.test.tsx @@ -15,6 +15,7 @@ import { useDocById, findSidebarCategory, useCurrentSidebarCategory, + useCurrentSidebarSiblings, useSidebarBreadcrumbs, isVisibleSidebarItem, } from '../docsUtils'; @@ -440,6 +441,7 @@ describe('isVisibleSidebarItem', () => { it('works with category', () => { const subCategoryAllUnlisted = testCategory({ href: '/sub-category-path', + linkUnlisted: true, items: [ { type: 'link', @@ -455,6 +457,7 @@ describe('isVisibleSidebarItem', () => { }, testCategory({ href: '/sub-sub-category-path', + linkUnlisted: true, items: [ { type: 'link', @@ -500,6 +503,22 @@ describe('isVisibleSidebarItem', () => { expect( isVisibleSidebarItem(categorySomeUnlisted, categorySomeUnlisted.href!), ).toBe(true); + + const categoryOnlyIndexListed = testCategory({ + href: '/category-only-index-listed', + items: [ + { + type: 'link', + href: '/sub-link-path', + label: 'Label', + unlisted: true, + }, + subCategoryAllUnlisted, + ], + }); + expect( + isVisibleSidebarItem(categoryOnlyIndexListed, '/nonexistentPath'), + ).toBe(true); }); }); @@ -762,3 +781,128 @@ describe('useCurrentSidebarCategory', () => { ); }); }); + +describe('useCurrentSidebarSiblings', () => { + const createUseCurrentSidebarSiblingsMock = + (sidebar?: PropSidebar) => (location: string) => + renderHook(() => useCurrentSidebarSiblings(), { + wrapper: ({children}) => ( + + {children} + + ), + }).result.current; + + it('works for sidebar category', () => { + const category: PropSidebarItemCategory = testCategory({ + href: '/cat', + items: [testLink(), testLink()], + }); + const sidebar: PropSidebar = [ + testLink(), + testLink(), + category, + testCategory(), + ]; + + const mockUseCurrentSidebarCategory = + createUseCurrentSidebarSiblingsMock(sidebar); + + expect(mockUseCurrentSidebarCategory('/cat')).toEqual(category.items); + }); + + it('works for sidebar root', () => { + const category: PropSidebarItemCategory = testCategory({ + href: '/cat', + items: [testLink(), testLink()], + }); + const sidebar: PropSidebar = [ + testLink({href: '/rootLink'}), + testLink(), + category, + testCategory(), + ]; + + const mockUseCurrentSidebarCategory = + createUseCurrentSidebarSiblingsMock(sidebar); + + expect(mockUseCurrentSidebarCategory('/rootLink')).toEqual(sidebar); + }); + + it('works for nested sidebar category', () => { + const category2: PropSidebarItemCategory = testCategory({ + href: '/cat2', + items: [testLink(), testCategory()], + }); + const category1: PropSidebarItemCategory = testCategory({ + href: '/cat1', + items: [testLink(), testLink(), category2, testCategory()], + }); + const sidebar: PropSidebar = [ + testLink(), + testLink(), + category1, + testCategory(), + ]; + + const mockUseCurrentSidebarCategory = + createUseCurrentSidebarSiblingsMock(sidebar); + + expect(mockUseCurrentSidebarCategory('/cat2')).toEqual(category2.items); + }); + + it('works for category link item', () => { + const link = testLink({href: '/my/link/path'}); + const category: PropSidebarItemCategory = testCategory({ + href: '/cat1', + items: [testLink(), testLink(), link, testCategory()], + }); + const sidebar: PropSidebar = [ + testLink(), + testLink(), + category, + testCategory(), + ]; + + const mockUseCurrentSidebarCategory = + createUseCurrentSidebarSiblingsMock(sidebar); + + expect(mockUseCurrentSidebarCategory('/my/link/path')).toEqual( + category.items, + ); + }); + + it('works for nested category link item', () => { + const link = testLink({href: '/my/link/path'}); + const category2: PropSidebarItemCategory = testCategory({ + href: '/cat2', + items: [testLink(), testLink(), link, testCategory()], + }); + const category1: PropSidebarItemCategory = testCategory({ + href: '/cat1', + items: [testLink(), testLink(), category2, testCategory()], + }); + const sidebar: PropSidebar = [ + testLink(), + testLink(), + category1, + testCategory(), + ]; + + const mockUseCurrentSidebarCategory = + createUseCurrentSidebarSiblingsMock(sidebar); + + expect(mockUseCurrentSidebarCategory('/my/link/path')).toEqual( + category2.items, + ); + }); + + it('throws when sidebar is missing', () => { + const mockUseCurrentSidebarCategory = createUseCurrentSidebarSiblingsMock(); + expect(() => + mockUseCurrentSidebarCategory('/cat'), + ).toThrowErrorMatchingInlineSnapshot( + `"Unexpected: cant find current sidebar in context"`, + ); + }); +}); diff --git a/packages/docusaurus-plugin-content-docs/src/client/doc.tsx b/packages/docusaurus-plugin-content-docs/src/client/doc.tsx index 6f4ce492e4..8d2710b631 100644 --- a/packages/docusaurus-plugin-content-docs/src/client/doc.tsx +++ b/packages/docusaurus-plugin-content-docs/src/client/doc.tsx @@ -50,7 +50,7 @@ export function DocProvider({ }: { children: ReactNode; content: PropDocContent; -}): JSX.Element { +}): ReactNode { const contextValue = useContextValue(content); return {children}; } diff --git a/packages/docusaurus-plugin-content-docs/src/client/docSidebarItemsExpandedState.tsx b/packages/docusaurus-plugin-content-docs/src/client/docSidebarItemsExpandedState.tsx index 3aa0d47594..417827700c 100644 --- a/packages/docusaurus-plugin-content-docs/src/client/docSidebarItemsExpandedState.tsx +++ b/packages/docusaurus-plugin-content-docs/src/client/docSidebarItemsExpandedState.tsx @@ -36,7 +36,7 @@ export function DocSidebarItemsExpandedStateProvider({ children, }: { children: ReactNode; -}): JSX.Element { +}): ReactNode { const [expandedItem, setExpandedItem] = useState(null); const contextValue = useMemo( () => ({expandedItem, setExpandedItem}), diff --git a/packages/docusaurus-plugin-content-docs/src/client/docsPreferredVersion.tsx b/packages/docusaurus-plugin-content-docs/src/client/docsPreferredVersion.tsx index 91dcd3a19c..1c9c8b6b69 100644 --- a/packages/docusaurus-plugin-content-docs/src/client/docsPreferredVersion.tsx +++ b/packages/docusaurus-plugin-content-docs/src/client/docsPreferredVersion.tsx @@ -163,7 +163,7 @@ function DocsPreferredVersionContextProviderUnsafe({ children, }: { children: ReactNode; -}): JSX.Element { +}): ReactNode { const value = useContextValue(); return {children}; } @@ -176,7 +176,7 @@ export function DocsPreferredVersionContextProvider({ children, }: { children: ReactNode; -}): JSX.Element { +}): ReactNode { return ( {children} diff --git a/packages/docusaurus-plugin-content-docs/src/client/docsSidebar.tsx b/packages/docusaurus-plugin-content-docs/src/client/docsSidebar.tsx index 4679ce4e63..d6a61682db 100644 --- a/packages/docusaurus-plugin-content-docs/src/client/docsSidebar.tsx +++ b/packages/docusaurus-plugin-content-docs/src/client/docsSidebar.tsx @@ -30,7 +30,7 @@ export function DocsSidebarProvider({ children: ReactNode; name: string | undefined; items: PropSidebar | undefined; -}): JSX.Element { +}): ReactNode { const stableValue: ContextValue | null = useMemo( () => (name && items ? {name, items} : null), [name, items], diff --git a/packages/docusaurus-plugin-content-docs/src/client/docsUtils.tsx b/packages/docusaurus-plugin-content-docs/src/client/docsUtils.tsx index 61ef935e09..aa00df8510 100644 --- a/packages/docusaurus-plugin-content-docs/src/client/docsUtils.tsx +++ b/packages/docusaurus-plugin-content-docs/src/client/docsUtils.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import {useMemo} from 'react'; +import {type ReactNode, useMemo} from 'react'; import {matchPath, useLocation} from '@docusaurus/router'; import renderRoutes from '@docusaurus/renderRoutes'; import { @@ -132,6 +132,25 @@ export function useCurrentSidebarCategory(): PropSidebarItemCategory { return deepestCategory; } +/** + * Gets the category associated with the current location. Should only be used + * on category index pages. + */ +export function useCurrentSidebarSiblings(): PropSidebarItem[] { + const {pathname} = useLocation(); + const sidebar = useDocsSidebar(); + if (!sidebar) { + throw new Error('Unexpected: cant find current sidebar in context'); + } + const categoryBreadcrumbs = getSidebarBreadcrumbs({ + sidebarItems: sidebar.items, + pathname, + onlyCategories: true, + }); + const deepestCategory = categoryBreadcrumbs.slice(-1)[0]; + return deepestCategory?.items ?? sidebar.items; +} + const isActive = (testedPath: string | undefined, activePath: string) => typeof testedPath !== 'undefined' && isSamePath(testedPath, activePath); const containsActiveSidebarItem = ( @@ -168,6 +187,7 @@ export function isVisibleSidebarItem( case 'category': return ( isActiveSidebarItem(item, activePath) || + (typeof item.href !== 'undefined' && !item.linkUnlisted) || item.items.some((subItem) => isVisibleSidebarItem(subItem, activePath)) ); case 'link': @@ -363,7 +383,7 @@ Available doc ids are: */ export function useDocRootMetadata({route}: DocRootProps): null | { /** The element that should be rendered at the current location. */ - docElement: JSX.Element; + docElement: ReactNode; /** * The name of the sidebar associated with the current doc. `sidebarName` and * `sidebarItems` correspond to the value of {@link useDocsSidebar}. diff --git a/packages/docusaurus-plugin-content-docs/src/client/docsVersion.tsx b/packages/docusaurus-plugin-content-docs/src/client/docsVersion.tsx index d89f982719..340b92708e 100644 --- a/packages/docusaurus-plugin-content-docs/src/client/docsVersion.tsx +++ b/packages/docusaurus-plugin-content-docs/src/client/docsVersion.tsx @@ -20,7 +20,7 @@ export function DocsVersionProvider({ }: { children: ReactNode; version: PropVersionMetadata | null; -}): JSX.Element { +}): ReactNode { return {children}; } diff --git a/packages/docusaurus-plugin-content-docs/src/client/index.ts b/packages/docusaurus-plugin-content-docs/src/client/index.ts index f60ba572fa..3751b4424b 100644 --- a/packages/docusaurus-plugin-content-docs/src/client/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/client/index.ts @@ -33,6 +33,7 @@ export { useLayoutDocsSidebar, useDocRootMetadata, useCurrentSidebarCategory, + useCurrentSidebarSiblings, filterDocCardListItems, } from './docsUtils'; @@ -59,6 +60,8 @@ export { getDocsVersionSearchTag, } from './docsSearch'; +export {useBreadcrumbsStructuredData} from './structuredDataUtils'; + export type ActivePlugin = { pluginId: string; pluginData: GlobalPluginData; diff --git a/packages/docusaurus-plugin-content-docs/src/client/structuredDataUtils.ts b/packages/docusaurus-plugin-content-docs/src/client/structuredDataUtils.ts new file mode 100644 index 0000000000..01367a4388 --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/client/structuredDataUtils.ts @@ -0,0 +1,32 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import type {PropSidebarBreadcrumbsItem} from '@docusaurus/plugin-content-docs'; +import type {WithContext, BreadcrumbList} from 'schema-dts'; + +export function useBreadcrumbsStructuredData({ + breadcrumbs, +}: { + breadcrumbs: PropSidebarBreadcrumbsItem[]; +}): WithContext { + const {siteConfig} = useDocusaurusContext(); + return { + '@context': 'https://schema.org', + '@type': 'BreadcrumbList', + itemListElement: breadcrumbs + // We filter breadcrumb items without links, they are not allowed + // See also https://github.com/facebook/docusaurus/issues/9319#issuecomment-2643560845 + .filter((breadcrumb) => breadcrumb.href) + .map((breadcrumb, index) => ({ + '@type': 'ListItem', + position: index + 1, + name: breadcrumb.label, + item: `${siteConfig.url}${breadcrumb.href}`, + })), + }; +} diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index fe72e070bb..a774c2b52c 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -6,6 +6,7 @@ */ import path from 'path'; +import fs from 'fs-extra'; import _ from 'lodash'; import logger from '@docusaurus/logger'; import { @@ -63,6 +64,37 @@ import type {LoadContext, Plugin} from '@docusaurus/types'; import type {DocFile, FullVersion} from './types'; import type {RuleSetRule} from 'webpack'; +// MDX loader is not 100% deterministic, leading to cache invalidation issue +// This permits to invalidate the MDX loader cache entries when content changes +// Problem documented here: https://github.com/facebook/docusaurus/pull/10934 +// TODO this is not a perfect solution, find better? +async function createMdxLoaderDependencyFile({ + dataDir, + options, + versionsMetadata, +}: { + dataDir: string; + options: PluginOptions; + versionsMetadata: VersionMetadata[]; +}): Promise { + // TODO this has been temporarily made opt-in until Rspack cache bug is fixed + // See https://github.com/facebook/docusaurus/pull/10931 + // See https://github.com/facebook/docusaurus/pull/10934#issuecomment-2672253145 + if (!process.env.DOCUSAURUS_ENABLE_MDX_DEPENDENCY_FILE) { + return undefined; + } + + const filePath = path.join(dataDir, '__mdx-loader-dependency.json'); + // the cache is invalidated whenever this file content changes + const fileContent = { + options, + versionsMetadata, + }; + await fs.ensureDir(dataDir); + await fs.writeFile(filePath, JSON.stringify(fileContent)); + return filePath; +} + export default async function pluginContentDocs( context: LoadContext, options: PluginOptions, @@ -107,6 +139,14 @@ export default async function pluginContentDocs( return createMDXLoaderRule({ include: contentDirs, options: { + dependencies: [ + await createMdxLoaderDependencyFile({ + dataDir, + options, + versionsMetadata, + }), + ].filter((d): d is string => typeof d === 'string'), + useCrossCompilerCache: siteConfig.future.experimental_faster.mdxCrossCompilerCache, admonitions: options.admonitions, diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index 806cf280ce..10f4a84a3b 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -20,7 +20,11 @@ declare module '@docusaurus/plugin-content-docs' { TagMetadata, TagsPluginOptions, } from '@docusaurus/utils'; - import type {Plugin, LoadContext} from '@docusaurus/types'; + import type { + Plugin, + LoadContext, + OptionValidationContext, + } from '@docusaurus/types'; import type {Overwrite, Required} from 'utility-types'; export type Assets = { @@ -559,13 +563,18 @@ declare module '@docusaurus/plugin-content-docs' { context: LoadContext, options: PluginOptions, ): Promise>; + + export function validateOptions( + args: OptionValidationContext, + ): PluginOptions; } declare module '@theme/DocItem' { + import type {ReactNode} from 'react'; import type {PropDocContent} from '@docusaurus/plugin-content-docs'; export type DocumentRoute = { - readonly component: () => JSX.Element; + readonly component: () => ReactNode; readonly exact: boolean; readonly path: string; readonly sidebar?: string; @@ -576,10 +585,11 @@ declare module '@theme/DocItem' { readonly content: PropDocContent; } - export default function DocItem(props: Props): JSX.Element; + export default function DocItem(props: Props): ReactNode; } declare module '@theme/DocCategoryGeneratedIndexPage' { + import type {ReactNode} from 'react'; import type {PropCategoryGeneratedIndex} from '@docusaurus/plugin-content-docs'; export interface Props { @@ -588,39 +598,45 @@ declare module '@theme/DocCategoryGeneratedIndexPage' { export default function DocCategoryGeneratedIndexPage( props: Props, - ): JSX.Element; + ): ReactNode; } declare module '@theme/DocTagsListPage' { + import type {ReactNode} from 'react'; import type {PropTagsListPage} from '@docusaurus/plugin-content-docs'; export interface Props extends PropTagsListPage {} - export default function DocTagsListPage(props: Props): JSX.Element; + export default function DocTagsListPage(props: Props): ReactNode; } declare module '@theme/DocTagDocListPage' { + import type {ReactNode} from 'react'; import type {PropTagDocList} from '@docusaurus/plugin-content-docs'; export interface Props { readonly tag: PropTagDocList; } - export default function DocTagDocListPage(props: Props): JSX.Element; + export default function DocTagDocListPage(props: Props): ReactNode; } declare module '@theme/DocBreadcrumbs' { - export default function DocBreadcrumbs(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function DocBreadcrumbs(): ReactNode; } declare module '@theme/DocsRoot' { + import type {ReactNode} from 'react'; import type {RouteConfigComponentProps} from 'react-router-config'; import type {Required} from 'utility-types'; export interface Props extends Required {} - export default function DocsRoot(props: Props): JSX.Element; + export default function DocsRoot(props: Props): ReactNode; } declare module '@theme/DocVersionRoot' { + import type {ReactNode} from 'react'; import type {PropVersionMetadata} from '@docusaurus/plugin-content-docs'; import type {RouteConfigComponentProps} from 'react-router-config'; import type {Required} from 'utility-types'; @@ -629,14 +645,15 @@ declare module '@theme/DocVersionRoot' { readonly version: PropVersionMetadata; } - export default function DocVersionRoot(props: Props): JSX.Element; + export default function DocVersionRoot(props: Props): ReactNode; } declare module '@theme/DocRoot' { + import type {ReactNode} from 'react'; import type {RouteConfigComponentProps} from 'react-router-config'; import type {Required} from 'utility-types'; export interface Props extends Required {} - export default function DocRoot(props: Props): JSX.Element; + export default function DocRoot(props: Props): ReactNode; } diff --git a/packages/docusaurus-plugin-content-docs/src/versions/files.ts b/packages/docusaurus-plugin-content-docs/src/versions/files.ts index 2f045717c2..00b3f08270 100644 --- a/packages/docusaurus-plugin-content-docs/src/versions/files.ts +++ b/packages/docusaurus-plugin-content-docs/src/versions/files.ts @@ -75,6 +75,21 @@ export function getDocsDirPathLocalized({ }); } +export function getPluginDirPathLocalized({ + localizationDir, + pluginId, +}: { + localizationDir: string; + pluginId: string; +}): string { + return getPluginI18nPath({ + localizationDir, + pluginName: 'docusaurus-plugin-content-docs', + pluginId, + subPaths: [], + }); +} + /** `community` => `[siteDir]/community_versions.json` */ export function getVersionsFilePath(siteDir: string, pluginId: string): string { return path.join(siteDir, addPluginIdPrefix(VERSIONS_JSON_FILE, pluginId)); diff --git a/packages/docusaurus-plugin-content-pages/package.json b/packages/docusaurus-plugin-content-pages/package.json index 01d3c08732..0c40d973f9 100644 --- a/packages/docusaurus-plugin-content-pages/package.json +++ b/packages/docusaurus-plugin-content-pages/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/plugin-content-pages", - "version": "3.6.2", + "version": "3.7.0", "description": "Pages plugin for Docusaurus.", "main": "lib/index.js", "types": "src/plugin-content-pages.d.ts", @@ -18,18 +18,18 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/mdx-loader": "3.6.2", - "@docusaurus/types": "3.6.2", - "@docusaurus/utils": "3.6.2", - "@docusaurus/utils-validation": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/mdx-loader": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", "fs-extra": "^11.1.1", "tslib": "^2.6.0", "webpack": "^5.88.1" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "engines": { "node": ">=18.0" diff --git a/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts b/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts index 1c7b037437..d9045fd3f4 100644 --- a/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts +++ b/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts @@ -7,7 +7,11 @@ declare module '@docusaurus/plugin-content-pages' { import type {MDXOptions} from '@docusaurus/mdx-loader'; - import type {LoadContext, Plugin} from '@docusaurus/types'; + import type { + LoadContext, + Plugin, + OptionValidationContext, + } from '@docusaurus/types'; import type {FrontMatterLastUpdate, LastUpdateData} from '@docusaurus/utils'; export type Assets = { @@ -82,9 +86,14 @@ declare module '@docusaurus/plugin-content-pages' { context: LoadContext, options: PluginOptions, ): Promise>; + + export function validateOptions( + args: OptionValidationContext, + ): PluginOptions; } declare module '@theme/MDXPage' { + import type {ReactNode} from 'react'; import type {LoadedMDXContent} from '@docusaurus/mdx-loader'; import type { MDXPageMetadata, @@ -100,5 +109,5 @@ declare module '@theme/MDXPage' { >; } - export default function MDXPage(props: Props): JSX.Element; + export default function MDXPage(props: Props): ReactNode; } diff --git a/packages/docusaurus-plugin-debug/package.json b/packages/docusaurus-plugin-debug/package.json index 57f93c6595..ff478bbc44 100644 --- a/packages/docusaurus-plugin-debug/package.json +++ b/packages/docusaurus-plugin-debug/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/plugin-debug", - "version": "3.6.2", + "version": "3.7.0", "description": "Debug plugin for Docusaurus.", "main": "lib/index.js", "types": "src/plugin-debug.d.ts", @@ -20,16 +20,16 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/types": "3.6.2", - "@docusaurus/utils": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils": "3.7.0", "fs-extra": "^11.1.1", - "react-json-view-lite": "^1.2.0", + "react-json-view-lite": "^2.3.0", "tslib": "^2.6.0" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "engines": { "node": ">=18.0" diff --git a/packages/docusaurus-plugin-debug/src/plugin-debug.d.ts b/packages/docusaurus-plugin-debug/src/plugin-debug.d.ts index f66d093a1b..f59d95f85d 100644 --- a/packages/docusaurus-plugin-debug/src/plugin-debug.d.ts +++ b/packages/docusaurus-plugin-debug/src/plugin-debug.d.ts @@ -14,46 +14,57 @@ declare module '@docusaurus/plugin-debug' { } declare module '@theme/DebugConfig' { - export default function DebugMetadata(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function DebugMetadata(): ReactNode; } declare module '@theme/DebugContent' { + import type {ReactNode} from 'react'; import type {AllContent} from '@docusaurus/types'; export interface Props { readonly allContent: AllContent; } - export default function DebugContent(props: Props): JSX.Element; + export default function DebugContent(props: Props): ReactNode; } declare module '@theme/DebugGlobalData' { - export default function DebugGlobalData(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function DebugGlobalData(): ReactNode; } declare module '@theme/DebugJsonView' { + import type {ReactNode} from 'react'; + export interface Props { readonly src: unknown; readonly collapseDepth?: number; } - export default function DebugJsonView(props: Props): JSX.Element; + export default function DebugJsonView(props: Props): ReactNode; } declare module '@theme/DebugLayout' { import type {ReactNode} from 'react'; - export default function DebugLayout(props: { - children: ReactNode; - }): JSX.Element; + export default function DebugLayout(props: {children: ReactNode}): ReactNode; } declare module '@theme/DebugRegistry' { - export default function DebugRegistry(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function DebugRegistry(): ReactNode; } declare module '@theme/DebugRoutes' { - export default function DebugRoutes(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function DebugRoutes(): ReactNode; } declare module '@theme/DebugSiteMetadata' { - export default function DebugSiteMetadata(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function DebugSiteMetadata(): ReactNode; } diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugConfig/index.tsx b/packages/docusaurus-plugin-debug/src/theme/DebugConfig/index.tsx index 6b110b8ab1..1245ec6121 100644 --- a/packages/docusaurus-plugin-debug/src/theme/DebugConfig/index.tsx +++ b/packages/docusaurus-plugin-debug/src/theme/DebugConfig/index.tsx @@ -5,12 +5,12 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import DebugLayout from '@theme/DebugLayout'; import DebugJsonView from '@theme/DebugJsonView'; -export default function DebugMetadata(): JSX.Element { +export default function DebugMetadata(): ReactNode { const {siteConfig} = useDocusaurusContext(); return ( diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugContent/index.tsx b/packages/docusaurus-plugin-debug/src/theme/DebugContent/index.tsx index 185c453d7c..9cd6773de6 100644 --- a/packages/docusaurus-plugin-debug/src/theme/DebugContent/index.tsx +++ b/packages/docusaurus-plugin-debug/src/theme/DebugContent/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import DebugLayout from '@theme/DebugLayout'; import DebugJsonView from '@theme/DebugJsonView'; @@ -52,7 +52,7 @@ function PluginContent({ ); } -export default function DebugContent({allContent}: Props): JSX.Element { +export default function DebugContent({allContent}: Props): ReactNode { return (

Plugin content

diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugGlobalData/index.tsx b/packages/docusaurus-plugin-debug/src/theme/DebugGlobalData/index.tsx index f66df5b7dd..139cc382ce 100644 --- a/packages/docusaurus-plugin-debug/src/theme/DebugGlobalData/index.tsx +++ b/packages/docusaurus-plugin-debug/src/theme/DebugGlobalData/index.tsx @@ -5,12 +5,12 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import useGlobalData from '@docusaurus/useGlobalData'; import DebugLayout from '@theme/DebugLayout'; import DebugJsonView from '@theme/DebugJsonView'; -export default function DebugMetadata(): JSX.Element { +export default function DebugMetadata(): ReactNode { const globalData = useGlobalData(); return ( diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugJsonView/index.tsx b/packages/docusaurus-plugin-debug/src/theme/DebugJsonView/index.tsx index c89445e702..c30a61a323 100644 --- a/packages/docusaurus-plugin-debug/src/theme/DebugJsonView/index.tsx +++ b/packages/docusaurus-plugin-debug/src/theme/DebugJsonView/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import { JsonView, defaultStyles, @@ -30,12 +30,10 @@ const paraisoStyles: JsonViewProps['style'] = { collapseIcon: styles.collapseIconParaiso!, expandIcon: styles.expandIconParaiso!, collapsedContent: styles.collapseContentParaiso!, + childFieldsContainer: styles.childFieldsContainerParaiso!, }; -export default function DebugJsonView({ - src, - collapseDepth, -}: Props): JSX.Element { +export default function DebugJsonView({src, collapseDepth}: Props): ReactNode { return ( diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugRegistry/index.tsx b/packages/docusaurus-plugin-debug/src/theme/DebugRegistry/index.tsx index 59cd4c7c21..c7e8272325 100644 --- a/packages/docusaurus-plugin-debug/src/theme/DebugRegistry/index.tsx +++ b/packages/docusaurus-plugin-debug/src/theme/DebugRegistry/index.tsx @@ -5,12 +5,12 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import registry from '@generated/registry'; import DebugLayout from '@theme/DebugLayout'; import styles from './styles.module.css'; -export default function DebugRegistry(): JSX.Element { +export default function DebugRegistry(): ReactNode { return (

Registry

diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugRoutes/index.tsx b/packages/docusaurus-plugin-debug/src/theme/DebugRoutes/index.tsx index 43b922ba91..8c771e076b 100644 --- a/packages/docusaurus-plugin-debug/src/theme/DebugRoutes/index.tsx +++ b/packages/docusaurus-plugin-debug/src/theme/DebugRoutes/index.tsx @@ -5,13 +5,13 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import routes from '@generated/routes'; import DebugLayout from '@theme/DebugLayout'; import DebugJsonView from '@theme/DebugJsonView'; import styles from './styles.module.css'; -export default function DebugRoutes(): JSX.Element { +export default function DebugRoutes(): ReactNode { return (

Routes

diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugSiteMetadata/index.tsx b/packages/docusaurus-plugin-debug/src/theme/DebugSiteMetadata/index.tsx index c366475762..4f24972834 100644 --- a/packages/docusaurus-plugin-debug/src/theme/DebugSiteMetadata/index.tsx +++ b/packages/docusaurus-plugin-debug/src/theme/DebugSiteMetadata/index.tsx @@ -5,12 +5,12 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import DebugLayout from '@theme/DebugLayout'; import styles from './styles.module.css'; -export default function DebugMetadata(): JSX.Element { +export default function DebugMetadata(): ReactNode { const {siteMetadata} = useDocusaurusContext(); return ( diff --git a/packages/docusaurus-plugin-google-analytics/package.json b/packages/docusaurus-plugin-google-analytics/package.json index d7d01322ae..31c345e396 100644 --- a/packages/docusaurus-plugin-google-analytics/package.json +++ b/packages/docusaurus-plugin-google-analytics/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/plugin-google-analytics", - "version": "3.6.2", + "version": "3.7.0", "description": "Global analytics (analytics.js) plugin for Docusaurus.", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -18,14 +18,14 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/types": "3.6.2", - "@docusaurus/utils-validation": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", "tslib": "^2.6.0" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "engines": { "node": ">=18.0" diff --git a/packages/docusaurus-plugin-google-gtag/package.json b/packages/docusaurus-plugin-google-gtag/package.json index ead7becb33..80036af5b2 100644 --- a/packages/docusaurus-plugin-google-gtag/package.json +++ b/packages/docusaurus-plugin-google-gtag/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/plugin-google-gtag", - "version": "3.6.2", + "version": "3.7.0", "description": "Global Site Tag (gtag.js) plugin for Docusaurus.", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -18,15 +18,15 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/types": "3.6.2", - "@docusaurus/utils-validation": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", "@types/gtag.js": "^0.0.12", "tslib": "^2.6.0" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "engines": { "node": ">=18.0" diff --git a/packages/docusaurus-plugin-google-tag-manager/package.json b/packages/docusaurus-plugin-google-tag-manager/package.json index c4f660d2aa..114d6dd53a 100644 --- a/packages/docusaurus-plugin-google-tag-manager/package.json +++ b/packages/docusaurus-plugin-google-tag-manager/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/plugin-google-tag-manager", - "version": "3.6.2", + "version": "3.7.0", "description": "Google Tag Manager (gtm.js) plugin for Docusaurus.", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -18,14 +18,14 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/types": "3.6.2", - "@docusaurus/utils-validation": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", "tslib": "^2.6.0" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "engines": { "node": ">=18.0" diff --git a/packages/docusaurus-plugin-ideal-image/package.json b/packages/docusaurus-plugin-ideal-image/package.json index 6145ba1b87..8374d3549d 100644 --- a/packages/docusaurus-plugin-ideal-image/package.json +++ b/packages/docusaurus-plugin-ideal-image/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/plugin-ideal-image", - "version": "3.6.2", + "version": "3.7.0", "description": "Docusaurus Plugin to generate an almost ideal image (responsive, lazy-loading, and low quality placeholder).", "main": "lib/index.js", "types": "src/plugin-ideal-image.d.ts", @@ -20,26 +20,26 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/lqip-loader": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/lqip-loader": "3.7.0", "@docusaurus/responsive-loader": "^1.7.0", - "@docusaurus/theme-translations": "3.6.2", - "@docusaurus/types": "3.6.2", - "@docusaurus/utils-validation": "3.6.2", - "@slorber/react-ideal-image": "^0.0.12", + "@docusaurus/theme-translations": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", + "@slorber/react-ideal-image": "^0.0.14", "react-waypoint": "^10.3.0", "sharp": "^0.32.3", "tslib": "^2.6.0", "webpack": "^5.88.1" }, "devDependencies": { - "@docusaurus/module-type-aliases": "3.6.2", + "@docusaurus/module-type-aliases": "3.7.0", "fs-extra": "^11.1.0" }, "peerDependencies": { "jimp": "*", - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "jimp": { diff --git a/packages/docusaurus-plugin-ideal-image/src/deps.d.ts b/packages/docusaurus-plugin-ideal-image/src/deps.d.ts index 654dd16221..13f80f4841 100644 --- a/packages/docusaurus-plugin-ideal-image/src/deps.d.ts +++ b/packages/docusaurus-plugin-ideal-image/src/deps.d.ts @@ -13,7 +13,12 @@ * full state object. */ declare module '@slorber/react-ideal-image' { - import type {ComponentProps, ComponentType, CSSProperties} from 'react'; + import type { + ComponentProps, + ComponentType, + CSSProperties, + ReactNode, + } from 'react'; export type LoadingState = 'initial' | 'loading' | 'loaded' | 'error'; @@ -115,5 +120,5 @@ declare module '@slorber/react-ideal-image' { width: number; } - export default function IdealImage(props: ImageProps): JSX.Element; + export default function IdealImage(props: ImageProps): ReactNode; } diff --git a/packages/docusaurus-plugin-ideal-image/src/index.ts b/packages/docusaurus-plugin-ideal-image/src/index.ts index 4b88621718..66c3c92c44 100644 --- a/packages/docusaurus-plugin-ideal-image/src/index.ts +++ b/packages/docusaurus-plugin-ideal-image/src/index.ts @@ -54,6 +54,12 @@ export default function pluginIdealImage( rules: [ { test: /\.(?:png|jpe?g)$/i, + // We don't want to use the image loader for non-React source code + // ie we don't want to use ideal image loader for CSS files... + // See https://github.com/facebook/docusaurus/issues/10862 + issuer: { + and: [/\.(?:tsx?|jsx?|mdx?)$/i], + }, use: [ require.resolve('@docusaurus/lqip-loader'), { diff --git a/packages/docusaurus-plugin-ideal-image/src/plugin-ideal-image.d.ts b/packages/docusaurus-plugin-ideal-image/src/plugin-ideal-image.d.ts index 561cbfb18a..28191e9816 100644 --- a/packages/docusaurus-plugin-ideal-image/src/plugin-ideal-image.d.ts +++ b/packages/docusaurus-plugin-ideal-image/src/plugin-ideal-image.d.ts @@ -52,7 +52,7 @@ declare module '@docusaurus/plugin-ideal-image' { } declare module '@theme/IdealImage' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export type SrcType = { width: number; @@ -72,5 +72,5 @@ declare module '@theme/IdealImage' { export interface Props extends ComponentProps<'img'> { readonly img: {default: string} | {src: SrcImage; preSrc: string} | string; } - export default function IdealImage(props: Props): JSX.Element; + export default function IdealImage(props: Props): ReactNode; } diff --git a/packages/docusaurus-plugin-ideal-image/src/theme/IdealImage/index.tsx b/packages/docusaurus-plugin-ideal-image/src/theme/IdealImage/index.tsx index 63d40cf63c..a983927ec4 100644 --- a/packages/docusaurus-plugin-ideal-image/src/theme/IdealImage/index.tsx +++ b/packages/docusaurus-plugin-ideal-image/src/theme/IdealImage/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import ReactIdealImage, { type IconKey, type State, @@ -80,7 +80,7 @@ function getMessage(icon: IconKey, state: State) { } } -export default function IdealImage(props: Props): JSX.Element { +export default function IdealImage(props: Props): ReactNode { const {img, ...propsRest} = props; // In dev env just use regular img with original file diff --git a/packages/docusaurus-plugin-pwa/package.json b/packages/docusaurus-plugin-pwa/package.json index 426a7302f5..bf45dd0fa7 100644 --- a/packages/docusaurus-plugin-pwa/package.json +++ b/packages/docusaurus-plugin-pwa/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/plugin-pwa", - "version": "3.6.2", + "version": "3.7.0", "description": "Docusaurus Plugin to add PWA support.", "main": "lib/index.js", "types": "src/plugin-pwa.d.ts", @@ -22,14 +22,14 @@ "dependencies": { "@babel/core": "^7.25.9", "@babel/preset-env": "^7.25.9", - "@docusaurus/bundler": "3.6.2", - "@docusaurus/core": "3.6.2", - "@docusaurus/logger": "3.6.2", - "@docusaurus/theme-common": "3.6.2", - "@docusaurus/theme-translations": "3.6.2", - "@docusaurus/types": "3.6.2", - "@docusaurus/utils": "3.6.2", - "@docusaurus/utils-validation": "3.6.2", + "@docusaurus/bundler": "3.7.0", + "@docusaurus/core": "3.7.0", + "@docusaurus/logger": "3.7.0", + "@docusaurus/theme-common": "3.7.0", + "@docusaurus/theme-translations": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", "babel-loader": "^9.2.1", "clsx": "^2.0.0", "core-js": "^3.31.1", @@ -41,12 +41,12 @@ "workbox-window": "^7.0.0" }, "devDependencies": { - "@docusaurus/module-type-aliases": "3.6.2", + "@docusaurus/module-type-aliases": "3.7.0", "fs-extra": "^11.1.0" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "engines": { "node": ">=18.0" diff --git a/packages/docusaurus-plugin-pwa/src/plugin-pwa.d.ts b/packages/docusaurus-plugin-pwa/src/plugin-pwa.d.ts index 85d6aa0884..b6c0205d16 100644 --- a/packages/docusaurus-plugin-pwa/src/plugin-pwa.d.ts +++ b/packages/docusaurus-plugin-pwa/src/plugin-pwa.d.ts @@ -76,6 +76,8 @@ declare module '@docusaurus/plugin-pwa' { } declare module '@theme/PwaReloadPopup' { + import type {ReactNode} from 'react'; + export interface Props { /** * The popup should call this callback when the `reload` button is clicked. @@ -84,5 +86,5 @@ declare module '@theme/PwaReloadPopup' { */ readonly onReload: () => void; } - export default function PwaReloadPopup(props: Props): JSX.Element; + export default function PwaReloadPopup(props: Props): ReactNode; } diff --git a/packages/docusaurus-plugin-pwa/src/theme/PwaReloadPopup/index.tsx b/packages/docusaurus-plugin-pwa/src/theme/PwaReloadPopup/index.tsx index 66d63d70e0..54222c66e5 100644 --- a/packages/docusaurus-plugin-pwa/src/theme/PwaReloadPopup/index.tsx +++ b/packages/docusaurus-plugin-pwa/src/theme/PwaReloadPopup/index.tsx @@ -5,14 +5,14 @@ * LICENSE file in the root directory of this source tree. */ -import React, {useState} from 'react'; +import React, {type ReactNode, useState} from 'react'; import clsx from 'clsx'; import Translate, {translate} from '@docusaurus/Translate'; import type {Props} from '@theme/PwaReloadPopup'; import styles from './styles.module.css'; -export default function PwaReloadPopup({onReload}: Props): JSX.Element | false { +export default function PwaReloadPopup({onReload}: Props): ReactNode { const [isVisible, setIsVisible] = useState(true); return ( diff --git a/packages/docusaurus-plugin-rsdoctor/package.json b/packages/docusaurus-plugin-rsdoctor/package.json index d5cafb8e5e..1f83d9b186 100644 --- a/packages/docusaurus-plugin-rsdoctor/package.json +++ b/packages/docusaurus-plugin-rsdoctor/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/plugin-rsdoctor", - "version": "3.6.2", + "version": "3.7.0", "description": "Rsdoctor plugin for Docusaurus.", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -18,16 +18,16 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/types": "3.6.2", - "@docusaurus/utils-validation": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", "@rsdoctor/rspack-plugin": "^0.4.6", "@rsdoctor/webpack-plugin": "^0.4.6", "tslib": "^2.6.0" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "engines": { "node": ">=18.0" diff --git a/packages/docusaurus-plugin-sitemap/package.json b/packages/docusaurus-plugin-sitemap/package.json index 2fffc5d538..9689816bc5 100644 --- a/packages/docusaurus-plugin-sitemap/package.json +++ b/packages/docusaurus-plugin-sitemap/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/plugin-sitemap", - "version": "3.6.2", + "version": "3.7.0", "description": "Simple sitemap generation plugin for Docusaurus.", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -18,12 +18,12 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/logger": "3.6.2", - "@docusaurus/types": "3.6.2", - "@docusaurus/utils": "3.6.2", - "@docusaurus/utils-common": "3.6.2", - "@docusaurus/utils-validation": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/logger": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils": "3.7.0", + "@docusaurus/utils-common": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", "fs-extra": "^11.1.1", "sitemap": "^7.1.1", "tslib": "^2.6.0" @@ -32,8 +32,8 @@ "@total-typescript/shoehorn": "^0.1.2" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "engines": { "node": ">=18.0" diff --git a/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemap.test.ts b/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemap.test.ts index f1f152ecb1..8bece909f3 100644 --- a/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemap.test.ts +++ b/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemap.test.ts @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import {createElement} from 'react'; import {fromPartial} from '@total-typescript/shoehorn'; import createSitemap from '../createSitemap'; import type {PluginOptions} from '../options'; @@ -39,7 +38,7 @@ describe('createSitemap', () => { const sitemap = await createSitemap({ siteConfig, routes: routes(['/', '/test']), - head: {}, + routesBuildMetadata: {}, options, }); expect(sitemap).toContain( @@ -51,7 +50,7 @@ describe('createSitemap', () => { const sitemap = await createSitemap({ siteConfig, routes: routes([]), - head: {}, + routesBuildMetadata: {}, options, }); expect(sitemap).toBeNull(); @@ -67,7 +66,7 @@ describe('createSitemap', () => { '/search/foo', '/tags/foo/bar', ]), - head: {}, + routesBuildMetadata: {}, options: { ...options, ignorePatterns: [ @@ -94,7 +93,7 @@ describe('createSitemap', () => { '/search/foo', '/tags/foo/bar', ]), - head: {}, + routesBuildMetadata: {}, options: { ...options, createSitemapItems: async (params) => { @@ -119,7 +118,7 @@ describe('createSitemap', () => { const sitemap = await createSitemap({ siteConfig, routes: routes(['/', '/docs/myDoc/', '/blog/post']), - head: {}, + routesBuildMetadata: {}, options: { ...options, createSitemapItems: async () => { @@ -135,7 +134,7 @@ describe('createSitemap', () => { const sitemap = await createSitemap({ siteConfig, routes: routes(['/', '/test', '/nested/test', '/nested/test2/']), - head: {}, + routesBuildMetadata: {}, options, }); @@ -149,7 +148,7 @@ describe('createSitemap', () => { const sitemap = await createSitemap({ siteConfig: {...siteConfig, trailingSlash: true}, routes: routes(['/', '/test', '/nested/test', '/nested/test2/']), - head: {}, + routesBuildMetadata: {}, options, }); @@ -167,7 +166,7 @@ describe('createSitemap', () => { trailingSlash: false, }, routes: routes(['/', '/test', '/nested/test', '/nested/test2/']), - head: {}, + routesBuildMetadata: {}, options, }); @@ -180,19 +179,10 @@ describe('createSitemap', () => { it('filters pages with noindex', async () => { const sitemap = await createSitemap({ siteConfig, - routesPaths: ['/', '/noindex', '/nested/test', '/nested/test2/'], routes: routes(['/', '/noindex', '/nested/test', '/nested/test2/']), - head: { + routesBuildMetadata: { '/noindex': { - meta: { - // @ts-expect-error: bad lib def - toComponent: () => [ - createElement('meta', { - name: 'robots', - content: 'NoFolloW, NoiNDeX', - }), - ], - }, + noIndex: true, }, }, options, @@ -204,24 +194,13 @@ describe('createSitemap', () => { it('does not generate anything for all pages with noindex', async () => { const sitemap = await createSitemap({ siteConfig, - routesPaths: ['/', '/noindex'], routes: routes(['/', '/noindex']), - head: { + routesBuildMetadata: { '/': { - meta: { - // @ts-expect-error: bad lib def - toComponent: () => [ - createElement('meta', {name: 'robots', content: 'noindex'}), - ], - }, + noIndex: true, }, '/noindex': { - meta: { - // @ts-expect-error: bad lib def - toComponent: () => [ - createElement('meta', {name: 'robots', content: 'noindex'}), - ], - }, + noIndex: true, }, }, options, diff --git a/packages/docusaurus-plugin-sitemap/src/createSitemap.ts b/packages/docusaurus-plugin-sitemap/src/createSitemap.ts index f3f3aace18..aa0f960e8d 100644 --- a/packages/docusaurus-plugin-sitemap/src/createSitemap.ts +++ b/packages/docusaurus-plugin-sitemap/src/createSitemap.ts @@ -10,22 +10,26 @@ import {sitemapItemsToXmlString} from './xml'; import {createSitemapItem} from './createSitemapItem'; import {isNoIndexMetaRoute} from './head'; import type {CreateSitemapItemsFn, CreateSitemapItemsParams} from './types'; -import type {RouteConfig} from '@docusaurus/types'; +import type {RouteConfig, RouteBuildMetadata} from '@docusaurus/types'; import type {PluginOptions} from './options'; -import type {HelmetServerState} from 'react-helmet-async'; // Not all routes should appear in the sitemap, and we should filter: // - parent routes, used for layouts // - routes matching options.ignorePatterns // - routes with no index metadata -function getSitemapRoutes({routes, head, options}: CreateSitemapParams) { +function getSitemapRoutes({ + routes, + routesBuildMetadata, + options, +}: CreateSitemapParams) { const {ignorePatterns} = options; const ignoreMatcher = createMatcher(ignorePatterns); function isRouteExcluded(route: RouteConfig) { return ( - ignoreMatcher(route.path) || isNoIndexMetaRoute({head, route: route.path}) + ignoreMatcher(route.path) || + isNoIndexMetaRoute({routesBuildMetadata, route: route.path}) ); } @@ -33,9 +37,8 @@ function getSitemapRoutes({routes, head, options}: CreateSitemapParams) { } // Our default implementation receives some additional parameters on purpose -// Params such as "head" are "messy" and not directly exposed to the user function createDefaultCreateSitemapItems( - internalParams: Pick, + internalParams: Pick, ): CreateSitemapItemsFn { return async (params) => { const sitemapRoutes = getSitemapRoutes({...params, ...internalParams}); @@ -55,17 +58,17 @@ function createDefaultCreateSitemapItems( } type CreateSitemapParams = CreateSitemapItemsParams & { - head: {[location: string]: HelmetServerState}; + routesBuildMetadata: {[location: string]: RouteBuildMetadata}; options: PluginOptions; }; export default async function createSitemap( params: CreateSitemapParams, ): Promise { - const {head, options, routes, siteConfig} = params; + const {routesBuildMetadata, options, routes, siteConfig} = params; const defaultCreateSitemapItems: CreateSitemapItemsFn = - createDefaultCreateSitemapItems({head, options}); + createDefaultCreateSitemapItems({routesBuildMetadata, options}); const sitemapItems = params.options.createSitemapItems ? await params.options.createSitemapItems({ diff --git a/packages/docusaurus-plugin-sitemap/src/head.ts b/packages/docusaurus-plugin-sitemap/src/head.ts index ed16fdf852..f491a66468 100644 --- a/packages/docusaurus-plugin-sitemap/src/head.ts +++ b/packages/docusaurus-plugin-sitemap/src/head.ts @@ -5,43 +5,21 @@ * LICENSE file in the root directory of this source tree. */ -import type {ReactElement} from 'react'; -import type {HelmetServerState} from 'react-helmet-async'; +import type {RouteBuildMetadata} from '@docusaurus/types'; // Maybe we want to add a routeConfig.metadata.noIndex instead? // But using Helmet is more reliable for third-party plugins... export function isNoIndexMetaRoute({ - head, + routesBuildMetadata, route, }: { - head: {[location: string]: HelmetServerState}; + routesBuildMetadata: {[location: string]: RouteBuildMetadata}; route: string; }): boolean { - const isNoIndexMetaTag = ({ - name, - content, - }: { - name?: string; - content?: string; - }): boolean => { - if (!name || !content) { - return false; - } - return ( - // meta name is not case-sensitive - name.toLowerCase() === 'robots' && - // Robots directives are not case-sensitive - content.toLowerCase().includes('noindex') - ); - }; + const routeBuildMetadata = routesBuildMetadata[route]; - // https://github.com/staylor/react-helmet-async/pull/167 - const meta = head[route]?.meta.toComponent() as unknown as - | ReactElement<{name?: string; content?: string}>[] - | undefined; - return ( - meta?.some((tag) => - isNoIndexMetaTag({name: tag.props.name, content: tag.props.content}), - ) ?? false - ); + if (routeBuildMetadata) { + return routeBuildMetadata.noIndex; + } + return false; } diff --git a/packages/docusaurus-plugin-sitemap/src/index.ts b/packages/docusaurus-plugin-sitemap/src/index.ts index 3bd27f9c26..5bada9d472 100644 --- a/packages/docusaurus-plugin-sitemap/src/index.ts +++ b/packages/docusaurus-plugin-sitemap/src/index.ts @@ -28,7 +28,7 @@ export default function pluginSitemap( return { name: PluginName, - async postBuild({siteConfig, routes, outDir, head}) { + async postBuild({siteConfig, routes, outDir, routesBuildMetadata}) { if (siteConfig.noIndex) { return; } @@ -36,7 +36,7 @@ export default function pluginSitemap( const generatedSitemap = await createSitemap({ siteConfig, routes, - head, + routesBuildMetadata, options, }); if (!generatedSitemap) { diff --git a/packages/docusaurus-plugin-svgr/.npmignore b/packages/docusaurus-plugin-svgr/.npmignore new file mode 100644 index 0000000000..03c9ae1e1b --- /dev/null +++ b/packages/docusaurus-plugin-svgr/.npmignore @@ -0,0 +1,3 @@ +.tsbuildinfo* +tsconfig* +__tests__ diff --git a/packages/docusaurus-plugin-svgr/README.md b/packages/docusaurus-plugin-svgr/README.md new file mode 100644 index 0000000000..27b865208d --- /dev/null +++ b/packages/docusaurus-plugin-svgr/README.md @@ -0,0 +1,7 @@ +# `@docusaurus/plugin-svgr` + +[SVGR](https://react-svgr.com/) plugin for Docusaurus. + +## Usage + +See [plugin-svgr documentation](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-svgr). diff --git a/packages/docusaurus-plugin-svgr/package.json b/packages/docusaurus-plugin-svgr/package.json new file mode 100644 index 0000000000..8cf7096038 --- /dev/null +++ b/packages/docusaurus-plugin-svgr/package.json @@ -0,0 +1,37 @@ +{ + "name": "@docusaurus/plugin-svgr", + "version": "3.7.0", + "description": "SVGR plugin for Docusaurus.", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "scripts": { + "build": "tsc --build", + "watch": "tsc --build --watch" + }, + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/facebook/docusaurus.git", + "directory": "packages/docusaurus-plugin-svgr" + }, + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", + "@svgr/core": "8.1.0", + "@svgr/webpack": "^8.1.0", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "engines": { + "node": ">=18.0" + } +} diff --git a/packages/docusaurus-plugin-svgr/src/__tests__/options.test.ts b/packages/docusaurus-plugin-svgr/src/__tests__/options.test.ts new file mode 100644 index 0000000000..63edff7dd2 --- /dev/null +++ b/packages/docusaurus-plugin-svgr/src/__tests__/options.test.ts @@ -0,0 +1,100 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {normalizePluginOptions} from '@docusaurus/utils-validation'; +import { + validateOptions, + type PluginOptions, + type Options, + DEFAULT_OPTIONS, +} from '../options'; +import type {Validate} from '@docusaurus/types'; + +function validate(options?: Options) { + return validateOptions({ + validate: normalizePluginOptions as Validate< + Options | undefined, + PluginOptions + >, + options, + }); +} + +function result(options?: Options) { + return { + id: 'default', + ...DEFAULT_OPTIONS, + ...options, + }; +} + +describe('validateOptions', () => { + it('accepts undefined', () => { + expect(validate(undefined)).toEqual(result(DEFAULT_OPTIONS)); + }); + + it('accepts empty object', () => { + expect(validate({})).toEqual(result(DEFAULT_OPTIONS)); + }); + + it('accepts defaults', () => { + expect(validate(DEFAULT_OPTIONS)).toEqual(result(DEFAULT_OPTIONS)); + }); + + it('rejects null', () => { + expect( + // @ts-expect-error: TS should error + () => validate(null), + ).toThrowErrorMatchingInlineSnapshot(`""value" must be of type object"`); + }); + + it('rejects number', () => { + expect( + // @ts-expect-error: TS should error + () => validate(42), + ).toThrowErrorMatchingInlineSnapshot(`""value" must be of type object"`); + }); + + describe('svgrConfig', () => { + it('accepts undefined', () => { + expect(validate({svgrConfig: undefined})).toEqual( + result(DEFAULT_OPTIONS), + ); + }); + + it('accepts empty', () => { + expect(validate({svgrConfig: {}})).toEqual(result(DEFAULT_OPTIONS)); + }); + + it('accepts any record', () => { + expect(validate({svgrConfig: {any: 'value', evenNumbers: 42}})).toEqual( + result({ + ...DEFAULT_OPTIONS, + svgrConfig: { + any: 'value', + evenNumbers: 42, + }, + }), + ); + }); + + it('accepts default', () => { + expect(validate({svgrConfig: DEFAULT_OPTIONS.svgrConfig})).toEqual( + result(DEFAULT_OPTIONS), + ); + }); + + it('rejects number values', () => { + expect(() => + // @ts-expect-error: invalid type + validate({svgrConfig: 42}), + ).toThrowErrorMatchingInlineSnapshot( + `""svgrConfig" must be of type object"`, + ); + }); + }); +}); diff --git a/packages/docusaurus-plugin-svgr/src/index.ts b/packages/docusaurus-plugin-svgr/src/index.ts new file mode 100644 index 0000000000..32a9c17b74 --- /dev/null +++ b/packages/docusaurus-plugin-svgr/src/index.ts @@ -0,0 +1,26 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {enhanceConfig} from './svgrLoader'; +import type {LoadContext, Plugin} from '@docusaurus/types'; +import type {PluginOptions, Options} from './options'; + +export default function pluginSVGR( + _context: LoadContext, + options: PluginOptions, +): Plugin { + return { + name: 'docusaurus-plugin-svgr', + configureWebpack: (config, isServer) => { + enhanceConfig(config, {isServer, svgrConfig: options.svgrConfig}); + }, + }; +} + +export {validateOptions} from './options'; + +export type {PluginOptions, Options}; diff --git a/packages/docusaurus-plugin-svgr/src/options.ts b/packages/docusaurus-plugin-svgr/src/options.ts new file mode 100644 index 0000000000..c4cd5c9f37 --- /dev/null +++ b/packages/docusaurus-plugin-svgr/src/options.ts @@ -0,0 +1,41 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import {Joi} from '@docusaurus/utils-validation'; +import type {OptionValidationContext} from '@docusaurus/types'; + +// TODO unfortunately there's a SVGR TS error when skipLibCheck=false +// related to prettier, see https://github.com/gregberge/svgr/issues/904 +// import type {Config as SVGRConfig} from '@svgr/core'; +// export type {SVGRConfig}; +export type SVGRConfig = any; +export type SVGOConfig = NonNullable; + +export type PluginOptions = { + svgrConfig: SVGRConfig; +}; + +export type Options = { + svgrConfig?: Partial; +}; + +export const DEFAULT_OPTIONS: Partial = { + svgrConfig: {}, +}; + +const pluginOptionsSchema = Joi.object({ + svgrConfig: Joi.object() + .pattern(Joi.string(), Joi.any()) + .optional() + .default(DEFAULT_OPTIONS.svgrConfig), +}).default(DEFAULT_OPTIONS); + +export function validateOptions({ + validate, + options, +}: OptionValidationContext): PluginOptions { + return validate(pluginOptionsSchema, options); +} diff --git a/packages/docusaurus-plugin-svgr/src/svgrLoader.ts b/packages/docusaurus-plugin-svgr/src/svgrLoader.ts new file mode 100644 index 0000000000..4520891385 --- /dev/null +++ b/packages/docusaurus-plugin-svgr/src/svgrLoader.ts @@ -0,0 +1,89 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {getFileLoaderUtils} from '@docusaurus/utils'; + +import type {SVGRConfig, SVGOConfig} from './options'; +import type {Configuration, RuleSetRule} from 'webpack'; + +// TODO Docusaurus v4: change these defaults? +// see https://github.com/facebook/docusaurus/issues/8297 +// see https://github.com/facebook/docusaurus/pull/10205 +// see https://github.com/facebook/docusaurus/pull/10211 +const DefaultSVGOConfig: SVGOConfig = { + plugins: [ + { + name: 'preset-default', + params: { + overrides: { + removeTitle: false, + removeViewBox: false, + }, + }, + }, + ], +}; + +const DefaultSVGRConfig: SVGRConfig = { + prettier: false, + svgo: true, + svgoConfig: DefaultSVGOConfig, + titleProp: true, +}; + +type Params = {isServer: boolean; svgrConfig: SVGRConfig}; + +function createSVGRRule(params: Params): RuleSetRule { + const options: SVGRConfig = { + ...DefaultSVGRConfig, + ...params.svgrConfig, + }; + return { + loader: require.resolve('@svgr/webpack'), + options, + }; +} + +export function enhanceConfig(config: Configuration, params: Params): void { + const utils = getFileLoaderUtils(params.isServer); + + const rules = config?.module?.rules as RuleSetRule[]; + + const existingSvgRule: RuleSetRule = (() => { + const rule = rules.find( + (r) => String(r.test) === String(utils.rules.svgs().test), + ); + if (!rule) { + throw new Error( + "Docusaurus built-in SVG rule couldn't be found. The SVGR plugin can't enhance it.", + ); + } + return rule; + })(); + + const newSvgRule: RuleSetRule = { + test: /\.svg$/i, + oneOf: [ + { + use: [createSVGRRule(params)], + // We don't want to use SVGR loader for non-React source code + // ie we don't want to use SVGR for CSS files... + issuer: { + and: [/\.(?:tsx?|jsx?|mdx?)$/i], + }, + }, + existingSvgRule, + ], + }; + + // This is annoying, but we have to "wrap" the existing SVG rule + // Adding another extra SVG rule (first or last) will not "override" + // the default: both rules will be applied (from last to bottom) leading to + // conflicting behavior. + const index = rules.indexOf(existingSvgRule); + rules[index] = newSvgRule; +} diff --git a/packages/docusaurus-plugin-svgr/src/types.d.ts b/packages/docusaurus-plugin-svgr/src/types.d.ts new file mode 100644 index 0000000000..6f6f99f127 --- /dev/null +++ b/packages/docusaurus-plugin-svgr/src/types.d.ts @@ -0,0 +1,8 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/// diff --git a/packages/docusaurus-plugin-svgr/tsconfig.json b/packages/docusaurus-plugin-svgr/tsconfig.json new file mode 100644 index 0000000000..343f87c70b --- /dev/null +++ b/packages/docusaurus-plugin-svgr/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": false + }, + "include": ["src"], + "exclude": ["**/__tests__/**"] +} diff --git a/packages/docusaurus-plugin-vercel-analytics/package.json b/packages/docusaurus-plugin-vercel-analytics/package.json index 0f31fa46d7..8fc89ec527 100644 --- a/packages/docusaurus-plugin-vercel-analytics/package.json +++ b/packages/docusaurus-plugin-vercel-analytics/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/plugin-vercel-analytics", - "version": "3.6.2", + "version": "3.7.0", "description": "Global vercel analytics plugin for Docusaurus.", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -18,17 +18,17 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/logger": "3.6.2", - "@docusaurus/types": "3.6.2", - "@docusaurus/utils": "3.6.2", - "@docusaurus/utils-validation": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/logger": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", "@vercel/analytics": "^1.1.1", "tslib": "^2.6.0" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "engines": { "node": ">=18.0" diff --git a/packages/docusaurus-preset-classic/package.json b/packages/docusaurus-preset-classic/package.json index a00bd11692..cfb770edaa 100644 --- a/packages/docusaurus-preset-classic/package.json +++ b/packages/docusaurus-preset-classic/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/preset-classic", - "version": "3.6.2", + "version": "3.7.0", "description": "Classic preset for Docusaurus.", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -18,23 +18,24 @@ }, "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/plugin-content-blog": "3.6.2", - "@docusaurus/plugin-content-docs": "3.6.2", - "@docusaurus/plugin-content-pages": "3.6.2", - "@docusaurus/plugin-debug": "3.6.2", - "@docusaurus/plugin-google-analytics": "3.6.2", - "@docusaurus/plugin-google-gtag": "3.6.2", - "@docusaurus/plugin-google-tag-manager": "3.6.2", - "@docusaurus/plugin-sitemap": "3.6.2", - "@docusaurus/theme-classic": "3.6.2", - "@docusaurus/theme-common": "3.6.2", - "@docusaurus/theme-search-algolia": "3.6.2", - "@docusaurus/types": "3.6.2" + "@docusaurus/core": "3.7.0", + "@docusaurus/plugin-content-blog": "3.7.0", + "@docusaurus/plugin-content-docs": "3.7.0", + "@docusaurus/plugin-content-pages": "3.7.0", + "@docusaurus/plugin-debug": "3.7.0", + "@docusaurus/plugin-google-analytics": "3.7.0", + "@docusaurus/plugin-google-gtag": "3.7.0", + "@docusaurus/plugin-google-tag-manager": "3.7.0", + "@docusaurus/plugin-sitemap": "3.7.0", + "@docusaurus/plugin-svgr": "3.7.0", + "@docusaurus/theme-classic": "3.7.0", + "@docusaurus/theme-common": "3.7.0", + "@docusaurus/theme-search-algolia": "3.7.0", + "@docusaurus/types": "3.7.0" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "engines": { "node": ">=18.0" diff --git a/packages/docusaurus-preset-classic/src/index.ts b/packages/docusaurus-preset-classic/src/index.ts index 45ae988bc5..eac8c461b3 100644 --- a/packages/docusaurus-preset-classic/src/index.ts +++ b/packages/docusaurus-preset-classic/src/index.ts @@ -37,6 +37,7 @@ export default function preset( blog, pages, sitemap, + svgr, theme, googleAnalytics, gtag, @@ -92,6 +93,9 @@ export default function preset( if (sitemap !== false && (isProd || debug)) { plugins.push(makePluginConfig('@docusaurus/plugin-sitemap', sitemap)); } + if (svgr !== false) { + plugins.push(makePluginConfig('@docusaurus/plugin-svgr', svgr)); + } if (Object.keys(rest).length > 0) { throw new Error( `Unrecognized keys ${Object.keys(rest).join( diff --git a/packages/docusaurus-preset-classic/src/options.ts b/packages/docusaurus-preset-classic/src/options.ts index a8fdb68125..98c4087ac6 100644 --- a/packages/docusaurus-preset-classic/src/options.ts +++ b/packages/docusaurus-preset-classic/src/options.ts @@ -9,6 +9,7 @@ import type {Options as DocsPluginOptions} from '@docusaurus/plugin-content-docs import type {Options as BlogPluginOptions} from '@docusaurus/plugin-content-blog'; import type {Options as PagesPluginOptions} from '@docusaurus/plugin-content-pages'; import type {Options as SitemapPluginOptions} from '@docusaurus/plugin-sitemap'; +import type {Options as SVGRPluginOptions} from '@docusaurus/plugin-svgr'; import type {Options as GAPluginOptions} from '@docusaurus/plugin-google-analytics'; import type {Options as GtagPluginOptions} from '@docusaurus/plugin-google-gtag'; import type {Options as GTMPluginOptions} from '@docusaurus/plugin-google-tag-manager'; @@ -31,6 +32,8 @@ export type Options = { pages?: false | PagesPluginOptions; /** Options for `@docusaurus/plugin-sitemap`. Use `false` to disable. */ sitemap?: false | SitemapPluginOptions; + /** Options for `@docusaurus/plugin-svgr`. Use `false` to disable. */ + svgr?: false | SVGRPluginOptions; /** Options for `@docusaurus/theme-classic`. */ theme?: ThemeOptions; /** diff --git a/packages/docusaurus-remark-plugin-npm2yarn/README.md b/packages/docusaurus-remark-plugin-npm2yarn/README.md index 055ca12d30..e0a08aa30f 100644 --- a/packages/docusaurus-remark-plugin-npm2yarn/README.md +++ b/packages/docusaurus-remark-plugin-npm2yarn/README.md @@ -63,11 +63,11 @@ module.exports = { | Property | Type | Default | Description | | --- | --- | --- | --- | | `sync` | `boolean` | `false` | Syncing tab choices (Yarn and npm). See https://docusaurus.io/docs/markdown-features/#syncing-tab-choices for details. | -| `converters` | `array` | `'yarn'`, `'pnpm'` | The list of converters to use. The order of the converters is important, as the first converter will be used as the default choice. | +| `converters` | `array` | `'yarn'`, `'pnpm'`, `'bun'` | The list of converters to use. The order of the converters is important, as the first converter will be used as the default choice. | ## Custom converters -In case you want to convert npm commands to something else than `yarn` or `pnpm`, you can use custom converters: +In case you want to convert npm commands to something else than `yarn`, `pnpm` or `bun`, you can use custom converters: ```ts type CustomConverter = [name: string, cb: (npmCode: string) => string]; @@ -83,6 +83,7 @@ type CustomConverter = [name: string, cb: (npmCode: string) => string]; converters: [ 'yarn', 'pnpm', + 'bun', ['Turbo', (code) => code.replace(/npm/g, 'turbo')], ], }, diff --git a/packages/docusaurus-remark-plugin-npm2yarn/package.json b/packages/docusaurus-remark-plugin-npm2yarn/package.json index f77d7ca0ba..8fb9dcec69 100644 --- a/packages/docusaurus-remark-plugin-npm2yarn/package.json +++ b/packages/docusaurus-remark-plugin-npm2yarn/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/remark-plugin-npm2yarn", - "version": "3.6.2", + "version": "3.7.0", "description": "Remark plugin for converting npm commands to Yarn commands as tabs.", "main": "lib/index.js", "publishConfig": { diff --git a/packages/docusaurus-remark-plugin-npm2yarn/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-remark-plugin-npm2yarn/src/__tests__/__snapshots__/index.test.ts.snap index adbbcadc9e..797b89fb97 100644 --- a/packages/docusaurus-remark-plugin-npm2yarn/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-remark-plugin-npm2yarn/src/__tests__/__snapshots__/index.test.ts.snap @@ -145,6 +145,30 @@ npm install --save docusaurus-plugin-name " `; +exports[`npm2yarn plugin work with bun converter 1`] = ` +"import Tabs from '@theme/Tabs' +import TabItem from '@theme/TabItem' + +## Installing a plugin + +A plugin is usually a npm package, so you install them like other npm packages using npm. + + + + \`\`\`bash + npm install --save docusaurus-plugin-name + \`\`\` + + + + \`\`\`bash + bun add docusaurus-plugin-name + \`\`\` + + +" +`; + exports[`npm2yarn plugin work with custom converter 1`] = ` "import Tabs from '@theme/Tabs' import TabItem from '@theme/TabItem' diff --git a/packages/docusaurus-remark-plugin-npm2yarn/src/__tests__/index.test.ts b/packages/docusaurus-remark-plugin-npm2yarn/src/__tests__/index.test.ts index 575365c8f2..9cf69eccf7 100644 --- a/packages/docusaurus-remark-plugin-npm2yarn/src/__tests__/index.test.ts +++ b/packages/docusaurus-remark-plugin-npm2yarn/src/__tests__/index.test.ts @@ -109,6 +109,12 @@ describe('npm2yarn plugin', () => { expect(result).toMatchSnapshot(); }); + it('work with bun converter', async () => { + const result = await processFixture('plugin', {converters: ['bun']}); + + expect(result).toMatchSnapshot(); + }); + it('work with custom converter', async () => { const result = await processFixture('plugin', { converters: [['Turbo', (code) => code.replace(/npm/g, 'turbo')]], diff --git a/packages/docusaurus-remark-plugin-npm2yarn/src/index.ts b/packages/docusaurus-remark-plugin-npm2yarn/src/index.ts index 17bd834fb4..9e3a16a777 100644 --- a/packages/docusaurus-remark-plugin-npm2yarn/src/index.ts +++ b/packages/docusaurus-remark-plugin-npm2yarn/src/index.ts @@ -20,7 +20,7 @@ import type {Transformer} from 'unified'; // eslint-disable-next-line @typescript-eslint/no-unused-vars type Plugin = any; // TODO fix this asap -type KnownConverter = 'yarn' | 'pnpm'; +type KnownConverter = 'yarn' | 'pnpm' | 'bun'; type CustomConverter = [name: string, cb: (npmCode: string) => string]; @@ -90,7 +90,7 @@ const transformNode = ( code: npmToYarn(npmCode, converter), node, value: converter, - label: converter === 'yarn' ? 'Yarn' : converter, + label: getLabelForConverter(converter), }); } const [converterName, converterFn] = converter; @@ -101,6 +101,17 @@ const transformNode = ( }); } + function getLabelForConverter(converter: KnownConverter) { + switch (converter) { + case 'yarn': + return 'Yarn'; + case 'bun': + return 'Bun'; + default: + return converter; + } + } + return [ { type: 'mdxJsxFlowElement', diff --git a/packages/docusaurus-theme-classic/package.json b/packages/docusaurus-theme-classic/package.json index 572015db9b..82f9fd44d9 100644 --- a/packages/docusaurus-theme-classic/package.json +++ b/packages/docusaurus-theme-classic/package.json @@ -1,6 +1,6 @@ { "name": "@docusaurus/theme-classic", - "version": "3.6.2", + "version": "3.7.0", "description": "Classic theme for Docusaurus", "main": "lib/index.js", "types": "src/theme-classic.d.ts", @@ -20,19 +20,19 @@ "copy:watch": "node ../../admin/scripts/copyUntypedFiles.js --watch" }, "dependencies": { - "@docusaurus/core": "3.6.2", - "@docusaurus/logger": "3.6.2", - "@docusaurus/mdx-loader": "3.6.2", - "@docusaurus/module-type-aliases": "3.6.2", - "@docusaurus/plugin-content-blog": "3.6.2", - "@docusaurus/plugin-content-docs": "3.6.2", - "@docusaurus/plugin-content-pages": "3.6.2", - "@docusaurus/theme-common": "3.6.2", - "@docusaurus/theme-translations": "3.6.2", - "@docusaurus/types": "3.6.2", - "@docusaurus/utils": "3.6.2", - "@docusaurus/utils-common": "3.6.2", - "@docusaurus/utils-validation": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/logger": "3.7.0", + "@docusaurus/mdx-loader": "3.7.0", + "@docusaurus/module-type-aliases": "3.7.0", + "@docusaurus/plugin-content-blog": "3.7.0", + "@docusaurus/plugin-content-docs": "3.7.0", + "@docusaurus/plugin-content-pages": "3.7.0", + "@docusaurus/theme-common": "3.7.0", + "@docusaurus/theme-translations": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils": "3.7.0", + "@docusaurus/utils-common": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "copy-text-to-clipboard": "^3.2.0", @@ -56,8 +56,8 @@ "utility-types": "^3.10.0" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "engines": { "node": ">=18.0" diff --git a/packages/docusaurus-theme-classic/src/__tests__/options.test.ts b/packages/docusaurus-theme-classic/src/__tests__/options.test.ts index a228aba6f8..0d21ee617c 100644 --- a/packages/docusaurus-theme-classic/src/__tests__/options.test.ts +++ b/packages/docusaurus-theme-classic/src/__tests__/options.test.ts @@ -827,6 +827,110 @@ describe('themeConfig', () => { ); }); }); + + describe('docsVersionDropdown', () => { + describe('versions', () => { + it('accepts array of strings', () => { + const config = { + navbar: { + items: [ + { + type: 'docsVersionDropdown', + versions: ['current', '1.0'], + }, + ], + }, + }; + testValidateThemeConfig(config); + }); + + it('rejects empty array of strings', () => { + const config = { + navbar: { + items: [ + { + type: 'docsVersionDropdown', + versions: [], + }, + ], + }, + }; + expect(() => + testValidateThemeConfig(config), + ).toThrowErrorMatchingInlineSnapshot( + `""navbar.items[0].versions" must contain at least 1 items"`, + ); + }); + + it('rejects array of non-strings', () => { + const config = { + navbar: { + items: [ + { + type: 'docsVersionDropdown', + versions: [1, 2], + }, + ], + }, + }; + expect(() => + testValidateThemeConfig(config), + ).toThrowErrorMatchingInlineSnapshot( + `""navbar.items[0].versions[0]" must be a string"`, + ); + }); + + it('accepts dictionary of version objects', () => { + const config = { + navbar: { + items: [ + { + type: 'docsVersionDropdown', + versions: {current: {}, '1.0': {label: '1.x'}}, + }, + ], + }, + }; + testValidateThemeConfig(config); + }); + + it('rejects empty dictionary of objects', () => { + const config = { + navbar: { + items: [ + { + type: 'docsVersionDropdown', + versions: {}, + }, + ], + }, + }; + expect(() => + testValidateThemeConfig(config), + ).toThrowErrorMatchingInlineSnapshot( + `""navbar.items[0].versions" must have at least 1 key"`, + ); + }); + + it('rejects dictionary of invalid objects', () => { + const config = { + navbar: { + items: [ + { + type: 'docsVersionDropdown', + versions: {current: {}, '1.0': {invalid: '1.x'}}, + }, + ], + }, + }; + expect(() => + testValidateThemeConfig(config), + ).toThrowErrorMatchingInlineSnapshot( + `""navbar.items[0].versions.1.0.invalid" is not allowed"`, + ); + }); + }); + }); }); describe('validateOptions', () => { diff --git a/packages/docusaurus-theme-classic/src/index.ts b/packages/docusaurus-theme-classic/src/index.ts index 568fd070c6..ac2ea69a4c 100644 --- a/packages/docusaurus-theme-classic/src/index.ts +++ b/packages/docusaurus-theme-classic/src/index.ts @@ -14,6 +14,7 @@ import { getAnnouncementBarInlineScript, DataAttributeQueryStringInlineJavaScript, } from './inlineScripts'; +import {SvgSpriteDefs} from './inlineSvgSprites'; import type {LoadContext, Plugin} from '@docusaurus/types'; import type {ThemeConfig} from '@docusaurus/theme-common'; import type {Plugin as PostCssPlugin} from 'postcss'; @@ -121,6 +122,14 @@ export default function themeClassic( injectHtmlTags() { return { preBodyTags: [ + { + tagName: 'svg', + attributes: { + xmlns: 'http://www.w3.org/2000/svg', + style: 'display: none;', + }, + innerHTML: SvgSpriteDefs, + }, { tagName: 'script', innerHTML: ` diff --git a/packages/docusaurus-theme-classic/src/inlineSvgSprites.ts b/packages/docusaurus-theme-classic/src/inlineSvgSprites.ts new file mode 100644 index 0000000000..b729c9bbb5 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/inlineSvgSprites.ts @@ -0,0 +1,12 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// For icons that are heavily repeated in the static html output +// See also https://github.com/facebook/docusaurus/issues/5865 +export const SvgSpriteDefs = ` + +`; diff --git a/packages/docusaurus-theme-classic/src/options.ts b/packages/docusaurus-theme-classic/src/options.ts index 7bd6253565..f4f84b5b1f 100644 --- a/packages/docusaurus-theme-classic/src/options.ts +++ b/packages/docusaurus-theme-classic/src/options.ts @@ -7,6 +7,10 @@ import {themes} from 'prism-react-renderer'; import {Joi, URISchema} from '@docusaurus/utils-validation'; +import type { + PropVersionItem, + PropVersionItems, +} from '@theme/NavbarItem/DocsVersionDropdownNavbarItem'; import type {Options, PluginOptions} from '@docusaurus/theme-classic'; import type {ThemeConfig} from '@docusaurus/theme-common'; import type { @@ -210,6 +214,17 @@ const DocsVersionDropdownNavbarItemSchema = NavbarItemBaseSchema.append({ dropdownActiveClassDisabled: Joi.boolean(), dropdownItemsBefore: Joi.array().items(DropdownSubitemSchema).default([]), dropdownItemsAfter: Joi.array().items(DropdownSubitemSchema).default([]), + versions: Joi.alternatives().try( + Joi.array().items(Joi.string().min(1)).min(1), + Joi.object() + .pattern( + Joi.string().min(1), + Joi.object({ + label: Joi.string().min(1), + }), + ) + .min(1), + ), }); const LocaleDropdownNavbarItemSchema = NavbarItemBaseSchema.append({ @@ -308,6 +323,7 @@ const FooterLinkItemSchema = Joi.object({ href: URISchema, html: Joi.string(), label: Joi.string(), + className: Joi.string(), }) .xor('to', 'href', 'html') .with('to', 'label') @@ -317,6 +333,12 @@ const FooterLinkItemSchema = Joi.object({ // attributes like target, aria-role, data-customAttribute...) .unknown(); +const FooterColumnItemSchema = Joi.object({ + title: Joi.string().allow(null).default(null), + className: Joi.string(), + items: Joi.array().items(FooterLinkItemSchema).default([]), +}); + const LogoSchema = Joi.object({ alt: Joi.string().allow(''), src: Joi.string().required(), @@ -384,12 +406,7 @@ export const ThemeConfigSchema = Joi.object({ logo: LogoSchema, copyright: Joi.string(), links: Joi.alternatives( - Joi.array().items( - Joi.object({ - title: Joi.string().allow(null).default(null), - items: Joi.array().items(FooterLinkItemSchema).default([]), - }), - ), + Joi.array().items(FooterColumnItemSchema), Joi.array().items(FooterLinkItemSchema), ) .messages({ diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index e0d5f47a8e..9ab3d8f903 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -50,51 +50,57 @@ declare module '@theme/Admonition' { readonly className?: string; } - export default function Admonition(props: Props): JSX.Element; + export default function Admonition(props: Props): ReactNode; } declare module '@theme/Admonition/Type/Note' { + import type {ReactNode} from 'react'; import type {Props as AdmonitionProps} from '@theme/Admonition'; export interface Props extends AdmonitionProps {} - export default function AdmonitionTypeNote(props: Props): JSX.Element; + export default function AdmonitionTypeNote(props: Props): ReactNode; } declare module '@theme/Admonition/Type/Info' { + import type {ReactNode} from 'react'; import type {Props as AdmonitionProps} from '@theme/Admonition'; export interface Props extends AdmonitionProps {} - export default function AdmonitionTypeInfo(props: Props): JSX.Element; + export default function AdmonitionTypeInfo(props: Props): ReactNode; } declare module '@theme/Admonition/Type/Tip' { + import type {ReactNode} from 'react'; import type {Props as AdmonitionProps} from '@theme/Admonition'; export interface Props extends AdmonitionProps {} - export default function AdmonitionTypeTip(props: Props): JSX.Element; + export default function AdmonitionTypeTip(props: Props): ReactNode; } // TODO remove before v4: Caution replaced by Warning // see https://github.com/facebook/docusaurus/issues/7558 declare module '@theme/Admonition/Type/Caution' { + import type {ReactNode} from 'react'; import type {Props as AdmonitionProps} from '@theme/Admonition'; export interface Props extends AdmonitionProps {} - export default function AdmonitionTypeCaution(props: Props): JSX.Element; + export default function AdmonitionTypeCaution(props: Props): ReactNode; } declare module '@theme/Admonition/Type/Warning' { + import type {ReactNode} from 'react'; import type {Props as AdmonitionProps} from '@theme/Admonition'; export interface Props extends AdmonitionProps {} - export default function AdmonitionTypeWarning(props: Props): JSX.Element; + export default function AdmonitionTypeWarning(props: Props): ReactNode; } declare module '@theme/Admonition/Type/Danger' { + import type {ReactNode} from 'react'; import type {Props as AdmonitionProps} from '@theme/Admonition'; export interface Props extends AdmonitionProps {} - export default function AdmonitionTypeDanger(props: Props): JSX.Element; + export default function AdmonitionTypeDanger(props: Props): ReactNode; } declare module '@theme/Admonition/Types' { @@ -118,74 +124,79 @@ declare module '@theme/Admonition/Layout' { readonly title?: ReactNode; readonly className?: string; } - export default function AdmonitionLayout(props: Props): JSX.Element; + export default function AdmonitionLayout(props: Props): ReactNode; } declare module '@theme/Admonition/Icon/Note' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function AdmonitionIconNote(props: Props): JSX.Element; + export default function AdmonitionIconNote(props: Props): ReactNode; } declare module '@theme/Admonition/Icon/Tip' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function AdmonitionIconTip(props: Props): JSX.Element; + export default function AdmonitionIconTip(props: Props): ReactNode; } declare module '@theme/Admonition/Icon/Warning' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function AdmonitionIconWarning(props: Props): JSX.Element; + export default function AdmonitionIconWarning(props: Props): ReactNode; } declare module '@theme/Admonition/Icon/Danger' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function AdmonitionIconDanger(props: Props): JSX.Element; + export default function AdmonitionIconDanger(props: Props): ReactNode; } declare module '@theme/Admonition/Icon/Info' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function AdmonitionIconInfo(props: Props): JSX.Element; + export default function AdmonitionIconInfo(props: Props): ReactNode; } declare module '@theme/AnnouncementBar' { - export default function AnnouncementBar(): JSX.Element | null; + import type {ReactNode} from 'react'; + + export default function AnnouncementBar(): ReactNode | null; } declare module '@theme/AnnouncementBar/Content' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'div'> {} - export default function AnnouncementBarContent(props: Props): JSX.Element; + export default function AnnouncementBarContent(props: Props): ReactNode; } declare module '@theme/AnnouncementBar/CloseButton' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'button'> {} - export default function AnnouncementBarCloseButton(props: Props): JSX.Element; + export default function AnnouncementBarCloseButton(props: Props): ReactNode; } declare module '@theme/BackToTopButton' { - export default function BackToTopButton(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function BackToTopButton(): ReactNode; } declare module '@theme/Blog/Components/Author' { + import type {ReactNode} from 'react'; import type {Author} from '@docusaurus/plugin-content-blog'; export interface Props { @@ -195,10 +206,11 @@ declare module '@theme/Blog/Components/Author' { readonly count?: number; } - export default function BlogAuthor(props: Props): JSX.Element; + export default function BlogAuthor(props: Props): ReactNode; } declare module '@theme/Blog/Components/Author/Socials' { + import type {ReactNode} from 'react'; import type {Author} from '@docusaurus/plugin-content-blog'; export interface Props { @@ -206,16 +218,17 @@ declare module '@theme/Blog/Components/Author/Socials' { readonly className?: string; } - export default function BlogAuthorSocials(props: Props): JSX.Element; + export default function BlogAuthorSocials(props: Props): ReactNode; } declare module '@theme/BlogListPaginator' { + import type {ReactNode} from 'react'; import type {BlogPaginatedMetadata} from '@docusaurus/plugin-content-blog'; export interface Props { readonly metadata: BlogPaginatedMetadata; } - export default function BlogListPaginator(props: Props): JSX.Element; + export default function BlogListPaginator(props: Props): ReactNode; } declare module '@theme/BlogSidebar/Content' { @@ -232,33 +245,36 @@ declare module '@theme/BlogSidebar/Content' { } declare module '@theme/BlogSidebar/Desktop' { + import type {ReactNode} from 'react'; import type {BlogSidebar} from '@docusaurus/plugin-content-blog'; export interface Props { readonly sidebar: BlogSidebar; } - export default function BlogSidebarDesktop(props: Props): JSX.Element; + export default function BlogSidebarDesktop(props: Props): ReactNode; } declare module '@theme/BlogSidebar/Mobile' { + import type {ReactNode} from 'react'; import type {BlogSidebar} from '@docusaurus/plugin-content-blog'; export interface Props { readonly sidebar: BlogSidebar; } - export default function BlogSidebarMobile(props: Props): JSX.Element; + export default function BlogSidebarMobile(props: Props): ReactNode; } declare module '@theme/BlogSidebar' { + import type {ReactNode} from 'react'; import type {BlogSidebar} from '@docusaurus/plugin-content-blog'; export interface Props { readonly sidebar?: BlogSidebar; } - export default function BlogSidebar(props: Props): JSX.Element; + export default function BlogSidebar(props: Props): ReactNode; } declare module '@theme/BlogPostItem' { @@ -269,7 +285,7 @@ declare module '@theme/BlogPostItem' { className?: string; } - export default function BlogPostItem(props: Props): JSX.Element; + export default function BlogPostItem(props: Props): ReactNode; } declare module '@theme/BlogPostItems' { @@ -281,7 +297,7 @@ declare module '@theme/BlogPostItems' { component?: ComponentType<{children: ReactNode}>; } - export default function BlogPostItem(props: Props): JSX.Element; + export default function BlogPostItem(props: Props): ReactNode; } declare module '@theme/BlogPostItem/Container' { @@ -292,35 +308,43 @@ declare module '@theme/BlogPostItem/Container' { className?: string; } - export default function BlogPostItemContainer(props: Props): JSX.Element; + export default function BlogPostItemContainer(props: Props): ReactNode; } declare module '@theme/BlogPostItem/Header' { - export default function BlogPostItemHeader(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function BlogPostItemHeader(): ReactNode; } declare module '@theme/BlogPostItem/Header/Title' { + import type {ReactNode} from 'react'; + export interface Props { className?: string; } - export default function BlogPostItemHeaderTitle(props: Props): JSX.Element; + export default function BlogPostItemHeaderTitle(props: Props): ReactNode; } declare module '@theme/BlogPostItem/Header/Info' { + import type {ReactNode} from 'react'; + export interface Props { className?: string; } - export default function BlogPostItemHeaderInfo(): JSX.Element; + export default function BlogPostItemHeaderInfo(): ReactNode; } declare module '@theme/BlogPostItem/Header/Authors' { + import type {ReactNode} from 'react'; + export interface Props { readonly className?: string; } - export default function BlogPostItemHeaderAuthors(props: Props): JSX.Element; + export default function BlogPostItemHeaderAuthors(props: Props): ReactNode; } declare module '@theme/BlogPostItem/Content' { @@ -331,14 +355,17 @@ declare module '@theme/BlogPostItem/Content' { className?: string; } - export default function BlogPostItemContent(props: Props): JSX.Element; + export default function BlogPostItemContent(props: Props): ReactNode; } declare module '@theme/BlogPostItem/Footer' { - export default function BlogPostItemFooter(): JSX.Element | null; + import type {ReactNode} from 'react'; + + export default function BlogPostItemFooter(): ReactNode | null; } declare module '@theme/BlogPostItem/Footer/ReadMoreLink' { + import type {ReactNode} from 'react'; import type {Props as LinkProps} from '@docusaurus/Link'; export type Props = LinkProps & { @@ -347,10 +374,12 @@ declare module '@theme/BlogPostItem/Footer/ReadMoreLink' { export default function BlogPostItemFooterReadMoreLink( props: Props, - ): JSX.Element | null; + ): ReactNode | null; } declare module '@theme/BlogPostPaginator' { + import type {ReactNode} from 'react'; + type Item = {readonly title: string; readonly permalink: string}; export interface Props { @@ -358,7 +387,7 @@ declare module '@theme/BlogPostPaginator' { readonly prevItem?: Item; } - export default function BlogPostPaginator(props: Props): JSX.Element; + export default function BlogPostPaginator(props: Props): ReactNode; } declare module '@theme/BlogLayout' { @@ -371,7 +400,7 @@ declare module '@theme/BlogLayout' { readonly toc?: ReactNode; } - export default function BlogLayout(props: Props): JSX.Element; + export default function BlogLayout(props: Props): ReactNode; } declare module '@theme/CodeBlock' { @@ -383,57 +412,63 @@ declare module '@theme/CodeBlock' { readonly metastring?: string; readonly title?: string; readonly language?: string; - readonly showLineNumbers?: boolean; + readonly showLineNumbers?: boolean | number; } - export default function CodeBlock(props: Props): JSX.Element; + export default function CodeBlock(props: Props): ReactNode; } declare module '@theme/CodeInline' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'code'> {} - export default function CodeInline(props: Props): JSX.Element; + export default function CodeInline(props: Props): ReactNode; } declare module '@theme/CodeBlock/CopyButton' { + import type {ReactNode} from 'react'; + export interface Props { readonly code: string; readonly className?: string; } - export default function CopyButton(props: Props): JSX.Element; + export default function CopyButton(props: Props): ReactNode; } declare module '@theme/CodeBlock/Container' { + import type {ReactNode} from 'react'; import type {ComponentProps} from 'react'; export default function CodeBlockContainer({ as: As, ...props - }: {as: T} & ComponentProps): JSX.Element; + }: {as: T} & ComponentProps): ReactNode; } declare module '@theme/CodeBlock/Content/Element' { + import type {ReactNode} from 'react'; import type {Props} from '@theme/CodeBlock'; export type {Props}; - export default function CodeBlockElementContent(props: Props): JSX.Element; + export default function CodeBlockElementContent(props: Props): ReactNode; } declare module '@theme/CodeBlock/Content/String' { + import type {ReactNode} from 'react'; import type {Props as CodeBlockProps} from '@theme/CodeBlock'; export interface Props extends Omit { readonly children: string; } - export default function CodeBlockStringContent(props: Props): JSX.Element; + export default function CodeBlockStringContent(props: Props): ReactNode; } declare module '@theme/CodeBlock/Line' { + import type {ReactNode} from 'react'; import type { LineInputProps, LineOutputProps, @@ -450,30 +485,34 @@ declare module '@theme/CodeBlock/Line' { readonly getTokenProps: (input: TokenInputProps) => TokenOutputProps; } - export default function CodeBlockLine(props: Props): JSX.Element; + export default function CodeBlockLine(props: Props): ReactNode; } declare module '@theme/CodeBlock/WordWrapButton' { + import type {ReactNode} from 'react'; + export interface Props { readonly className?: string; readonly onClick: React.MouseEventHandler; readonly isEnabled: boolean; } - export default function WordWrapButton(props: Props): JSX.Element; + export default function WordWrapButton(props: Props): ReactNode; } declare module '@theme/DocCard' { + import type {ReactNode} from 'react'; import type {PropSidebarItem} from '@docusaurus/plugin-content-docs'; export interface Props { readonly item: PropSidebarItem; } - export default function DocCard(props: Props): JSX.Element; + export default function DocCard(props: Props): ReactNode; } declare module '@theme/DocCardList' { + import type {ReactNode} from 'react'; import type {PropSidebarItem} from '@docusaurus/plugin-content-docs'; export interface Props { @@ -481,43 +520,57 @@ declare module '@theme/DocCardList' { readonly className?: string; } - export default function DocCardList(props: Props): JSX.Element; + export default function DocCardList(props: Props): ReactNode; } declare module '@theme/DocItem/Layout' { + import type {ReactNode} from 'react'; + export interface Props { - readonly children: JSX.Element; + readonly children: ReactNode; } - export default function DocItemLayout(props: Props): JSX.Element; + export default function DocItemLayout(props: Props): ReactNode; } declare module '@theme/DocItem/Metadata' { - export default function DocItemMetadata(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function DocItemMetadata(): ReactNode; } declare module '@theme/DocItem/Content' { + import type {ReactNode} from 'react'; + export interface Props { - readonly children: JSX.Element; + readonly children: ReactNode; } - export default function DocItemContent(props: Props): JSX.Element; + export default function DocItemContent(props: Props): ReactNode; } declare module '@theme/DocItem/TOC/Mobile' { - export default function DocItemTOCMobile(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function DocItemTOCMobile(): ReactNode; } declare module '@theme/DocItem/TOC/Desktop' { - export default function DocItemTOCDesktop(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function DocItemTOCDesktop(): ReactNode; } declare module '@theme/DocItem/Paginator' { - export default function DocItemPaginator(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function DocItemPaginator(): ReactNode; } declare module '@theme/DocItem/Footer' { - export default function DocItemFooter(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function DocItemFooter(): ReactNode; } declare module '@theme/DocRoot/Layout' { @@ -527,11 +580,11 @@ declare module '@theme/DocRoot/Layout' { readonly children: ReactNode; } - export default function DocRootLayout(props: Props): JSX.Element; + export default function DocRootLayout(props: Props): ReactNode; } declare module '@theme/DocRoot/Layout/Sidebar' { - import type {Dispatch, SetStateAction} from 'react'; + import type {Dispatch, SetStateAction, ReactNode} from 'react'; import type {PropSidebar} from '@docusaurus/plugin-content-docs'; export interface Props { @@ -540,17 +593,19 @@ declare module '@theme/DocRoot/Layout/Sidebar' { readonly setHiddenSidebarContainer: Dispatch>; } - export default function DocRootLayoutSidebar(props: Props): JSX.Element; + export default function DocRootLayoutSidebar(props: Props): ReactNode; } declare module '@theme/DocRoot/Layout/Sidebar/ExpandButton' { + import type {ReactNode} from 'react'; + export interface Props { toggleSidebar: () => void; } export default function DocRootLayoutSidebarExpandButton( props: Props, - ): JSX.Element; + ): ReactNode; } declare module '@theme/DocRoot/Layout/Main' { @@ -561,19 +616,23 @@ declare module '@theme/DocRoot/Layout/Main' { readonly children: ReactNode; } - export default function DocRootLayoutMain(props: Props): JSX.Element; + export default function DocRootLayoutMain(props: Props): ReactNode; } declare module '@theme/DocPaginator' { + import type {ReactNode} from 'react'; import type {PropNavigation} from '@docusaurus/plugin-content-docs'; // May be simpler to provide a {navigation: PropNavigation} prop? - export interface Props extends PropNavigation {} + export interface Props extends PropNavigation { + className?: string; + } - export default function DocPaginator(props: Props): JSX.Element; + export default function DocPaginator(props: Props): ReactNode; } declare module '@theme/DocSidebar' { + import type {ReactNode} from 'react'; import type {PropSidebarItem} from '@docusaurus/plugin-content-docs'; export interface Props { @@ -583,26 +642,29 @@ declare module '@theme/DocSidebar' { readonly isHidden: boolean; } - export default function DocSidebar(props: Props): JSX.Element; + export default function DocSidebar(props: Props): ReactNode; } declare module '@theme/DocSidebar/Mobile' { + import type {ReactNode} from 'react'; import type {Props as DocSidebarProps} from '@theme/DocSidebar'; export interface Props extends DocSidebarProps {} - export default function DocSidebarMobile(props: Props): JSX.Element; + export default function DocSidebarMobile(props: Props): ReactNode; } declare module '@theme/DocSidebar/Desktop' { + import type {ReactNode} from 'react'; import type {Props as DocSidebarProps} from '@theme/DocSidebar'; export interface Props extends DocSidebarProps {} - export default function DocSidebarDesktop(props: Props): JSX.Element; + export default function DocSidebarDesktop(props: Props): ReactNode; } declare module '@theme/DocSidebar/Desktop/Content' { + import type {ReactNode} from 'react'; import type {PropSidebarItem} from '@docusaurus/plugin-content-docs'; export interface Props { @@ -611,18 +673,21 @@ declare module '@theme/DocSidebar/Desktop/Content' { readonly sidebar: readonly PropSidebarItem[]; } - export default function Content(props: Props): JSX.Element; + export default function Content(props: Props): ReactNode; } declare module '@theme/DocSidebar/Desktop/CollapseButton' { + import type {ReactNode} from 'react'; + export interface Props { readonly onClick: React.MouseEventHandler; } - export default function CollapseButton(props: Props): JSX.Element; + export default function CollapseButton(props: Props): ReactNode; } declare module '@theme/DocSidebarItem' { + import type {ReactNode} from 'react'; import type {PropSidebarItem} from '@docusaurus/plugin-content-docs'; export interface Props { @@ -634,10 +699,11 @@ declare module '@theme/DocSidebarItem' { readonly index: number; } - export default function DocSidebarItem(props: Props): JSX.Element; + export default function DocSidebarItem(props: Props): ReactNode; } declare module '@theme/DocSidebarItem/Link' { + import type {ReactNode} from 'react'; import type {Props as DocSidebarItemProps} from '@theme/DocSidebarItem'; import type {PropSidebarItemLink} from '@docusaurus/plugin-content-docs'; @@ -646,10 +712,11 @@ declare module '@theme/DocSidebarItem/Link' { readonly item: PropSidebarItemLink; } - export default function DocSidebarItemLink(props: Props): JSX.Element; + export default function DocSidebarItemLink(props: Props): ReactNode; } declare module '@theme/DocSidebarItem/Html' { + import type {ReactNode} from 'react'; import type {Props as DocSidebarItemProps} from '@theme/DocSidebarItem'; import type {PropSidebarItemHtml} from '@docusaurus/plugin-content-docs'; @@ -657,10 +724,11 @@ declare module '@theme/DocSidebarItem/Html' { readonly item: PropSidebarItemHtml; } - export default function DocSidebarItemHtml(props: Props): JSX.Element; + export default function DocSidebarItemHtml(props: Props): ReactNode; } declare module '@theme/DocSidebarItem/Category' { + import type {ReactNode} from 'react'; import type {Props as DocSidebarItemProps} from '@theme/DocSidebarItem'; import type {PropSidebarItemCategory} from '@docusaurus/plugin-content-docs'; @@ -668,10 +736,11 @@ declare module '@theme/DocSidebarItem/Category' { readonly item: PropSidebarItemCategory; } - export default function DocSidebarItemCategory(props: Props): JSX.Element; + export default function DocSidebarItemCategory(props: Props): ReactNode; } declare module '@theme/DocSidebarItems' { + import type {ReactNode} from 'react'; import type {Props as DocSidebarItemProps} from '@theme/DocSidebarItem'; import type {PropSidebarItem} from '@docusaurus/plugin-content-docs'; @@ -679,44 +748,54 @@ declare module '@theme/DocSidebarItems' { readonly items: readonly PropSidebarItem[]; } - export default function DocSidebarItems(props: Props): JSX.Element; + export default function DocSidebarItems(props: Props): ReactNode; } declare module '@theme/DocVersionBanner' { + import type {ReactNode} from 'react'; + export interface Props { readonly className?: string; } - export default function DocVersionBanner(props: Props): JSX.Element; + export default function DocVersionBanner(props: Props): ReactNode; } declare module '@theme/DocVersionBadge' { + import type {ReactNode} from 'react'; + export interface Props { readonly className?: string; } - export default function DocVersionBadge(props: Props): JSX.Element; + export default function DocVersionBadge(props: Props): ReactNode; } declare module '@theme/DocVersionSuggestions' { - export default function DocVersionSuggestions(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function DocVersionSuggestions(): ReactNode; } declare module '@theme/EditMetaRow' { + import type {ReactNode} from 'react'; + export interface Props { readonly className: string; readonly editUrl: string | null | undefined; readonly lastUpdatedAt: number | undefined; readonly lastUpdatedBy: string | undefined; } - export default function EditMetaRow(props: Props): JSX.Element; + export default function EditMetaRow(props: Props): ReactNode; } declare module '@theme/EditThisPage' { + import type {ReactNode} from 'react'; + export interface Props { readonly editUrl: string; } - export default function EditThisPage(props: Props): JSX.Element; + export default function EditThisPage(props: Props): ReactNode; } declare module '@theme/ErrorPageContent' { @@ -727,35 +806,43 @@ declare module '@theme/ErrorPageContent' { } declare module '@theme/Footer' { - export default function Footer(): JSX.Element | null; + import type {ReactNode} from 'react'; + + export default function Footer(): ReactNode | null; } declare module '@theme/Footer/Logo' { + import type {ReactNode} from 'react'; + import type {FooterLogo} from '@docusaurus/theme-common'; export interface Props { readonly logo: FooterLogo; } - export default function FooterLogo(props: Props): JSX.Element; + export default function FooterLogo(props: Props): ReactNode; } declare module '@theme/Footer/Copyright' { + import type {ReactNode} from 'react'; + export interface Props { readonly copyright: string; } - export default function FooterCopyright(props: Props): JSX.Element; + export default function FooterCopyright(props: Props): ReactNode; } declare module '@theme/Footer/LinkItem' { + import type {ReactNode} from 'react'; + import type {FooterLinkItem} from '@docusaurus/theme-common'; export interface Props { readonly item: FooterLinkItem; } - export default function FooterLinkItem(props: Props): JSX.Element; + export default function FooterLinkItem(props: Props): ReactNode; } declare module '@theme/Footer/Layout' { @@ -768,41 +855,44 @@ declare module '@theme/Footer/Layout' { readonly copyright: ReactNode; } - export default function FooterLayout(props: Props): JSX.Element; + export default function FooterLayout(props: Props): ReactNode; } declare module '@theme/Footer/Links' { + import type {ReactNode} from 'react'; import type {Footer} from '@docusaurus/theme-common'; export interface Props { readonly links: Footer['links']; } - export default function FooterLinks(props: Props): JSX.Element; + export default function FooterLinks(props: Props): ReactNode; } declare module '@theme/Footer/Links/MultiColumn' { + import type {ReactNode} from 'react'; import type {MultiColumnFooter} from '@docusaurus/theme-common'; export interface Props { readonly columns: MultiColumnFooter['links']; } - export default function FooterLinksMultiColumn(props: Props): JSX.Element; + export default function FooterLinksMultiColumn(props: Props): ReactNode; } declare module '@theme/Footer/Links/Simple' { + import type {ReactNode} from 'react'; import type {SimpleFooter} from '@docusaurus/theme-common'; export interface Props { readonly links: SimpleFooter['links']; } - export default function FooterLinksSimple(props: Props): JSX.Element; + export default function FooterLinksSimple(props: Props): ReactNode; } declare module '@theme/Heading' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; type HeadingType = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; @@ -810,15 +900,17 @@ declare module '@theme/Heading' { readonly as: HeadingType; } - export default function Heading(props: Props): JSX.Element; + export default function Heading(props: Props): ReactNode; } declare module '@theme/NotFound/Content' { + import type {ReactNode} from 'react'; + export interface Props { readonly className?: string; } - export default function NotFoundContent(props: Props): JSX.Element; + export default function NotFoundContent(props: Props): ReactNode; } declare module '@theme/Layout' { @@ -834,7 +926,7 @@ declare module '@theme/Layout' { readonly description?: string; } - export default function Layout(props: Props): JSX.Element; + export default function Layout(props: Props): ReactNode; } declare module '@theme/Layout/Provider' { @@ -844,99 +936,105 @@ declare module '@theme/Layout/Provider' { readonly children: ReactNode; } - export default function LayoutProvider(props: Props): JSX.Element; + export default function LayoutProvider(props: Props): ReactNode; } declare module '@theme/SearchMetadata' { + import type {ReactNode} from 'react'; + export interface Props { readonly locale?: string; readonly version?: string; readonly tag?: string; } - export default function SearchMetadata(props: Props): JSX.Element; + export default function SearchMetadata(props: Props): ReactNode; } declare module '@theme/LastUpdated' { + import type {ReactNode} from 'react'; + export interface Props { readonly lastUpdatedAt?: number; readonly lastUpdatedBy?: string; } - export default function LastUpdated(props: Props): JSX.Element; + export default function LastUpdated(props: Props): ReactNode; } declare module '@theme/SkipToContent' { - export default function SkipToContent(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function SkipToContent(): ReactNode; } declare module '@theme/MDXComponents/A' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'a'> {} - export default function MDXA(props: Props): JSX.Element; + export default function MDXA(props: Props): ReactNode; } declare module '@theme/MDXComponents/Code' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'code'> {} - export default function MDXCode(props: Props): JSX.Element; + export default function MDXCode(props: Props): ReactNode; } declare module '@theme/MDXComponents/Details' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'details'> {} - export default function MDXDetails(props: Props): JSX.Element; + export default function MDXDetails(props: Props): ReactNode; } declare module '@theme/MDXComponents/Ul' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'ul'> {} - export default function MDXUl(props: Props): JSX.Element; + export default function MDXUl(props: Props): ReactNode; } declare module '@theme/MDXComponents/Li' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'li'> {} - export default function MDXLi(props: Props): JSX.Element; + export default function MDXLi(props: Props): ReactNode; } declare module '@theme/MDXComponents/Img' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'img'> {} - export default function MDXImg(props: Props): JSX.Element; + export default function MDXImg(props: Props): ReactNode; } declare module '@theme/MDXComponents/Heading' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; import type Heading from '@theme/Heading'; export interface Props extends ComponentProps {} - export default function MDXHeading(props: Props): JSX.Element; + export default function MDXHeading(props: Props): ReactNode; } declare module '@theme/MDXComponents/Pre' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'pre'> {} - export default function MDXPre(props: Props): JSX.Element; + export default function MDXPre(props: Props): ReactNode; } declare module '@theme/MDXComponents' { - import type {ComponentType, ComponentProps} from 'react'; + import type {ComponentType, ComponentProps, ReactNode} from 'react'; import type MDXCode from '@theme/MDXComponents/Code'; import type MDXA from '@theme/MDXComponents/A'; @@ -962,12 +1060,12 @@ declare module '@theme/MDXComponents' { readonly pre: typeof MDXPre; readonly ul: typeof MDXUl; readonly img: typeof MDXImg; - readonly h1: (props: ComponentProps<'h1'>) => JSX.Element; - readonly h2: (props: ComponentProps<'h2'>) => JSX.Element; - readonly h3: (props: ComponentProps<'h3'>) => JSX.Element; - readonly h4: (props: ComponentProps<'h4'>) => JSX.Element; - readonly h5: (props: ComponentProps<'h5'>) => JSX.Element; - readonly h6: (props: ComponentProps<'h6'>) => JSX.Element; + readonly h1: (props: ComponentProps<'h1'>) => ReactNode; + readonly h2: (props: ComponentProps<'h2'>) => ReactNode; + readonly h3: (props: ComponentProps<'h3'>) => ReactNode; + readonly h4: (props: ComponentProps<'h4'>) => ReactNode; + readonly h5: (props: ComponentProps<'h5'>) => ReactNode; + readonly h6: (props: ComponentProps<'h6'>) => ReactNode; readonly admonition: typeof Admonition; readonly mermaid: typeof Mermaid; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -985,41 +1083,51 @@ declare module '@theme/MDXContent' { readonly children: ReactNode; } - export default function MDXContent(props: Props): JSX.Element; + export default function MDXContent(props: Props): ReactNode; } declare module '@theme/Navbar' { - export default function Navbar(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function Navbar(): ReactNode; } declare module '@theme/Navbar/ColorModeToggle' { + import type {ReactNode} from 'react'; + export interface Props { readonly className?: string; } - export default function NavbarColorModeToggle( - props: Props, - ): JSX.Element | null; + export default function NavbarColorModeToggle(props: Props): ReactNode | null; } declare module '@theme/Navbar/Logo' { - export default function NavbarLogo(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function NavbarLogo(): ReactNode; } declare module '@theme/Navbar/Content' { - export default function NavbarContent(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function NavbarContent(): ReactNode; } declare module '@theme/Navbar/Layout' { + import type {ReactNode} from 'react'; + export interface Props { readonly children: React.ReactNode; } - export default function NavbarLayout(props: Props): JSX.Element; + export default function NavbarLayout(props: Props): ReactNode; } declare module '@theme/Navbar/MobileSidebar' { - export default function NavbarMobileSidebar(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function NavbarMobileSidebar(): ReactNode; } declare module '@theme/Navbar/MobileSidebar/Layout' { @@ -1031,23 +1139,31 @@ declare module '@theme/Navbar/MobileSidebar/Layout' { readonly secondaryMenu: ReactNode; } - export default function NavbarMobileSidebarLayout(props: Props): JSX.Element; + export default function NavbarMobileSidebarLayout(props: Props): ReactNode; } declare module '@theme/Navbar/MobileSidebar/Toggle' { - export default function NavbarMobileSidebarToggle(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function NavbarMobileSidebarToggle(): ReactNode; } declare module '@theme/Navbar/MobileSidebar/PrimaryMenu' { - export default function NavbarMobileSidebarPrimaryMenu(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function NavbarMobileSidebarPrimaryMenu(): ReactNode; } declare module '@theme/Navbar/MobileSidebar/SecondaryMenu' { - export default function NavbarMobileSidebarSecondaryMenu(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function NavbarMobileSidebarSecondaryMenu(): ReactNode; } declare module '@theme/Navbar/MobileSidebar/Header' { - export default function NavbarMobileSidebarHeader(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function NavbarMobileSidebarHeader(): ReactNode; } declare module '@theme/Navbar/Search' { @@ -1058,10 +1174,11 @@ declare module '@theme/Navbar/Search' { readonly className?: string; } - export default function NavbarSearch(props: Props): JSX.Element; + export default function NavbarSearch(props: Props): ReactNode; } declare module '@theme/NavbarItem/DefaultNavbarItem' { + import type {ReactNode} from 'react'; import type {Props as NavbarNavLinkProps} from '@theme/NavbarItem/NavbarNavLink'; export type DesktopOrMobileNavBarItemProps = NavbarNavLinkProps & { @@ -1074,7 +1191,7 @@ declare module '@theme/NavbarItem/DefaultNavbarItem' { readonly mobile?: boolean; } - export default function DefaultNavbarItem(props: Props): JSX.Element; + export default function DefaultNavbarItem(props: Props): ReactNode; } declare module '@theme/NavbarItem/NavbarNavLink' { @@ -1091,10 +1208,11 @@ declare module '@theme/NavbarItem/NavbarNavLink' { readonly isDropdownLink?: boolean; } - export default function NavbarNavLink(props: Props): JSX.Element; + export default function NavbarNavLink(props: Props): ReactNode; } declare module '@theme/NavbarItem/DropdownNavbarItem' { + import type {ReactNode} from 'react'; import type {Props as NavbarNavLinkProps} from '@theme/NavbarItem/NavbarNavLink'; import type {LinkLikeNavbarItemProps} from '@theme/NavbarItem'; @@ -1108,19 +1226,22 @@ declare module '@theme/NavbarItem/DropdownNavbarItem' { readonly mobile?: boolean; } - export default function DropdownNavbarItem(props: Props): JSX.Element; + export default function DropdownNavbarItem(props: Props): ReactNode; } declare module '@theme/NavbarItem/SearchNavbarItem' { + import type {ReactNode} from 'react'; + export interface Props { readonly mobile?: boolean; readonly className?: string; } - export default function SearchNavbarItem(props: Props): JSX.Element; + export default function SearchNavbarItem(props: Props): ReactNode; } declare module '@theme/NavbarItem/LocaleDropdownNavbarItem' { + import type {ReactNode} from 'react'; import type {Props as DropdownNavbarItemProps} from '@theme/NavbarItem/DropdownNavbarItem'; import type {LinkLikeNavbarItemProps} from '@theme/NavbarItem'; @@ -1130,36 +1251,50 @@ declare module '@theme/NavbarItem/LocaleDropdownNavbarItem' { readonly queryString?: string; } - export default function LocaleDropdownNavbarItem(props: Props): JSX.Element; + export default function LocaleDropdownNavbarItem(props: Props): ReactNode; } declare module '@theme/NavbarItem/DocsVersionDropdownNavbarItem' { + import type {ReactNode} from 'react'; import type {Props as DropdownNavbarItemProps} from '@theme/NavbarItem/DropdownNavbarItem'; import type {LinkLikeNavbarItemProps} from '@theme/NavbarItem'; + type PropVersionItem = { + readonly label?: string; + }; + + type PropVersionItems = { + readonly [version: string]: PropVersionItem; + }; + + type PropVersions = string[] | PropVersionItems; + export interface Props extends DropdownNavbarItemProps { readonly docsPluginId?: string; readonly dropdownActiveClassDisabled?: boolean; readonly dropdownItemsBefore: LinkLikeNavbarItemProps[]; readonly dropdownItemsAfter: LinkLikeNavbarItemProps[]; + readonly versions?: PropVersions; } export default function DocsVersionDropdownNavbarItem( props: Props, - ): JSX.Element; + ): ReactNode; } declare module '@theme/NavbarItem/DocsVersionNavbarItem' { + import type {ReactNode} from 'react'; import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem'; export interface Props extends DefaultNavbarItemProps { readonly docsPluginId?: string; } - export default function DocsVersionNavbarItem(props: Props): JSX.Element; + export default function DocsVersionNavbarItem(props: Props): ReactNode; } declare module '@theme/NavbarItem/DocNavbarItem' { + import type {ReactNode} from 'react'; import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem'; export interface Props extends DefaultNavbarItemProps { @@ -1167,12 +1302,11 @@ declare module '@theme/NavbarItem/DocNavbarItem' { readonly docsPluginId?: string; } - export default function DocsSidebarNavbarItem( - props: Props, - ): JSX.Element | null; + export default function DocsSidebarNavbarItem(props: Props): ReactNode | null; } declare module '@theme/NavbarItem/DocSidebarNavbarItem' { + import type {ReactNode} from 'react'; import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem'; export interface Props extends DefaultNavbarItemProps { @@ -1180,17 +1314,18 @@ declare module '@theme/NavbarItem/DocSidebarNavbarItem' { readonly docsPluginId?: string; } - export default function DocSidebarNavbarItem(props: Props): JSX.Element; + export default function DocSidebarNavbarItem(props: Props): ReactNode; } declare module '@theme/NavbarItem/HtmlNavbarItem' { + import type {ReactNode} from 'react'; import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem'; export interface Props extends DefaultNavbarItemProps { readonly value: string; } - export default function HtmlNavbarItem(props: Props): JSX.Element; + export default function HtmlNavbarItem(props: Props): ReactNode; } declare module '@theme/NavbarItem/ComponentTypes' { @@ -1225,7 +1360,7 @@ declare module '@theme/NavbarItem/ComponentTypes' { } declare module '@theme/NavbarItem' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem'; import type {Props as DocNavbarItemProps} from '@theme/NavbarItem/DocNavbarItem'; import type {Props as DocSidebarNavbarItemProps} from '@theme/NavbarItem/DocSidebarNavbarItem'; @@ -1259,7 +1394,7 @@ declare module '@theme/NavbarItem' { export type NavbarItemType = Props['type']; - export default function NavbarItem(props: Props): JSX.Element; + export default function NavbarItem(props: Props): ReactNode; } declare module '@theme/PaginatorNavLink' { @@ -1268,43 +1403,50 @@ declare module '@theme/PaginatorNavLink' { export interface Props extends Omit { readonly title: ReactNode; - readonly subLabel?: JSX.Element; + readonly subLabel?: ReactNode; readonly isNext?: boolean; } - export default function PaginatorNavLink(props: Props): JSX.Element; + export default function PaginatorNavLink(props: Props): ReactNode; } declare module '@theme/SearchBar' { - export default function SearchBar(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function SearchBar(): ReactNode; } declare module '@theme/Mermaid' { + import type {ReactNode} from 'react'; + export interface Props { value: string; } - export default function Mermaid(props: Props): JSX.Element; + export default function Mermaid(props: Props): ReactNode; } declare module '@theme/TabItem' { + import type {ReactNode} from 'react'; + import type {TabItemProps} from '@docusaurus/theme-common/internal'; export interface Props extends TabItemProps {} - export default function TabItem(props: Props): JSX.Element; + export default function TabItem(props: Props): ReactNode; } declare module '@theme/Tabs' { + import type {ReactNode} from 'react'; import type {TabsProps} from '@docusaurus/theme-common/internal'; export interface Props extends TabsProps {} - export default function Tabs(props: Props): JSX.Element; + export default function Tabs(props: Props): ReactNode; } declare module '@theme/ThemedImage' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends Omit, 'src'> { readonly sources: { @@ -1313,7 +1455,7 @@ declare module '@theme/ThemedImage' { }; } - export default function ThemedImage(props: Props): JSX.Element; + export default function ThemedImage(props: Props): ReactNode; } declare module '@theme/Details' { @@ -1324,6 +1466,7 @@ declare module '@theme/Details' { } declare module '@theme/TOCItems' { + import type {ReactNode} from 'react'; import type {TOCItem} from '@docusaurus/mdx-loader'; export interface Props { @@ -1335,10 +1478,11 @@ declare module '@theme/TOCItems' { readonly linkActiveClassName?: string; } - export default function TOCItems(props: Props): JSX.Element; + export default function TOCItems(props: Props): ReactNode; } declare module '@theme/TOCItems/Tree' { + import type {ReactNode} from 'react'; import type {TOCTreeNode} from '@docusaurus/theme-common/internal'; export interface Props { @@ -1348,10 +1492,11 @@ declare module '@theme/TOCItems/Tree' { readonly isChild?: boolean; } - export default function TOCItems(props: Props): JSX.Element; + export default function TOCItems(props: Props): ReactNode; } declare module '@theme/TOC' { + import type {ReactNode} from 'react'; import type {TOCItem} from '@docusaurus/mdx-loader'; // `minHeadingLevel` only comes from doc/post front matter, and won't have a @@ -1363,10 +1508,11 @@ declare module '@theme/TOC' { readonly className?: string; } - export default function TOC(props: Props): JSX.Element; + export default function TOC(props: Props): ReactNode; } declare module '@theme/TOCInline' { + import type {ReactNode} from 'react'; import type {TOCItem} from '@docusaurus/mdx-loader'; export interface Props { @@ -1375,10 +1521,11 @@ declare module '@theme/TOCInline' { readonly maxHeadingLevel?: number; } - export default function TOCInline(props: Props): JSX.Element; + export default function TOCInline(props: Props): ReactNode; } declare module '@theme/TOCCollapsible' { + import type {ReactNode} from 'react'; import type {TOCItem} from '@docusaurus/mdx-loader'; export interface Props { @@ -1388,22 +1535,21 @@ declare module '@theme/TOCCollapsible' { readonly toc: readonly TOCItem[]; } - export default function TOCCollapsible(props: Props): JSX.Element; + export default function TOCCollapsible(props: Props): ReactNode; } declare module '@theme/TOCCollapsible/CollapseButton' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'button'> { collapsed: boolean; } - export default function TOCCollapsibleCollapseButton( - props: Props, - ): JSX.Element; + export default function TOCCollapsibleCollapseButton(props: Props): ReactNode; } declare module '@theme/ColorModeToggle' { + import type {ReactNode} from 'react'; import type {ColorMode} from '@docusaurus/theme-common'; export interface Props { @@ -1417,192 +1563,245 @@ declare module '@theme/ColorModeToggle' { readonly onChange: (colorMode: ColorMode) => void; } - export default function ColorModeToggle(props: Props): JSX.Element; + export default function ColorModeToggle(props: Props): ReactNode; } declare module '@theme/Logo' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'a'> { readonly imageClassName?: string; readonly titleClassName?: string; } - export default function Logo(props: Props): JSX.Element; + export default function Logo(props: Props): ReactNode; } declare module '@theme/Icon/Arrow' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function IconArrow(props: Props): JSX.Element; + export default function IconArrow(props: Props): ReactNode; } declare module '@theme/Icon/DarkMode' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function IconDarkMode(props: Props): JSX.Element; + export default function IconDarkMode(props: Props): ReactNode; } declare module '@theme/Icon/Edit' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function IconEdit(props: Props): JSX.Element; + export default function IconEdit(props: Props): ReactNode; } declare module '@theme/Icon/Home' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function IconHome(props: Props): JSX.Element; + export default function IconHome(props: Props): ReactNode; } declare module '@theme/Icon/LightMode' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function IconLightMode(props: Props): JSX.Element; + export default function IconLightMode(props: Props): ReactNode; } declare module '@theme/Icon/Menu' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function IconMenu(props: Props): JSX.Element; + export default function IconMenu(props: Props): ReactNode; } declare module '@theme/Icon/Close' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function IconClose(props: Props): JSX.Element; + export default function IconClose(props: Props): ReactNode; } declare module '@theme/Icon/Copy' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function IconCopy(props: Props): JSX.Element; + export default function IconCopy(props: Props): ReactNode; } declare module '@theme/Icon/Language' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function IconLanguage(props: Props): JSX.Element; + export default function IconLanguage(props: Props): ReactNode; } declare module '@theme/Icon/Success' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function IconSuccess(props: Props): JSX.Element; + export default function IconSuccess(props: Props): ReactNode; } declare module '@theme/Icon/ExternalLink' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function IconExternalLink(props: Props): JSX.Element; + export default function IconExternalLink(props: Props): ReactNode; } declare module '@theme/Icon/WordWrap' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function IconWordWrap(props: Props): JSX.Element; + export default function IconWordWrap(props: Props): ReactNode; } declare module '@theme/Icon/Socials/Twitter' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function Twitter(props: Props): JSX.Element; + export default function Twitter(props: Props): ReactNode; } declare module '@theme/Icon/Socials/GitHub' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function Github(props: Props): JSX.Element; + export default function Github(props: Props): ReactNode; } declare module '@theme/Icon/Socials/X' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function X(props: Props): JSX.Element; + export default function X(props: Props): ReactNode; } declare module '@theme/Icon/Socials/LinkedIn' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function LinkedIn(props: Props): JSX.Element; + export default function LinkedIn(props: Props): ReactNode; } declare module '@theme/Icon/Socials/Default' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function DefaultSocialIcon(props: Props): JSX.Element; + export default function DefaultSocialIcon(props: Props): ReactNode; } declare module '@theme/Icon/Socials/StackOverflow' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> {} - export default function StackOverflow(props: Props): JSX.Element; + export default function StackOverflow(props: Props): ReactNode; +} + +declare module '@theme/Icon/Socials/Bluesky' { + import type {ComponentProps, ReactNode} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function Bluesky(props: Props): ReactNode; +} + +declare module '@theme/Icon/Socials/Instagram' { + import type {ComponentProps, ReactNode} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function Instagram(props: Props): ReactNode; +} + +declare module '@theme/Icon/Socials/Threads' { + import type {ComponentProps, ReactNode} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function Threads(props: Props): ReactNode; +} + +declare module '@theme/Icon/Socials/YouTube' { + import type {ComponentProps, ReactNode} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function YouTube(props: Props): ReactNode; +} + +declare module '@theme/Icon/Socials/Twitch' { + import type {ComponentProps, ReactNode} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function Twitch(props: Props): ReactNode; +} + +declare module '@theme/Icon/Socials/Mastodon' { + import type {ComponentProps, ReactNode} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function Mastodon(props: Props): ReactNode; } declare module '@theme/TagsListByLetter' { + import type {ReactNode} from 'react'; import type {TagsListItem} from '@docusaurus/utils'; export interface Props { readonly tags: readonly TagsListItem[]; } - export default function TagsListByLetter(props: Props): JSX.Element; + export default function TagsListByLetter(props: Props): ReactNode; } declare module '@theme/TagsListInline' { + import type {ReactNode} from 'react'; import type {Tag} from '@docusaurus/utils'; export interface Props { readonly tags: readonly Tag[]; } - export default function TagsListInline(props: Props): JSX.Element; + export default function TagsListInline(props: Props): ReactNode; } declare module '@theme/Tag' { + import type {ReactNode} from 'react'; import type {TagsListItem} from '@docusaurus/utils'; import type {Optional} from 'utility-types'; export interface Props extends Optional {} - export default function Tag(props: Props): JSX.Element; + export default function Tag(props: Props): ReactNode; } declare module '@theme/ContentVisibility' { + import type {ReactNode} from 'react'; + export interface Props { readonly metadata: { // the visibility metadata our 3 content plugins share in common @@ -1611,23 +1810,27 @@ declare module '@theme/ContentVisibility' { }; } - export default function ContentVisibility(props: Props): JSX.Element; + export default function ContentVisibility(props: Props): ReactNode; } declare module '@theme/ContentVisibility/Unlisted' { + import type {ReactNode} from 'react'; + export interface Props { className?: string; } - export default function Unlisted(props: Props): JSX.Element; + export default function Unlisted(props: Props): ReactNode; } declare module '@theme/ContentVisibility/Draft' { + import type {ReactNode} from 'react'; + export interface Props { className?: string; } - export default function Draft(props: Props): JSX.Element; + export default function Draft(props: Props): ReactNode; } declare module '@theme/prism-include-languages' { @@ -1639,5 +1842,18 @@ declare module '@theme/prism-include-languages' { } declare module '@theme/DocBreadcrumbs/Items/Home' { - export default function HomeBreadcrumbItem(): JSX.Element; + import type {ReactNode} from 'react'; + + export default function HomeBreadcrumbItem(): ReactNode; +} + +declare module '@theme/DocBreadcrumbs/StructuredData' { + import type {ReactNode} from 'react'; + import type {PropSidebarBreadcrumbsItem} from '@docusaurus/plugin-content-docs'; + + export interface Props { + readonly breadcrumbs: PropSidebarBreadcrumbsItem[]; + } + + export default function DocBreadcrumbsStructuredData(props: Props): ReactNode; } diff --git a/packages/docusaurus-theme-classic/src/theme/Admonition/Icon/Danger.tsx b/packages/docusaurus-theme-classic/src/theme/Admonition/Icon/Danger.tsx index 90d4a5515f..5ef416dc58 100644 --- a/packages/docusaurus-theme-classic/src/theme/Admonition/Icon/Danger.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Admonition/Icon/Danger.tsx @@ -5,10 +5,10 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import type {Props} from '@theme/Admonition/Icon/Danger'; -export default function AdmonitionIconDanger(props: Props): JSX.Element { +export default function AdmonitionIconDanger(props: Props): ReactNode { return ( ) { ) : null; } -export default function AdmonitionLayout(props: Props): JSX.Element { +export default function AdmonitionLayout(props: Props): ReactNode { const {type, icon, title, children, className} = props; return ( diff --git a/packages/docusaurus-theme-classic/src/theme/Admonition/Type/Caution.tsx b/packages/docusaurus-theme-classic/src/theme/Admonition/Type/Caution.tsx index 35e6a19e81..48ac08878d 100644 --- a/packages/docusaurus-theme-classic/src/theme/Admonition/Type/Caution.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Admonition/Type/Caution.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import clsx from 'clsx'; import Translate from '@docusaurus/Translate'; import type {Props} from '@theme/Admonition/Type/Caution'; @@ -27,7 +27,7 @@ const defaultProps = { // TODO remove before v4: Caution replaced by Warning // see https://github.com/facebook/docusaurus/issues/7558 -export default function AdmonitionTypeCaution(props: Props): JSX.Element { +export default function AdmonitionTypeCaution(props: Props): ReactNode { return ( { return AdmonitionTypes.info!; } -export default function Admonition(unprocessedProps: Props): JSX.Element { +export default function Admonition(unprocessedProps: Props): ReactNode { const props = processAdmonitionProps(unprocessedProps); const AdmonitionTypeComponent = getAdmonitionTypeComponent(props.type); return ; diff --git a/packages/docusaurus-theme-classic/src/theme/AnnouncementBar/CloseButton/index.tsx b/packages/docusaurus-theme-classic/src/theme/AnnouncementBar/CloseButton/index.tsx index 5ae3135bf9..6fde5e09ac 100644 --- a/packages/docusaurus-theme-classic/src/theme/AnnouncementBar/CloseButton/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/AnnouncementBar/CloseButton/index.tsx @@ -5,16 +5,14 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import clsx from 'clsx'; import {translate} from '@docusaurus/Translate'; import IconClose from '@theme/Icon/Close'; import type {Props} from '@theme/AnnouncementBar/CloseButton'; import styles from './styles.module.css'; -export default function AnnouncementBarCloseButton( - props: Props, -): JSX.Element | null { +export default function AnnouncementBarCloseButton(props: Props): ReactNode { return (
} diff --git a/packages/docusaurus-theme-classic/src/theme/BackToTopButton/index.tsx b/packages/docusaurus-theme-classic/src/theme/BackToTopButton/index.tsx index f2d7a9ddb3..62f805d276 100644 --- a/packages/docusaurus-theme-classic/src/theme/BackToTopButton/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BackToTopButton/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import clsx from 'clsx'; import {translate} from '@docusaurus/Translate'; import {ThemeClassNames} from '@docusaurus/theme-common'; @@ -13,7 +13,7 @@ import {useBackToTopButton} from '@docusaurus/theme-common/internal'; import styles from './styles.module.css'; -export default function BackToTopButton(): JSX.Element { +export default function BackToTopButton(): ReactNode { const {shown, scrollToTop} = useBackToTopButton({threshold: 300}); return ( + +
+
); } -export function ShowcaseCarouselV1(): JSX.Element { +export function ShowcaseCarouselV1(): ReactNode { return ( - A freelance React and React-Native developer near Paris and Docusaurus maintainer. Also runs ThisWeekInReact.com, a newsletter to stay updated with the React ecosystem. - - + description: A freelance React and React-Native developer near Paris and Docusaurus maintainer. Also runs ThisWeekInReact.com, a newsletter to stay updated with the React ecosystem. socials: + bluesky: sebastienlorber.com x: sebastienlorber linkedin: sebastienlorber github: slorber + instagram: thisweekinreact newsletter: https://thisweekinreact.com yangshun: name: Yangshun Tay - title: Front End Engineer at Meta - url: https://github.com/yangshun + title: Ex-Meta Staff Engineer, Co-founder GreatFrontEnd + url: https://linkedin.com/in/yangshun image_url: https://github.com/yangshun.png page: true socials: x: yangshunz + linkedin: yangshun github: yangshun + newsletter: https://www.greatfrontend.com lex111: name: Alexey Pyltsyn diff --git a/website/blog/releases/3.7/img/social-card.png b/website/blog/releases/3.7/img/social-card.png new file mode 100644 index 0000000000..59905b0873 Binary files /dev/null and b/website/blog/releases/3.7/img/social-card.png differ diff --git a/website/blog/releases/3.7/index.mdx b/website/blog/releases/3.7/index.mdx new file mode 100644 index 0000000000..557a323858 --- /dev/null +++ b/website/blog/releases/3.7/index.mdx @@ -0,0 +1,107 @@ +--- +title: Docusaurus 3.7 +authors: [slorber] +tags: [release] +image: ./img/social-card.png +date: 2025-01-03 +--- + +We are happy to announce **Docusaurus 3.7**. + +Docusaurus is now compatible with [React 19](https://react.dev/blog/2024/12/05/react-19). + +Upgrading should be easy. Our [release process](/community/release-process) respects [Semantic Versioning](https://semver.org/). Minor versions do not include any breaking changes. + +![Docusaurus blog post social card](./img/social-card.png) + +{/* truncate */} + +## Highlight + +### React 19 + +In [#10763](https://github.com/facebook/docusaurus/pull/10763), we added support for [React 19](https://react.dev/blog/2024/12/05/react-19), and the Docusaurus website is running on React 19 already. + +From now on, all newly initialized sites will run on React 19 by default, and React 19 will be the minimum required version Docusaurus v4. + +However, React 18 remains supported, and existing Docusaurus sites can either choose to stay on React 18, or upgrade their dependencies to React 19: + +```diff +{ + "name": "my-docusaurus-site", + "dependencies": { +- "react": "^18.0.0", +- "react-dom": "^18.0.0" ++ "react": "^19.0.0", ++ "react-dom": "^19.0.0" + } +} +``` + +:::warning + +There's no urge to upgrade your site immediately. + +React 19 is a bit heavier than React 18. Since we support both versions, we don't leverage yet the new features that are exclusive to React 19. + +However, upgrading to React 19 prepares your site for Docusaurus v4, that will drop support for React 18. + +Here are good reasons to upgrade your site before Docusaurus v4: + +- You have custom React code and want to ensure it is ready for React19 +- You plan to leverage the brand-new React 19 features in your own code +- You use custom or third-party plugins and want to ensure their compatibility +- You have a monorepo and want to align the React dependency to v19 for all packages + +::: + +Along the way, we [fixed](https://github.com/facebook/docusaurus/pull/10786) all the remaining hydration errors reported by React 19, some of them produced by our aggressive HTML minifier settings. + +### SVGR plugin + +Docusaurus has built-in support for [SVGR](https://github.com/gregberge/svgr), allowing you to seamlessly import and use SVG files as React components: + +```tsx +import DocusaurusSvg from './docusaurus.svg'; + +; +``` + +This built-in support has been the source of various bug reports due to the inability to customize the [SVGR Options](https://react-svgr.com/docs/options/), in particular the [SVG Optimizer](https://svgo.dev/) options. + +In [#10677](https://github.com/facebook/docusaurus/pull/10677), we extracted a new [`@docusaurus/plugin-svgr`](/docs/api/plugins/@docusaurus/plugin-svgr) that you can now configure according to your needs. It is included by default in our classic preset: + +```js +export default { + presets: [ + [ + 'classic', + { + svgr: { + svgrConfig: { + // Your SVGR options ... + svgoConfig: { + // Your SVGO options ... + // Use "svgoConfig: undefined" to use a svgo.config.js file + }, + }, + }, + }, + ], + ], +}; +``` + +## Other changes + +Other notable changes include: + +- [#10768](https://github.com/facebook/docusaurus/pull/10768): Blog authors have built-in icons for social platforms bluesky, mastodon, threads, twitch, youtube, instagram. +- [#10729](https://github.com/facebook/docusaurus/pull/10729): Blog now supports `frontMatter.sidebar_label` +- [#10803](https://github.com/facebook/docusaurus/pull/10803): `@docusaurus/remark-plugin-npm2yarn` now supports Bun conversions. +- [#10672](https://github.com/facebook/docusaurus/pull/10672): Upgrade Algolia DocSearch to `algoliasearch` v5. +- [#10800](https://github.com/facebook/docusaurus/pull/10800): Docusaurus Faster turns Rspack incremental mode on by default. +- [#10783](https://github.com/facebook/docusaurus/pull/10783): Improve Dutch theme translations. +- [#10760](https://github.com/facebook/docusaurus/pull/10760): Improve Korean theme translations. + +Check the **[3.7.0 changelog entry](/changelog/3.7.0)** for an exhaustive list of changes. diff --git a/website/docs/api/docusaurus.config.js.mdx b/website/docs/api/docusaurus.config.js.mdx index fb358955dc..41f5c50a9f 100644 --- a/website/docs/api/docusaurus.config.js.mdx +++ b/website/docs/api/docusaurus.config.js.mdx @@ -186,7 +186,7 @@ It is also a way to opt-in for upcoming breaking changes coming in the next majo Features prefixed by `experimental_` or `unstable_` are subject to changes in **minor versions**, and not considered as [Semantic Versioning breaking changes](/community/release-process). -Features prefixed by `v_` (`v6_` `v7_`, etc.) are future flags that are expected to be turned on by default in the next major versions. These are less likely to change, but we keep the possibility to do so. +Features namespaced by `v` (`v6` `v7`, etc.) are future flags that are expected to be turned on by default in the next major versions. These are less likely to change, but we keep the possibility to do so. `future` API breaking changes should be easy to handle, and will be documented in minor/major version blog posts. @@ -197,12 +197,17 @@ Example: ```js title="docusaurus.config.js" export default { future: { + v4: { + removeLegacyPostBuildHeadAttribute: true, + }, experimental_faster: { swcJsLoader: true, swcJsMinimizer: true, swcHtmlMinimizer: true, lightningCssMinimizer: true, rspackBundler: true, + rspackPersistentCache: true, + ssgWorkerThreads: true, mdxCrossCompilerCache: true, }, experimental_storage: { @@ -214,13 +219,17 @@ export default { }; ``` +- `v4`: Permits to opt-in for upcoming Docusaurus v4 breaking changes and features, to prepare your site in advance for this new version. Use `true` as a shorthand to enable all the flags. + - [`removeLegacyPostBuildHeadAttribute`](https://github.com/facebook/docusaurus/pull/10435): Removes the legacy `plugin.postBuild({head})` API that prevents us from applying useful SSG optimizations ([explanations](https://github.com/facebook/docusaurus/pull/10850)). - `experimental_faster`: An object containing feature flags to make the Docusaurus build faster. This requires adding the `@docusaurus/faster` package to your site's dependencies. Use `true` as a shorthand to enable all flags. Read more on the [Docusaurus Faster](https://github.com/facebook/docusaurus/issues/10556) issue. Available feature flags: - [`swcJsLoader`](https://github.com/facebook/docusaurus/pull/10435): Use [SWC](https://swc.rs/) to transpile JS (instead of [Babel](https://babeljs.io/)). - [`swcJsMinimizer`](https://github.com/facebook/docusaurus/pull/10441): Use [SWC](https://swc.rs/) to minify JS (instead of [Terser](https://github.com/terser/terser)). - [`swcHtmlMinimizer `](https://github.com/facebook/docusaurus/pull/10554): Use [SWC](https://swc.rs/) to minify HTML and inlined JS/CSS (instead of [html-minifier-terser](https://github.com/terser/html-minifier-terser)). - [`lightningCssMinimizer`](https://github.com/facebook/docusaurus/pull/10522): Use [Lightning CSS](https://lightningcss.dev/) to minify CSS (instead of [cssnano](https://github.com/cssnano/cssnano) and [clean-css](https://github.com/clean-css/clean-css)). - [`rspackBundler`](https://github.com/facebook/docusaurus/pull/10402): Use [Rspack](https://rspack.dev/) to bundle your app (instead of [webpack](https://webpack.js.org/)). + - [`rspackPersistentCache`](https://github.com/facebook/docusaurus/pull/10931): Use [Rspack Persistent Cache](https://rspack.dev/config/cache) to re-build your app faster on subsequent builds. Requires `rspackBundler: true`. Requires persisting `./node_modules/.cache` across rebuilds. - [`mdxCrossCompilerCache`](https://github.com/facebook/docusaurus/pull/10479): Compile MDX files only once for both browser/Node.js environments instead of twice. + - [`ssgWorkerThreads`](https://github.com/facebook/docusaurus/pull/10826): Using a Node.js worker thread pool to execute the static site generation phase faster. Requires `future.v4.removeLegacyPostBuildHeadAttribute` to be turned on. - `experimental_storage`: Site-wide browser storage options that theme authors should strive to respect. - `type`: The browser storage theme authors should use. Possible values are `localStorage` and `sessionStorage`. Defaults to `localStorage`. - `namespace`: Whether to namespace the browser storage keys to avoid storage key conflicts when Docusaurus sites are hosted under the same domain, or on localhost. Possible values are `string | boolean`. The namespace is appended at the end of the storage keys `key-namespace`. Use `true` to automatically generate a random namespace from your site `url + baseUrl`. Defaults to `false` (no namespace, historical behavior). diff --git a/website/docs/api/plugin-methods/lifecycle-apis.mdx b/website/docs/api/plugin-methods/lifecycle-apis.mdx index 4606eb6775..bc6c1f77aa 100644 --- a/website/docs/api/plugin-methods/lifecycle-apis.mdx +++ b/website/docs/api/plugin-methods/lifecycle-apis.mdx @@ -369,6 +369,7 @@ interface Props { preBodyTags: string; postBodyTags: string; routesPaths: string[]; + routesBuildMetadata: {[location: string]: {noIndex: boolean}}; plugins: Plugin[]; content: Content; } diff --git a/website/docs/api/plugins/overview.mdx b/website/docs/api/plugins/overview.mdx index 651517d4ee..23eb708929 100644 --- a/website/docs/api/plugins/overview.mdx +++ b/website/docs/api/plugins/overview.mdx @@ -23,8 +23,11 @@ These plugins will add a useful behavior to your Docusaurus site. - [@docusaurus/plugin-debug](./plugin-debug.mdx) - [@docusaurus/plugin-sitemap](./plugin-sitemap.mdx) +- [@docusaurus/plugin-svgr](./plugin-svgr.mdx) +- [@docusaurus/plugin-rsdoctor](./plugin-rsdoctor.mdx) - [@docusaurus/plugin-pwa](./plugin-pwa.mdx) - [@docusaurus/plugin-client-redirects](./plugin-client-redirects.mdx) - [@docusaurus/plugin-ideal-image](./plugin-ideal-image.mdx) - [@docusaurus/plugin-google-analytics](./plugin-google-analytics.mdx) - [@docusaurus/plugin-google-gtag](./plugin-google-gtag.mdx) +- [@docusaurus/plugin-google-tag-manager](./plugin-google-tag-manager.mdx) diff --git a/website/docs/api/plugins/plugin-content-blog.mdx b/website/docs/api/plugins/plugin-content-blog.mdx index 17f545d193..1a1703b7c4 100644 --- a/website/docs/api/plugins/plugin-content-blog.mdx +++ b/website/docs/api/plugins/plugin-content-blog.mdx @@ -250,6 +250,8 @@ Accepted fields: | `author_image_url` | `string` | `undefined` | ⚠️ Prefer using `authors`. The URL to the author's thumbnail image. | | `author_title` | `string` | `undefined` | ⚠️ Prefer using `authors`. A description of the author. | | `title` | `string` | Markdown title | The blog post title. | +| `title_meta` | `string` | `frontMatter.title` | The blog post SEO metadata title, used in `` for `` and `og:title`. Permits to override `title` when the displayed title and SEO title should be different. | +| `sidebar_label` | `string` | `title` | A custom label for the blog sidebar, replacing the default one (`title`). | | `date` | `string` | File name or file creation time | The blog post creation date. If not specified, this can be extracted from the file or folder name, e.g, `2021-04-15-blog-post.mdx`, `2021-04-15-blog-post/index.mdx`, `2021/04/15/blog-post.mdx`. Otherwise, it is the Markdown file creation time. | | `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your post. Strings can be a reference to keys of a [tags file](#tags-file) (usually `tags.yml`) | | `draft` | `boolean` | `false` | Draft blog posts will only be available during development. | @@ -277,7 +279,8 @@ type AuthorKey = string; // Social platform name -> Social platform link // Example: {MyPlatform: 'https://myplatform.com/myusername'} -// Pre-defined platforms ("x", "github", "twitter", "linkedin", "stackoverflow") accept handles: +// Pre-defined platforms +// ("x", "github", "twitter", "linkedin", "stackoverflow", "instagram", "bluesky", "mastodon", "threads", "twitch", "youtube") accept handles: // Example: {github: 'slorber'} type AuthorSocials = Record<string, string>; diff --git a/website/docs/api/plugins/plugin-content-docs.mdx b/website/docs/api/plugins/plugin-content-docs.mdx index b14df36827..fa9ddbf53e 100644 --- a/website/docs/api/plugins/plugin-content-docs.mdx +++ b/website/docs/api/plugins/plugin-content-docs.mdx @@ -278,7 +278,6 @@ Accepted fields: | --- | --- | --- | --- | | `id` | `string` | file path (including folders, without the extension) | A unique document ID. | | `title` | `string` | Markdown title or `id` | The text title of your document. Used for the page metadata and as a fallback value in multiple places (sidebar, next/previous buttons...). Automatically added at the top of your doc if it does not contain any Markdown title. | -| `title_meta` | `string` | `frontMatter.title` | The SEO metadata title of your document used in `<head>` for `<title>` and `og:title`. Permits to override `frontMatter.title` when the displayed title and SEO title should be different. | | `pagination_label` | `string` | `sidebar_label` or `title` | The text used in the document next/previous buttons for this document. | | `sidebar_label` | `string` | `title` | The text shown in the document sidebar for this document. | | `sidebar_position` | `number` | Default ordering | Controls the position of a doc inside the generated sidebar slice when using `autogenerated` sidebar items. See also [Autogenerated sidebar metadata](/docs/sidebar/autogenerated#autogenerated-sidebar-metadata). | diff --git a/website/docs/api/plugins/plugin-debug.mdx b/website/docs/api/plugins/plugin-debug.mdx index e580466ce5..d764e61930 100644 --- a/website/docs/api/plugins/plugin-debug.mdx +++ b/website/docs/api/plugins/plugin-debug.mdx @@ -24,7 +24,7 @@ If you use a standalone plugin, you may need to achieve the same effect by check export default { plugins: [ // highlight-next-line - process.env.NODE_ENV === 'production' && '@docusaurus/plugin-debug', + process.env.NODE_ENV !== 'production' && '@docusaurus/plugin-debug', ].filter(Boolean), }; ``` diff --git a/website/docs/api/plugins/plugin-svgr.mdx b/website/docs/api/plugins/plugin-svgr.mdx new file mode 100644 index 0000000000..bd5bef1eab --- /dev/null +++ b/website/docs/api/plugins/plugin-svgr.mdx @@ -0,0 +1,55 @@ +--- +sidebar_position: 7 +slug: /api/plugins/@docusaurus/plugin-svgr +--- + +# 📦 plugin-svgr + +import APITable from '@site/src/components/APITable'; + +An [SVGR](https://react-svgr.com/) plugin to transform SVG files into React components automatically at build time. + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-svgr +``` + +:::tip + +If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. + +You can configure this plugin through the [preset options](../../using-plugins.mdx#docusauruspreset-classic). + +::: + +## Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `svgrConfig` | `object` | `{}` | The [SVGR config options](https://react-svgr.com/docs/options/), forwarded as is | + +```mdx-code-block +</APITable> +``` + +### Example configuration {#ex-config} + +You can configure this plugin through plugin options. + +```js config-tabs +// Preset Options: svgr +// Plugin Options: @docusaurus/plugin-svgr + +const config = { + svgrConfig: { + /* SVGR config */ + }, +}; +``` diff --git a/website/docs/api/themes/theme-configuration.mdx b/website/docs/api/themes/theme-configuration.mdx index 7be1ba2b64..7349ed7983 100644 --- a/website/docs/api/themes/theme-configuration.mdx +++ b/website/docs/api/themes/theme-configuration.mdx @@ -597,11 +597,23 @@ Accepted fields: | `dropdownItemsAfter` | <code>[LinkLikeItem](#navbar-dropdown)[]</code> | `[]` | Add additional dropdown items at the end of the dropdown. | | `docsPluginId` | `string` | `'default'` | The ID of the docs plugin that the doc versioning belongs to. | | `dropdownActiveClassDisabled` | `boolean` | `false` | Do not add the link active class when browsing docs. | +| `versions` | `DropdownVersions` | `undefined` | Specify a custom list of versions to include in the dropdown. See [the versioning guide](../../guides/docs/versioning.mdx#docsVersionDropdown) for details. | ```mdx-code-block </APITable> ``` +Types: + +```ts +type DropdownVersion = { + /** Allows you to provide a custom display label for each version. */ + label?: string; +}; + +type DropdownVersions = string[] | {[versionName: string]: DropdownVersion}; +``` + Example configuration: ```js title="docusaurus.config.js" diff --git a/website/docs/api/themes/theme-live-codeblock.mdx b/website/docs/api/themes/theme-live-codeblock.mdx index dd9fa7e327..212c910b3e 100644 --- a/website/docs/api/themes/theme-live-codeblock.mdx +++ b/website/docs/api/themes/theme-live-codeblock.mdx @@ -5,7 +5,7 @@ slug: /api/themes/@docusaurus/theme-live-codeblock # 📦 theme-live-codeblock -This theme provides a `@theme/CodeBlock` component that is powered by react-live. You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. +This theme provides a `@theme/CodeBlock` component that is powered by [react-live](https://commerce.nearform.com/open-source/react-live/). You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. ```bash npm2yarn npm install --save @docusaurus/theme-live-codeblock diff --git a/website/docs/deployment.mdx b/website/docs/deployment.mdx index d80af32c4b..1d001e79fe 100644 --- a/website/docs/deployment.mdx +++ b/website/docs/deployment.mdx @@ -840,7 +840,7 @@ See [docs](https://docs.quantcdn.io/docs/cli/continuous-integration) and [blog]( ## Deploying to Cloudflare Pages {#deploying-to-cloudflare-pages} -[Cloudflare Pages](https://pages.cloudflare.com/) is a Jamstack platform for frontend developers to collaborate and deploy websites. Get started within a few minutes by following [this article](https://dev.to/apidev234/deploying-docusaurus-to-cloudflare-pages-565g). +[Cloudflare Pages](https://pages.cloudflare.com/) is a Jamstack platform for frontend developers to collaborate and deploy websites. Get started within a few minutes by following [this page](https://developers.cloudflare.com/pages/framework-guides/deploy-a-docusaurus-site/). ## Deploying to Azure Static Web Apps {#deploying-to-azure-static-web-apps} diff --git a/website/docs/guides/docs/sidebar/index.mdx b/website/docs/guides/docs/sidebar/index.mdx index ae1d4ac400..4d2c4d209b 100644 --- a/website/docs/guides/docs/sidebar/index.mdx +++ b/website/docs/guides/docs/sidebar/index.mdx @@ -64,7 +64,7 @@ You can also define your sidebars explicitly. ## Sidebar object {#sidebar-object} -A sidebar at its crux is a hierarchy of categories, doc links, and other hyperlinks. +A sidebar is a hierarchy of categories, doc links, and other hyperlinks. ```ts type Sidebar = diff --git a/website/docs/guides/docs/versioning.mdx b/website/docs/guides/docs/versioning.mdx index 08fab227b5..196f7a3790 100644 --- a/website/docs/guides/docs/versioning.mdx +++ b/website/docs/guides/docs/versioning.mdx @@ -258,7 +258,7 @@ See [docs plugin configuration](../../api/plugins/plugin-content-docs.mdx#config ## Navbar items {#navbar-items} -We offer several navbar items to help you quickly set up navigation without worrying about versioned routes. +We offer several docs navbar items to help you quickly set up navigation without worrying about versioned routes. - [`doc`](../../api/themes/theme-configuration.mdx#navbar-doc-link): a link to a doc. - [`docSidebar`](../../api/themes/theme-configuration.mdx#navbar-doc-sidebar): a link to the first item in a sidebar. @@ -271,6 +271,52 @@ These links would all look for an appropriate version to link to, in the followi 2. **Preferred version**: the version that the user last viewed. If there's no history, fall back to... 3. **Latest version**: the default version that we navigate to, configured by the `lastVersion` option. +## `docsVersionDropdown` {#docsVersionDropdown} + +By default, the [`docsVersionDropdown`](../../api/themes/theme-configuration.mdx#navbar-docs-version-dropdown) displays a dropdown with all the available docs versions. + +The `versions` attribute allows you to display a subset of the available docs versions in a given order: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + items: [ + { + type: 'docsVersionDropdown', + // highlight-start + versions: ['current', '3.0', '2.0'], + // highlight-end + }, + ], + }, + }, +}; +``` + +Passing a `versions` object, lets you override the display label of each version: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + items: [ + { + type: 'docsVersionDropdown', + // highlight-start + versions: { + current: {label: 'Version 4.0'}, + '3.0': {label: 'Version 3.0'}, + '2.0': {label: 'Version 2.0'}, + }, + // highlight-end + }, + ], + }, + }, +}; +``` + ## Recommended practices {#recommended-practices} ### Version your documentation only when needed {#version-your-documentation-only-when-needed} diff --git a/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx b/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx index cfe3c3bfe6..6b8c896fb9 100644 --- a/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx +++ b/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx @@ -395,18 +395,12 @@ The `Line` component will receive the list of class names, based on which you ca You can enable line numbering for your code block by using `showLineNumbers` key within the language meta string (don't forget to add space directly before the key). ````md -```jsx {1,4-6,11} showLineNumbers +```jsx showLineNumbers import React from 'react'; -function MyComponent(props) { - if (props.isBar) { - return <div>Bar</div>; - } - +export default function MyComponent(props) { return <div>Foo</div>; } - -export default MyComponent; ``` ```` @@ -414,18 +408,36 @@ export default MyComponent; <BrowserWindow> ``` -```jsx {1,4-6,11} showLineNumbers +```jsx showLineNumbers import React from 'react'; -function MyComponent(props) { - if (props.isBar) { - return <div>Bar</div>; - } - +export default function MyComponent(props) { return <div>Foo</div>; } +``` -export default MyComponent; +```mdx-code-block +</BrowserWindow> +``` + +By default, the counter starts at line number 1. It's possible to pass a custom counter start value to split large code blocks for readability: + +````md +```jsx showLineNumbers=3 +export default function MyComponent(props) { + return <div>Foo</div>; +} +``` +```` + +```mdx-code-block +<BrowserWindow> +``` + +```jsx showLineNumbers=3 +export default function MyComponent(props) { + return <div>Foo</div>; +} ``` ```mdx-code-block diff --git a/website/docs/guides/markdown-features/markdown-features-math-equations.mdx b/website/docs/guides/markdown-features/markdown-features-math-equations.mdx index 178ef2fd9a..0fd9543d8e 100644 --- a/website/docs/guides/markdown-features/markdown-features-math-equations.mdx +++ b/website/docs/guides/markdown-features/markdown-features-math-equations.mdx @@ -10,9 +10,11 @@ import BrowserWindow from '@site/src/components/BrowserWindow'; Mathematical equations can be rendered using [KaTeX](https://katex.org). +See [below](#configuration) how to activate them. + ## Usage {#usage} -Please read [KaTeX](https://katex.org) documentation for more details. +Please read the [KaTeX](https://katex.org) documentation for more details. ### Inline {#inline} diff --git a/website/docs/installation.mdx b/website/docs/installation.mdx index 1da802db42..1295709b94 100644 --- a/website/docs/installation.mdx +++ b/website/docs/installation.mdx @@ -21,12 +21,12 @@ Use **[docusaurus.new](https://docusaurus.new)** to test Docusaurus immediately ## Requirements {#requirements} -- [Node.js](https://nodejs.org/en/download/) version 18.0 or above (which can be checked by running `node -v`). You can use [nvm](https://github.com/nvm-sh/nvm) for managing multiple Node versions on a single machine installed. - - When installing Node.js, you are recommended to check all checkboxes related to dependencies. +- [Node.js](https://nodejs.org/en/download/) version 18.0 or above (which can be checked by running `node -v`). You can use [nvm](https://github.com/nvm-sh/nvm) to manage multiple Node.js versions on a single machine. + - When installing Node.js, it is recommended to check all checkboxes related to dependencies. ## Scaffold project website {#scaffold-project-website} -The easiest way to install Docusaurus is to use the command line tool that helps you scaffold a skeleton Docusaurus website. You can run this command anywhere in a new empty repository or within an existing repository, it will create a new directory containing the scaffolded files. +The easiest way to install Docusaurus is to use the [`create-docusaurus`](./api/misc/create-docusaurus.mdx) command line tool that helps you scaffold a skeleton Docusaurus website. You can run this command anywhere in a new empty repository or within an existing repository, it will create a new directory containing the scaffolded files. ```bash npx create-docusaurus@latest my-website classic diff --git a/website/docs/introduction.mdx b/website/docs/introduction.mdx index d9c6bf8b7e..811723891d 100644 --- a/website/docs/introduction.mdx +++ b/website/docs/introduction.mdx @@ -180,6 +180,12 @@ Currently, GitBook is only free for open-source and non-profit teams. Docusaurus In comparison with statically generated HTML and interactivity added using `<script />` tags, Docusaurus sites are React apps. Using modern JavaScript ecosystem tooling, we hope to set new standards on doc sites' performance, asset building pipeline and optimizations, and ease to set up. +### Rspress {#rspress} + +[Rspress](https://rspress.dev/) is a fast static site generator based on Rspack, a Rust-based bundler. It supports content writing with MDX (Markdown with React components), integrated text search, multilingual support (i18n), and extensibility through plugins. Designed for creating elegant documentation and static websites, Rspress produces static HTML files that are easy to deploy. + +Rspress and Docusaurus are quite similar. They both have their pros and cons. Rspress was created more recently and benefits from a modern infrastructure that enables faster site builds. Docusaurus stands out for its maturity, comprehensive feature set, flexibility, and strong community. It is also [modernizing its infrastructure](https://github.com/facebook/docusaurus/issues/10556) regularly to remain competitive in terms of performance. + ## Staying informed {#staying-informed} - [GitHub](https://github.com/facebook/docusaurus) diff --git a/website/docs/migration/v2/migration-versioned-sites.mdx b/website/docs/migration/v2/migration-versioned-sites.mdx index c4a799025d..33db32cc7d 100644 --- a/website/docs/migration/v2/migration-versioned-sites.mdx +++ b/website/docs/migration/v2/migration-versioned-sites.mdx @@ -171,6 +171,6 @@ title: Demo hello world -- pre style="background: black">zzz</pre> -+ pre style={{background: 'black'}}>zzz</pre> +- <pre style="background: black">zzz</pre> ++ <pre style={{background: 'black'}}>zzz</pre> ``` diff --git a/website/docs/migration/v3.mdx b/website/docs/migration/v3.mdx index fc2e2e7e31..6021316f24 100644 --- a/website/docs/migration/v3.mdx +++ b/website/docs/migration/v3.mdx @@ -508,6 +508,8 @@ While not an ideal solution, you can also either of the following without conver **「。」の後に文を続けると`**`が意図した動作をしません。** また、**[リンク](https://docusaurus.io/)** や **`コード`** のすぐ外側に`**`、そのさらに外側に句読点以外がある場合も同様です。 ``` +A unofficial remark plugin [remark-cjk-friendly](https://www.npmjs.com/package/remark-cjk-friendly) can fix this issue in most cases without modifying the Markdown source written in Chinese, Japanese, and Korean like the above. + ::: </details> diff --git a/website/docs/swizzling.mdx b/website/docs/swizzling.mdx index 35ca59cca8..277535fc0a 100644 --- a/website/docs/swizzling.mdx +++ b/website/docs/swizzling.mdx @@ -94,6 +94,12 @@ npm run swizzle -- --list Use `--help` to see all available CLI options, or refer to the reference [swizzle CLI documentation](./cli.mdx#docusaurus-swizzle). +:::tip Removing Unneeded Swizzled Components + +If you decide that a previously swizzled component is no longer necessary, you can simply remove its file(s) from the `src/theme` directory. After removing the component, make sure to restart your development server to ensure the changes are properly reflected. + +::: + :::note After swizzling a component, **restart your dev server** in order for Docusaurus to know about the new component. diff --git a/website/docs/typescript-support.mdx b/website/docs/typescript-support.mdx index 1493cbe123..6da089e2a7 100644 --- a/website/docs/typescript-support.mdx +++ b/website/docs/typescript-support.mdx @@ -10,7 +10,7 @@ The minimum required version is **TypeScript 5.1**. ## Initialization {#initialization} -Docusaurus supports writing and using TypeScript theme components. If the init template provides a TypeScript variant, you can directly initialize a site with full TypeScript support by using the `--typescript` flag. +Docusaurus supports writing and using TypeScript theme components. If the init template provides a TypeScript variant, you can directly [initialize a site](./installation.mdx#scaffold-project-website) with full TypeScript support by using the `--typescript` flag. ```bash npx create-docusaurus@latest my-website classic --typescript diff --git a/website/docs/using-plugins.mdx b/website/docs/using-plugins.mdx index 92d86097d7..a9d7f04324 100644 --- a/website/docs/using-plugins.mdx +++ b/website/docs/using-plugins.mdx @@ -148,6 +148,7 @@ The classic preset is shipped by default to new Docusaurus websites created with - [`@docusaurus/plugin-google-tag-manager`](./api/plugins/plugin-google-tag-manager.mdx) - [`@docusaurus/plugin-google-analytics`](./api/plugins/plugin-google-analytics.mdx) (**deprecated**) - [`@docusaurus/plugin-sitemap`](./api/plugins/plugin-sitemap.mdx) +- [`@docusaurus/plugin-svgr`](./api/plugins/plugin-svgr.mdx) The classic preset will relay each option entry to the respective plugin/theme. @@ -171,6 +172,8 @@ export default { pages: {}, // Will be passed to @docusaurus/plugin-sitemap (false to disable) sitemap: {}, + // Will be passed to @docusaurus/plugin-svgr (false to disable) + svgr: {}, // Will be passed to @docusaurus/plugin-google-gtag (only enabled when explicitly specified) gtag: {}, // Will be passed to @docusaurus/plugin-google-tag-manager (only enabled when explicitly specified) diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index b52e5c859a..a1ce845153 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -163,6 +163,7 @@ export default async function createConfigAsync() { baseUrlIssueBanner: true, url: 'https://docusaurus.io', future: { + v4: !isSlower, // Not accurate, but good enough experimental_faster: !isSlower, experimental_storage: { namespace: true, @@ -281,7 +282,7 @@ export default async function createConfigAsync() { }, ], [ - './src/plugins/changelog/index.js', + './src/plugins/changelog/index.ts', { blogTitle: 'Docusaurus changelog', blogDescription: @@ -347,13 +348,16 @@ export default async function createConfigAsync() { from: ['/docs/resources', '/docs/next/resources'], to: '/community/resources', }, + { + from: '/docs/api/misc/docusaurus-init', + to: '/docs/api/misc/create-docusaurus', + }, ...dogfoodingRedirects, ], } satisfies ClientRedirectsOptions, ], [ 'ideal-image', - { quality: 70, max: 1030, @@ -547,6 +551,11 @@ export default async function createConfigAsync() { priority: null, changefreq: null, }, + svgr: { + svgrConfig: { + svgoConfig: undefined, // Use .svgo.config.js + }, + }, } satisfies Preset.Options, ], ], @@ -795,11 +804,12 @@ export default async function createConfigAsync() { }, { title: 'Legal', - // Please don't remove the privacy and terms, it's a legal - // requirement. + className: 'footer-column-legal', + // Don't remove the privacy and terms, it's a legal requirement. items: [ { label: 'Privacy', + className: 'footer-item-privacy', href: 'https://opensource.facebook.com/legal/privacy/', }, { diff --git a/website/package.json b/website/package.json index 09860e0d4b..92cfcecfc5 100644 --- a/website/package.json +++ b/website/package.json @@ -1,6 +1,6 @@ { "name": "website", - "version": "3.6.2", + "version": "3.7.0", "private": true, "scripts": { "docusaurus": "docusaurus", @@ -38,28 +38,27 @@ "dependencies": { "@crowdin/cli": "^3.13.0", "@crowdin/crowdin-api-client": "^1.29.5", - "@docusaurus/core": "3.6.2", - "@docusaurus/logger": "3.6.2", - "@docusaurus/plugin-client-redirects": "3.6.2", - "@docusaurus/plugin-ideal-image": "3.6.2", - "@docusaurus/plugin-pwa": "3.6.2", - "@docusaurus/plugin-rsdoctor": "3.6.2", - "@docusaurus/preset-classic": "3.6.2", - "@docusaurus/remark-plugin-npm2yarn": "3.6.2", - "@docusaurus/theme-classic": "3.6.2", - "@docusaurus/theme-common": "3.6.2", - "@docusaurus/theme-live-codeblock": "3.6.2", - "@docusaurus/theme-mermaid": "3.6.2", - "@docusaurus/utils": "3.6.2", - "@docusaurus/utils-common": "3.6.2", + "@docusaurus/core": "3.7.0", + "@docusaurus/logger": "3.7.0", + "@docusaurus/plugin-client-redirects": "3.7.0", + "@docusaurus/plugin-ideal-image": "3.7.0", + "@docusaurus/plugin-pwa": "3.7.0", + "@docusaurus/plugin-rsdoctor": "3.7.0", + "@docusaurus/preset-classic": "3.7.0", + "@docusaurus/remark-plugin-npm2yarn": "3.7.0", + "@docusaurus/theme-classic": "3.7.0", + "@docusaurus/theme-common": "3.7.0", + "@docusaurus/theme-live-codeblock": "3.7.0", + "@docusaurus/theme-mermaid": "3.7.0", + "@docusaurus/utils": "3.7.0", + "@docusaurus/utils-common": "3.7.0", "clsx": "^2.0.0", "color": "^4.2.3", "fs-extra": "^11.1.1", "netlify-plugin-cache": "^1.0.3", - "pure-react-carousel": "^1.30.1", "raw-loader": "^4.0.2", - "react": "^18.0.0", - "react-dom": "^18.0.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", "react-lite-youtube-embed": "^2.3.52", "react-medium-image-zoom": "^5.1.6", "recma-mdx-displayname": "^0.4.1", @@ -83,8 +82,8 @@ ] }, "devDependencies": { - "@docusaurus/eslint-plugin": "3.6.2", - "@docusaurus/tsconfig": "3.6.2", + "@docusaurus/eslint-plugin": "3.7.0", + "@docusaurus/tsconfig": "3.7.0", "@types/color": "^3.0.4", "@types/jest": "^29.5.3", "cross-env": "^7.0.3", diff --git a/website/src/components/APITable/index.tsx b/website/src/components/APITable/index.tsx index 91ef2d509c..96d4e43278 100644 --- a/website/src/components/APITable/index.tsx +++ b/website/src/components/APITable/index.tsx @@ -84,7 +84,7 @@ const APITableRowComp = React.forwardRef(APITableRow); * assumptions about how the children looks; however, those assumptions * should be generally correct in the MDX context. */ -export default function APITable({children, name}: Props): JSX.Element { +export default function APITable({children, name}: Props): ReactNode { if (children.type !== 'table') { throw new Error( 'Bad usage of APITable component.\nIt is probably that your Markdown table is malformed.\nMake sure to double-check you have the appropriate number of columns for each table row.', diff --git a/website/src/components/BrowserWindow/IframeWindow.tsx b/website/src/components/BrowserWindow/IframeWindow.tsx index 10512e7764..2fe9d74f90 100644 --- a/website/src/components/BrowserWindow/IframeWindow.tsx +++ b/website/src/components/BrowserWindow/IframeWindow.tsx @@ -5,12 +5,12 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import BrowserWindow from './index'; // Quick and dirty component, to improve later if needed -export default function IframeWindow({url}: {url: string}): JSX.Element { +export default function IframeWindow({url}: {url: string}): ReactNode { return ( <div style={{padding: 10}}> <BrowserWindow diff --git a/website/src/components/BrowserWindow/index.tsx b/website/src/components/BrowserWindow/index.tsx index 0d2312ee8e..6f096d59df 100644 --- a/website/src/components/BrowserWindow/index.tsx +++ b/website/src/components/BrowserWindow/index.tsx @@ -24,7 +24,7 @@ export default function BrowserWindow({ url = 'http://localhost:3000', style, bodyStyle, -}: Props): JSX.Element { +}: Props): ReactNode { return ( <div className={styles.browserWindow} style={{...style, minHeight}}> <div className={styles.browserWindowHeader}> diff --git a/website/src/components/ColorGenerator/index.tsx b/website/src/components/ColorGenerator/index.tsx index 7fbcdfa03b..71d6b44425 100644 --- a/website/src/components/ColorGenerator/index.tsx +++ b/website/src/components/ColorGenerator/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React, {useEffect, useState} from 'react'; +import React, {type ReactNode, useEffect, useState} from 'react'; import clsx from 'clsx'; import Color from 'color'; import Link from '@docusaurus/Link'; @@ -33,7 +33,7 @@ function wcagContrast(foreground: string, background: string) { return contrast > 7 ? 'AAA 🏅' : contrast > 4.5 ? 'AA 👍' : 'Fail 🔴'; } -export default function ColorGenerator(): JSX.Element { +export default function ColorGenerator(): ReactNode { const {colorMode, setColorMode} = useColorMode(); const isDarkTheme = colorMode === 'dark'; diff --git a/website/src/components/ConfigTabs.tsx b/website/src/components/ConfigTabs.tsx index 7618848ede..c49d80ce32 100644 --- a/website/src/components/ConfigTabs.tsx +++ b/website/src/components/ConfigTabs.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import Link from '@docusaurus/Link'; import {useActiveVersion} from '@docusaurus/plugin-content-docs/client'; import Translate, {translate} from '@docusaurus/Translate'; @@ -25,7 +25,7 @@ export default function ConfigTabs({ code, pluginName, presetOptionName, -}: Props): JSX.Element { +}: Props): ReactNode { const versionPath = useActiveVersion(docsPluginId)!.path; return ( diff --git a/website/src/components/ErrorBoundaryTestButton/index.tsx b/website/src/components/ErrorBoundaryTestButton/index.tsx index f5c1113da0..d944962c68 100644 --- a/website/src/components/ErrorBoundaryTestButton/index.tsx +++ b/website/src/components/ErrorBoundaryTestButton/index.tsx @@ -15,7 +15,7 @@ export default function ErrorBoundaryTestButton({ children?: ReactNode; message?: string; cause?: string; -}): JSX.Element { +}): ReactNode { const [state, setState] = useState(false); if (state) { throw new Error(message, { diff --git a/website/src/components/HackerNewsIcon.tsx b/website/src/components/HackerNewsIcon.tsx index 4d27e76713..872e241e85 100644 --- a/website/src/components/HackerNewsIcon.tsx +++ b/website/src/components/HackerNewsIcon.tsx @@ -5,14 +5,14 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import Link from '@docusaurus/Link'; export default function HackerNewsIcon({ size = 54, }: { size?: number; -}): JSX.Element { +}): ReactNode { return ( <Link to="https://news.ycombinator.com/item?id=32303052" diff --git a/website/src/components/Highlight.tsx b/website/src/components/Highlight.tsx index ad7e214a9f..8e0599f17e 100644 --- a/website/src/components/Highlight.tsx +++ b/website/src/components/Highlight.tsx @@ -13,7 +13,7 @@ export default function Highlight({ }: { children: ReactNode; color: string; -}): JSX.Element { +}): ReactNode { return ( <span style={{ diff --git a/website/src/components/NavbarItems/CustomDogfoodNavbarItem.tsx b/website/src/components/NavbarItems/CustomDogfoodNavbarItem.tsx index b0c5aedcc8..f0b9dc340e 100644 --- a/website/src/components/NavbarItems/CustomDogfoodNavbarItem.tsx +++ b/website/src/components/NavbarItems/CustomDogfoodNavbarItem.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import {useLocation} from '@docusaurus/router'; // used to dogfood custom navbar elements are possible @@ -13,7 +13,7 @@ import {useLocation} from '@docusaurus/router'; export default function CustomDogfoodNavbarItem(props: { content: string; mobile?: boolean; -}): JSX.Element | null { +}): ReactNode { const {pathname} = useLocation(); const shouldRender = pathname === '/tests' || pathname.startsWith('/tests/'); if (!shouldRender) { diff --git a/website/src/components/Playground/index.tsx b/website/src/components/Playground/index.tsx index 052f51389e..fc03bf4c6e 100644 --- a/website/src/components/Playground/index.tsx +++ b/website/src/components/Playground/index.tsx @@ -7,7 +7,7 @@ /* eslint-disable global-require */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import clsx from 'clsx'; import Translate from '@docusaurus/Translate'; import Link from '@docusaurus/Link'; @@ -56,7 +56,7 @@ interface Props { image: string; url: string; urlTS: string; - description: JSX.Element; + description: ReactNode; } function PlaygroundCard({name, image, url, urlTS, description}: Props) { @@ -92,7 +92,7 @@ function PlaygroundCard({name, image, url, urlTS, description}: Props) { ); } -export function PlaygroundCardsRow(): JSX.Element { +export function PlaygroundCardsRow(): ReactNode { return ( <div className="row"> {Playgrounds.map((playground) => ( diff --git a/website/src/components/ProductHuntCard.tsx b/website/src/components/ProductHuntCard.tsx index d223f47e96..3f5b0a6c29 100644 --- a/website/src/components/ProductHuntCard.tsx +++ b/website/src/components/ProductHuntCard.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import type {ComponentProps} from 'react'; +import type {ComponentProps, ReactNode} from 'react'; import React from 'react'; import clsx from 'clsx'; import Link from '@docusaurus/Link'; @@ -16,7 +16,7 @@ export default function ProductHuntCard({ }: { className?: string; style?: ComponentProps<'a'>['style']; -}): JSX.Element { +}): ReactNode { return ( <Link to="https://www.producthunt.com/posts/docusaurus-2-0?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-docusaurus-2-0" diff --git a/website/src/components/Svg/index.tsx b/website/src/components/Svg/index.tsx index a37a4eddd7..69f27f00c9 100644 --- a/website/src/components/Svg/index.tsx +++ b/website/src/components/Svg/index.tsx @@ -18,7 +18,7 @@ export type SvgIconProps = ComponentProps<'svg'> & { children: ReactNode; // Node passed into the SVG element. }; -export default function Svg(props: SvgIconProps): JSX.Element { +export default function Svg(props: SvgIconProps): ReactNode { const { svgClass, colorAttr, diff --git a/website/src/components/TeamProfileCards/index.tsx b/website/src/components/TeamProfileCards/index.tsx index b2a6edeb94..331ed26960 100644 --- a/website/src/components/TeamProfileCards/index.tsx +++ b/website/src/components/TeamProfileCards/index.tsx @@ -78,7 +78,7 @@ function TeamProfileCardCol(props: ProfileProps) { ); } -export function ActiveTeamRow(): JSX.Element { +export function ActiveTeamRow(): ReactNode { return ( <div className="row"> <TeamProfileCardCol @@ -117,7 +117,7 @@ export function ActiveTeamRow(): JSX.Element { ); } -export function HonoraryAlumniTeamRow(): JSX.Element { +export function HonoraryAlumniTeamRow(): ReactNode { return ( <div className="row"> <TeamProfileCardCol @@ -168,7 +168,7 @@ export function HonoraryAlumniTeamRow(): JSX.Element { ); } -export function StudentFellowsTeamRow(): JSX.Element { +export function StudentFellowsTeamRow(): ReactNode { return ( <div className="row"> <TeamProfileCardCol diff --git a/website/src/components/Tweet/index.tsx b/website/src/components/Tweet/index.tsx index a97bcce634..97d4040289 100644 --- a/website/src/components/Tweet/index.tsx +++ b/website/src/components/Tweet/index.tsx @@ -28,7 +28,7 @@ export default function Tweet({ content, date, githubUsername, -}: Props): JSX.Element { +}: Props): ReactNode { return ( <div className={clsx('card', styles.tweet)}> <div className="card__header"> diff --git a/website/src/components/TweetQuote/index.tsx b/website/src/components/TweetQuote/index.tsx index 9092fa3435..61597a4005 100644 --- a/website/src/components/TweetQuote/index.tsx +++ b/website/src/components/TweetQuote/index.tsx @@ -26,7 +26,7 @@ export default function TweetQuote({ name, job, children, -}: Props): JSX.Element { +}: Props): ReactNode { const avatar = `https://unavatar.io/x/${handle}`; const profileUrl = `https://x.com/${handle}`; return ( diff --git a/website/src/components/UpgradeGuide/index.tsx b/website/src/components/UpgradeGuide/index.tsx index 5cb2f118f1..0d3fbdbd4f 100644 --- a/website/src/components/UpgradeGuide/index.tsx +++ b/website/src/components/UpgradeGuide/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import { useLatestVersion, useActiveDocContext, @@ -114,7 +114,7 @@ function VersionNotice() { return null; } -export default function UpgradeGuide(): JSX.Element { +export default function UpgradeGuide(): ReactNode { return ( <> <VersionNotice /> diff --git a/website/src/components/Versions.tsx b/website/src/components/Versions.tsx index 74be4c26b4..9ce7547273 100644 --- a/website/src/components/Versions.tsx +++ b/website/src/components/Versions.tsx @@ -27,11 +27,7 @@ type ContextValue = { const Context = React.createContext<ContextValue | null>(null); -export function VersionsProvider({ - children, -}: { - children: ReactNode; -}): JSX.Element { +export function VersionsProvider({children}: {children: ReactNode}): ReactNode { const [canaryVersion, setCanaryVersion] = useState<ContextValue | null>(null); const mounted = useRef(true); useEffect(() => { @@ -70,7 +66,7 @@ function useStableVersion(): string { : lastVersion; } -export function CanaryVersion(): JSX.Element { +export function CanaryVersion(): ReactNode { const canaryVersion = useContext(Context); // Show a sensible name return canaryVersion ? ( @@ -90,7 +86,7 @@ export function CanaryVersion(): JSX.Element { ); } -export function StableVersion(): JSX.Element { +export function StableVersion(): ReactNode { const currentVersion = useStableVersion(); return <span>{currentVersion}</span>; } @@ -104,17 +100,17 @@ function useStableMajorVersionNumber(): number { return useNextMajorVersionNumber() - 1; } -export function NextMajorVersion(): JSX.Element { +export function NextMajorVersion(): ReactNode { const majorVersionNumber = useNextMajorVersionNumber(); return <span>{majorVersionNumber}</span>; } -export function StableMajorVersion(): JSX.Element { +export function StableMajorVersion(): ReactNode { const majorVersionNumber = useStableMajorVersionNumber(); return <span>{majorVersionNumber}</span>; } -function GitBranchLink({branch}: {branch: string}): JSX.Element { +function GitBranchLink({branch}: {branch: string}): ReactNode { return ( <Link to={`https://github.com/facebook/docusaurus/tree/${branch}`}> <code>{branch}</code> @@ -122,13 +118,13 @@ function GitBranchLink({branch}: {branch: string}): JSX.Element { ); } -export function StableMajorBranchLink(): JSX.Element { +export function StableMajorBranchLink(): ReactNode { const majorVersionNumber = useStableMajorVersionNumber(); const branch = `docusaurus-v${majorVersionNumber}`; return <GitBranchLink branch={branch} />; } -export function NextMajorBranchLink(): JSX.Element { +export function NextMajorBranchLink(): ReactNode { return <GitBranchLink branch="main" />; } @@ -156,7 +152,7 @@ export function InsertIfCanaryVersionKnown({ return null; } -export function PackageJSONDiff(): JSX.Element { +export function PackageJSONDiff(): ReactNode { const canaryVersion = useContext(Context)?.name ?? '0.0.0-4922'; const stableVersion = useStableVersion(); return ( @@ -170,7 +166,7 @@ export function PackageJSONDiff(): JSX.Element { ); } -export function PublishTime(): JSX.Element | null { +export function PublishTime(): ReactNode { const time = useContext(Context)?.time; if (!time) { return null; diff --git a/website/src/data/features.tsx b/website/src/data/features.tsx index 6e154c6342..015f9d82b9 100644 --- a/website/src/data/features.tsx +++ b/website/src/data/features.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import Translate, {translate} from '@docusaurus/Translate'; export type FeatureItem = { @@ -15,7 +15,7 @@ export type FeatureItem = { width: number; height: number; }; - text: JSX.Element; + text: ReactNode; }; const FEATURES: FeatureItem[] = [ diff --git a/website/src/data/showcase/datagit.png b/website/src/data/showcase/datagit.png index bd1f065f9d..c42475496f 100644 Binary files a/website/src/data/showcase/datagit.png and b/website/src/data/showcase/datagit.png differ diff --git a/website/src/data/showcase/prismatic.png b/website/src/data/showcase/prismatic.png index df575e675b..e7b4d49a63 100644 Binary files a/website/src/data/showcase/prismatic.png and b/website/src/data/showcase/prismatic.png differ diff --git a/website/src/data/users.tsx b/website/src/data/users.tsx index 459900e295..b742cd17e9 100644 --- a/website/src/data/users.tsx +++ b/website/src/data/users.tsx @@ -61,14 +61,6 @@ export type TagType = // Add sites to this list // prettier-ignore const Users: User[] = [ - { - title: 'AgileTs', - description: 'Global State and Logic Framework for reactive Applications', - preview: require('./showcase/agilets.png'), - website: 'https://agile-ts.org/', - source: 'https://github.com/agile-ts/documentation', - tags: ['opensource', 'design'], - }, { title: 'AI-Speaker', description: 'Local, reliable, fast and private Audio and IoT gate.', @@ -309,10 +301,10 @@ const Users: User[] = [ { title: 'Datagit', description: - 'A persian tutorial website strive to make quality education for everyone.', + 'A Persian tutorial website strives to make quality education for everyone.', preview: require('./showcase/datagit.png'), website: 'https://datagit.ir/', - source: 'https://github.com/ghaseminya/datagit_v2.docusaurus', + source: 'https://github.com/massoudmaboudi/datagit', tags: ['opensource', 'favorite', 'rtl'], }, { @@ -1123,11 +1115,11 @@ const Users: User[] = [ }, { title: 'Prismatic', - description: 'An Integration Platform for B2B Software Companies', + description: 'The Embedded Integration Platform for B2B SaaS Teams', preview: require('./showcase/prismatic.png'), website: 'https://prismatic.io/docs/', source: null, - tags: ['product'], + tags: ['design', 'large', 'product'], }, { title: 'Pyre', @@ -1827,7 +1819,7 @@ const Users: User[] = [ description: 'A DSL for building full-stack web apps with less boilerplate.', preview: require('./showcase/wasp.png'), - website: 'https://wasp-lang.dev/', + website: 'https://wasp.sh/', source: 'https://github.com/wasp-lang/wasp/tree/main/web', tags: ['opensource'], }, diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx index fa71e6cd9e..22f270186e 100644 --- a/website/src/pages/index.tsx +++ b/website/src/pages/index.tsx @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +import type {ReactNode} from 'react'; import clsx from 'clsx'; import LiteYouTubeEmbed from 'react-lite-youtube-embed'; import Link from '@docusaurus/Link'; @@ -257,7 +258,7 @@ function TopBanner() { ); } -export default function Home(): JSX.Element { +export default function Home(): ReactNode { const { siteConfig: {customFields, tagline}, } = useDocusaurusContext(); diff --git a/website/src/pages/showcase/index.tsx b/website/src/pages/showcase/index.tsx index 471342f120..de338e3ca8 100644 --- a/website/src/pages/showcase/index.tsx +++ b/website/src/pages/showcase/index.tsx @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +import type {ReactNode} from 'react'; import Translate, {translate} from '@docusaurus/Translate'; import Link from '@docusaurus/Link'; @@ -35,7 +36,7 @@ function ShowcaseHeader() { ); } -export default function Showcase(): JSX.Element { +export default function Showcase(): ReactNode { return ( <Layout title={TITLE} description={DESCRIPTION}> <main className="margin-vert--lg"> diff --git a/website/src/pages/versions.tsx b/website/src/pages/versions.tsx index 895bb7184a..5e453e27d1 100644 --- a/website/src/pages/versions.tsx +++ b/website/src/pages/versions.tsx @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +import type {ReactNode} from 'react'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import Link from '@docusaurus/Link'; import Translate from '@docusaurus/Translate'; @@ -34,7 +35,7 @@ function ReleaseNotesLabel() { ); } -export default function Version(): JSX.Element { +export default function Version(): ReactNode { const { siteConfig: {organizationName, projectName}, } = useDocusaurusContext(); diff --git a/website/src/plugins/changelog/index.js b/website/src/plugins/changelog/index.js deleted file mode 100644 index 2636bc9b9c..0000000000 --- a/website/src/plugins/changelog/index.js +++ /dev/null @@ -1,160 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import path from 'path'; -import fs from 'fs-extra'; -import pluginContentBlog from '@docusaurus/plugin-content-blog'; -import {aliasedSitePath, docuHash, normalizeUrl} from '@docusaurus/utils'; - -/** - * Multiple versions may be published on the same day, causing the order to be - * the reverse. Therefore, our publish time has a "fake hour" to order them. - */ -const publishTimes = new Set(); -/** - * @type {Record<string, {name: string, url: string,alias: string, imageURL: string}>} - */ -const authorsMap = {}; - -/** - * @param {string} section - */ -function processSection(section) { - const title = section - .match(/\n## .*/)?.[0] - .trim() - .replace('## ', ''); - if (!title) { - return null; - } - const content = section - .replace(/\n## .*/, '') - .trim() - .replace('running_woman', 'running'); - - let authors = content.match(/## Committers: \d.*/s); - if (authors) { - authors = authors[0] - .match(/- .*/g) - .map( - (line) => - line.match( - /- (?:(?<name>.*?) \()?\[@(?<alias>.*)\]\((?<url>.*?)\)\)?/, - ).groups, - ) - .map((author) => ({ - ...author, - name: author.name ?? author.alias, - imageURL: `https://github.com/${author.alias}.png`, - })) - .sort((a, b) => a.url.localeCompare(b.url)); - - authors.forEach((author) => { - authorsMap[author.alias] = author; - }); - } - let hour = 20; - const date = title.match(/ \((?<date>.*)\)/)?.groups.date; - while (publishTimes.has(`${date}T${hour}:00`)) { - hour -= 1; - } - publishTimes.add(`${date}T${hour}:00`); - - return { - title: title.replace(/ \(.*\)/, ''), - content: `--- -mdx: - format: md -date: ${`${date}T${hour}:00`}${ - authors - ? ` -authors: -${authors.map((author) => ` - '${author.alias}'`).join('\n')}` - : '' - } ---- - -# ${title.replace(/ \(.*\)/, '')} - -<!-- truncate --> - -${content.replace(/####/g, '##')}`, - }; -} - -/** - * @param {import('@docusaurus/types').LoadContext} context - * @returns {import('@docusaurus/types').Plugin} - */ -export default async function ChangelogPlugin(context, options) { - const generateDir = path.join(context.siteDir, 'changelog/source'); - const blogPlugin = await pluginContentBlog.default(context, { - ...options, - path: generateDir, - id: 'changelog', - blogListComponent: '@theme/ChangelogList', - blogPostComponent: '@theme/ChangelogPage', - }); - const changelogPath = path.join(__dirname, '../../../../CHANGELOG.md'); - return { - ...blogPlugin, - name: 'changelog-plugin', - async loadContent() { - const fileContent = await fs.readFile(changelogPath, 'utf-8'); - const sections = fileContent - .split(/(?=\n## )/) - .map(processSection) - .filter(Boolean); - await Promise.all( - sections.map((section) => - fs.outputFile( - path.join(generateDir, `${section.title}.md`), - section.content, - ), - ), - ); - const authorsPath = path.join(generateDir, 'authors.json'); - await fs.outputFile(authorsPath, JSON.stringify(authorsMap, null, 2)); - const content = await blogPlugin.loadContent(); - content.blogPosts.forEach((post, index) => { - const pageIndex = Math.floor(index / options.postsPerPage); - post.metadata.listPageLink = normalizeUrl([ - context.baseUrl, - options.routeBasePath, - pageIndex === 0 ? '/' : `/page/${pageIndex + 1}`, - ]); - }); - return content; - }, - configureWebpack(...args) { - const config = blogPlugin.configureWebpack(...args); - const pluginDataDirRoot = path.join( - context.generatedFilesDir, - 'changelog-plugin', - 'default', - ); - // Redirect the metadata path to our folder - const mdxLoader = config.module.rules[0].use[0]; - mdxLoader.options.metadataPath = (mdxPath) => { - // Note that metadataPath must be the same/in-sync as - // the path from createData for each MDX. - const aliasedPath = aliasedSitePath(mdxPath, context.siteDir); - return path.join(pluginDataDirRoot, `${docuHash(aliasedPath)}.json`); - }; - return config; - }, - getThemePath() { - return './theme'; - }, - getPathsToWatch() { - // Don't watch the generated dir - return [changelogPath]; - }, - }; -} - -export const {validateOptions} = pluginContentBlog; diff --git a/website/src/plugins/changelog/index.ts b/website/src/plugins/changelog/index.ts new file mode 100644 index 0000000000..46f5f08efb --- /dev/null +++ b/website/src/plugins/changelog/index.ts @@ -0,0 +1,208 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import path from 'path'; +import fs from 'fs-extra'; +import pluginContentBlog from '@docusaurus/plugin-content-blog'; +import {aliasedSitePath, docuHash, normalizeUrl} from '@docusaurus/utils'; + +export {validateOptions} from '@docusaurus/plugin-content-blog'; + +/** + * Multiple versions may be published on the same day, causing the order to be + * the reverse. Therefore, our publish time has a "fake hour" to order them. + */ +// TODO may leak small amount of memory in multi-locale builds +const publishTimes = new Set<string>(); + +type Author = {name: string; url: string; alias: string; imageURL: string}; + +type AuthorsMap = Record<string, Author>; + +type ChangelogEntry = { + title: string; + content: string; + authors: Author[]; +}; + +function parseAuthor(committerLine: string): Author { + const groups = committerLine.match( + /- (?:(?<name>.*?) \()?\[@(?<alias>.*)\]\((?<url>.*?)\)\)?/, + )!.groups as {name: string; alias: string; url: string}; + + return { + ...groups, + name: groups.name ?? groups.alias, + imageURL: `https://github.com/${groups.alias}.png`, + }; +} + +function parseAuthors(content: string): Author[] { + const committersContent = content.match(/## Committers: \d.*/s)?.[0]; + if (!committersContent) { + return []; + } + const committersLines = committersContent.match(/- .*/g)!; + + const authors = committersLines + .map(parseAuthor) + .sort((a, b) => a.url.localeCompare(b.url)); + + return authors; +} + +function createAuthorsMap(changelogEntries: ChangelogEntry[]): AuthorsMap { + const allAuthors = changelogEntries.flatMap((entry) => entry.authors); + const authorsMap: AuthorsMap = {}; + allAuthors?.forEach((author) => { + authorsMap[author.alias] = author; + }); + return authorsMap; +} + +function toChangelogEntry(sectionContent: string): ChangelogEntry | null { + const title = sectionContent + .match(/\n## .*/)?.[0] + .trim() + .replace('## ', ''); + if (!title) { + return null; + } + const content = sectionContent + .replace(/\n## .*/, '') + .trim() + .replace('running_woman', 'running'); + + const authors = parseAuthors(content); + + let hour = 20; + const date = title.match(/ \((?<date>.*)\)/)?.groups!.date; + while (publishTimes.has(`${date}T${hour}:00`)) { + hour -= 1; + } + publishTimes.add(`${date}T${hour}:00`); + + return { + authors, + title: title.replace(/ \(.*\)/, ''), + content: `--- +mdx: + format: md +date: ${`${date}T${hour}:00`}${ + authors.length > 0 + ? ` +authors: +${authors.map((author) => ` - '${author.alias}'`).join('\n')}` + : '' + } +--- + +# ${title.replace(/ \(.*\)/, '')} + +<!-- truncate --> + +${content.replace(/####/g, '##')}`, + }; +} + +function toChangelogEntries(fileContent: string): ChangelogEntry[] { + return fileContent + .split(/(?=\n## )/) + .map(toChangelogEntry) + .filter((s): s is ChangelogEntry => s !== null); +} + +async function createBlogFiles( + generateDir: string, + changelogEntries: ChangelogEntry[], +) { + await Promise.all( + changelogEntries.map((changelogEntry) => + fs.outputFile( + path.join(generateDir, `${changelogEntry.title}.md`), + changelogEntry.content, + ), + ), + ); + + await fs.outputFile( + path.join(generateDir, 'authors.json'), + JSON.stringify(createAuthorsMap(changelogEntries), null, 2), + ); +} + +const ChangelogPlugin: typeof pluginContentBlog = + async function ChangelogPlugin(context, options) { + const generateDir = path.join(context.siteDir, 'changelog/source'); + const blogPlugin = await pluginContentBlog(context, { + ...options, + path: generateDir, + id: 'changelog', + blogListComponent: '@theme/ChangelogList', + blogPostComponent: '@theme/ChangelogPage', + }); + const changelogPath = path.join(__dirname, '../../../../CHANGELOG.md'); + return { + ...blogPlugin, + name: 'changelog-plugin', + + async loadContent() { + const fileContent = await fs.readFile(changelogPath, 'utf-8'); + const changelogEntries = toChangelogEntries(fileContent); + + // We have to create intermediate files here + // Unfortunately Docusaurus doesn't have yet any concept of virtual file + await createBlogFiles(generateDir, changelogEntries); + + // Read the files we actually just wrote + const content = (await blogPlugin.loadContent?.())!; + + content.blogPosts.forEach((post, index) => { + const pageIndex = Math.floor( + index / (options.postsPerPage as number), + ); + // @ts-expect-error: TODO Docusaurus use interface declaration merging + post.metadata.listPageLink = normalizeUrl([ + context.baseUrl, + options.routeBasePath, + pageIndex === 0 ? '/' : `/page/${pageIndex + 1}`, + ]); + }); + return content; + }, + + configureWebpack(...args) { + const config = blogPlugin.configureWebpack?.(...args); + const pluginDataDirRoot = path.join( + context.generatedFilesDir, + 'changelog-plugin', + 'default', + ); + // Redirect the metadata path to our folder + // @ts-expect-error: unsafe but works + const mdxLoader = config.module.rules[0].use[0]; + mdxLoader.options.metadataPath = (mdxPath: string) => { + // Note that metadataPath must be the same/in-sync as + // the path from createData for each MDX. + const aliasedPath = aliasedSitePath(mdxPath, context.siteDir); + return path.join(pluginDataDirRoot, `${docuHash(aliasedPath)}.json`); + }; + return config; + }, + + getThemePath() { + return './theme'; + }, + + getPathsToWatch() { + // Don't watch the generated dir + return [changelogPath]; + }, + }; + }; + +export default ChangelogPlugin; diff --git a/website/src/plugins/changelog/theme/ChangelogItem/Header/Author/index.tsx b/website/src/plugins/changelog/theme/ChangelogItem/Header/Author/index.tsx index b37b0f5bf9..90a3497dd1 100644 --- a/website/src/plugins/changelog/theme/ChangelogItem/Header/Author/index.tsx +++ b/website/src/plugins/changelog/theme/ChangelogItem/Header/Author/index.tsx @@ -5,17 +5,14 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import clsx from 'clsx'; import Link from '@docusaurus/Link'; import type {Props} from '@theme/Blog/Components/Author'; import styles from './styles.module.css'; -export default function ChangelogAuthor({ - author, - className, -}: Props): JSX.Element { +export default function ChangelogAuthor({author, className}: Props): ReactNode { const {name, url, imageURL} = author; return ( <div className={clsx('avatar margin-bottom--sm', className)}> diff --git a/website/src/plugins/changelog/theme/ChangelogItem/Header/Authors/index.tsx b/website/src/plugins/changelog/theme/ChangelogItem/Header/Authors/index.tsx index 248cdb7802..9869799df4 100644 --- a/website/src/plugins/changelog/theme/ChangelogItem/Header/Authors/index.tsx +++ b/website/src/plugins/changelog/theme/ChangelogItem/Header/Authors/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React, {useState} from 'react'; +import React, {type ReactNode, useState} from 'react'; import clsx from 'clsx'; import {useBlogPost} from '@docusaurus/plugin-content-blog/client'; import ChangelogItemHeaderAuthor from '@theme/ChangelogItem/Header/Author'; @@ -15,9 +15,7 @@ import type {Props} from '@theme/BlogPostItem/Header/Authors'; import styles from './styles.module.css'; // Component responsible for the authors layout -export default function BlogPostAuthors({ - className, -}: Props): JSX.Element | null { +export default function BlogPostAuthors({className}: Props): ReactNode { const { metadata: {authors}, assets, diff --git a/website/src/plugins/changelog/theme/ChangelogItem/Header/index.tsx b/website/src/plugins/changelog/theme/ChangelogItem/Header/index.tsx index e3fe6c9918..a8d591e4bc 100644 --- a/website/src/plugins/changelog/theme/ChangelogItem/Header/index.tsx +++ b/website/src/plugins/changelog/theme/ChangelogItem/Header/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import {useBlogPost} from '@docusaurus/plugin-content-blog/client'; import BlogPostItemHeaderTitle from '@theme/BlogPostItem/Header/Title'; @@ -24,7 +24,7 @@ function ChangelogTitle() { ); } -export default function ChangelogItemHeader(): JSX.Element { +export default function ChangelogItemHeader(): ReactNode { return ( <header> <ChangelogTitle /> diff --git a/website/src/plugins/changelog/theme/ChangelogItem/index.tsx b/website/src/plugins/changelog/theme/ChangelogItem/index.tsx index 87d7b865e2..166c345624 100644 --- a/website/src/plugins/changelog/theme/ChangelogItem/index.tsx +++ b/website/src/plugins/changelog/theme/ChangelogItem/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import ChangelogItemHeader from '@theme/ChangelogItem/Header'; import type {Props} from '@theme/BlogPostItem'; import BlogPostItemContainer from '@theme/BlogPostItem/Container'; @@ -13,7 +13,7 @@ import BlogPostItemContent from '@theme/BlogPostItem/Content'; import styles from './styles.module.css'; -export default function ChangelogItem({children}: Props): JSX.Element { +export default function ChangelogItem({children}: Props): ReactNode { return ( <BlogPostItemContainer className={styles.changelogItemContainer}> <ChangelogItemHeader /> diff --git a/website/src/plugins/changelog/theme/ChangelogList/Header/index.tsx b/website/src/plugins/changelog/theme/ChangelogList/Header/index.tsx index 6d995390b0..f475d50b8c 100644 --- a/website/src/plugins/changelog/theme/ChangelogList/Header/index.tsx +++ b/website/src/plugins/changelog/theme/ChangelogList/Header/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import Translate from '@docusaurus/Translate'; import Link from '@docusaurus/Link'; import Heading from '@theme/Heading'; @@ -61,7 +61,7 @@ export default function ChangelogListHeader({ blogTitle, }: { blogTitle: string; -}): JSX.Element { +}): ReactNode { return ( <header className="margin-bottom--lg"> <Heading as="h1" style={{fontSize: '3rem'}}> diff --git a/website/src/plugins/changelog/theme/ChangelogList/index.tsx b/website/src/plugins/changelog/theme/ChangelogList/index.tsx index d2315c32e2..9163c4bf6d 100644 --- a/website/src/plugins/changelog/theme/ChangelogList/index.tsx +++ b/website/src/plugins/changelog/theme/ChangelogList/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import clsx from 'clsx'; import { PageMetadata, @@ -20,7 +20,7 @@ import ChangelogItem from '@theme/ChangelogItem'; import ChangelogListHeader from '@theme/ChangelogList/Header'; import type {Props} from '@theme/BlogListPage'; -function ChangelogListMetadata(props: Props): JSX.Element { +function ChangelogListMetadata(props: Props): ReactNode { const {metadata} = props; const {blogTitle, blogDescription} = metadata; return ( @@ -31,7 +31,7 @@ function ChangelogListMetadata(props: Props): JSX.Element { ); } -function ChangelogListContent(props: Props): JSX.Element { +function ChangelogListContent(props: Props): ReactNode { const {metadata, items, sidebar} = props; const {blogTitle} = metadata; return ( @@ -43,7 +43,7 @@ function ChangelogListContent(props: Props): JSX.Element { ); } -export default function ChangelogList(props: Props): JSX.Element { +export default function ChangelogList(props: Props): ReactNode { return ( <HtmlClassNameProvider className={clsx( diff --git a/website/src/plugins/changelog/theme/ChangelogPage/index.tsx b/website/src/plugins/changelog/theme/ChangelogPage/index.tsx index a40661579d..3f3972e85f 100644 --- a/website/src/plugins/changelog/theme/ChangelogPage/index.tsx +++ b/website/src/plugins/changelog/theme/ChangelogPage/index.tsx @@ -39,7 +39,7 @@ function ChangelogPageContent({ }: { sidebar: BlogSidebar; children: ReactNode; -}): JSX.Element { +}): ReactNode { const {metadata, toc} = useBlogPost(); const {nextItem, prevItem, frontMatter} = metadata; const { @@ -73,7 +73,7 @@ function ChangelogPageContent({ // This page doesn't change anything. It's just swapping BlogPostItem with our // own ChangelogItem. We don't want to apply the swizzled item to the actual // blog. -export default function ChangelogPage(props: Props): JSX.Element { +export default function ChangelogPage(props: Props): ReactNode { const ChangelogContent = props.content; return ( <BlogPostProvider content={props.content} isBlogPostPage> diff --git a/website/src/plugins/changelog/theme/ChangelogPaginator/index.tsx b/website/src/plugins/changelog/theme/ChangelogPaginator/index.tsx index 76e99f97c4..ac1ca4f107 100644 --- a/website/src/plugins/changelog/theme/ChangelogPaginator/index.tsx +++ b/website/src/plugins/changelog/theme/ChangelogPaginator/index.tsx @@ -7,12 +7,12 @@ // Changed the text labels. -import React from 'react'; +import React, {type ReactNode} from 'react'; import Translate, {translate} from '@docusaurus/Translate'; import PaginatorNavLink from '@theme/PaginatorNavLink'; import type {Props} from '@theme/BlogPostPaginator'; -export default function ChangelogPaginator(props: Props): JSX.Element { +export default function ChangelogPaginator(props: Props): ReactNode { const {nextItem, prevItem} = props; return ( diff --git a/website/src/plugins/changelog/theme/Icon/Expand/index.tsx b/website/src/plugins/changelog/theme/Icon/Expand/index.tsx index 0326367a6f..9b0fb800a4 100644 --- a/website/src/plugins/changelog/theme/Icon/Expand/index.tsx +++ b/website/src/plugins/changelog/theme/Icon/Expand/index.tsx @@ -5,11 +5,11 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import type {Props} from '@theme/Icon/Expand'; -export default function IconExpand({expanded, ...props}: Props): JSX.Element { +export default function IconExpand({expanded, ...props}: Props): ReactNode { if (expanded) { return ( <svg diff --git a/website/src/plugins/changelog/theme/types.d.ts b/website/src/plugins/changelog/theme/types.d.ts index f6af8075f2..c6d29b7361 100644 --- a/website/src/plugins/changelog/theme/types.d.ts +++ b/website/src/plugins/changelog/theme/types.d.ts @@ -16,11 +16,11 @@ declare module '@theme/ChangelogList'; declare module '@theme/ChangelogList/Header'; declare module '@theme/Icon/Expand' { - import type {ComponentProps} from 'react'; + import type {ComponentProps, ReactNode} from 'react'; export interface Props extends ComponentProps<'svg'> { expanded?: boolean; } - export default function IconExpand(props: Props): JSX.Element; + export default function IconExpand(props: Props): ReactNode; } diff --git a/website/src/plugins/featureRequests/FeatureRequestsPage.tsx b/website/src/plugins/featureRequests/FeatureRequestsPage.tsx index 0ff26e826b..7cc1099bc3 100644 --- a/website/src/plugins/featureRequests/FeatureRequestsPage.tsx +++ b/website/src/plugins/featureRequests/FeatureRequestsPage.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React, {useEffect} from 'react'; +import React, {type ReactNode, useEffect} from 'react'; import clsx from 'clsx'; import {useColorMode} from '@docusaurus/theme-common'; import Layout from '@theme/Layout'; @@ -48,7 +48,7 @@ export default function FeatureRequests({ basePath, }: { basePath: string; -}): JSX.Element { +}): ReactNode { return ( <Layout title="Feedback" description="Docusaurus 2 Feature Requests page"> <CannyWidget basePath={basePath} /> diff --git a/website/src/theme/Admonition/Types.tsx b/website/src/theme/Admonition/Types.tsx index c7856ef20a..a4b5df33e3 100644 --- a/website/src/theme/Admonition/Types.tsx +++ b/website/src/theme/Admonition/Types.tsx @@ -5,12 +5,12 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import type {Props} from '@theme/Admonition'; import DefaultAdmonitionTypes from '@theme-original/Admonition/Types'; import Heading from '@theme/Heading'; -function MyCustomAdmonition(props: Props): JSX.Element { +function MyCustomAdmonition(props: Props): ReactNode { return ( <div style={{border: 'solid red', padding: 10}}> <Heading as="h5" style={{color: 'blue', fontSize: 30}}> diff --git a/website/src/theme/CodeBlock/index.tsx b/website/src/theme/CodeBlock/index.tsx index 82dc1b0f5f..172095db45 100644 --- a/website/src/theme/CodeBlock/index.tsx +++ b/website/src/theme/CodeBlock/index.tsx @@ -5,13 +5,13 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import CodeBlock from '@theme-original/CodeBlock'; import type {Props} from '@theme/CodeBlock'; // This component does nothing on purpose // Dogfood: wrapping a theme component already enhanced by another theme // See https://github.com/facebook/docusaurus/pull/5983 -export default function CodeBlockWrapper(props: Props): JSX.Element { +export default function CodeBlockWrapper(props: Props): ReactNode { return <CodeBlock {...props} />; } diff --git a/website/src/theme/ColorModeToggle.tsx b/website/src/theme/ColorModeToggle.tsx index 85e886bc75..70df415859 100644 --- a/website/src/theme/ColorModeToggle.tsx +++ b/website/src/theme/ColorModeToggle.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import OriginalToggle from '@theme-original/ColorModeToggle'; import { lightStorage, @@ -24,7 +24,7 @@ import type {Props} from '@theme/ColorModeToggle'; // session storage, and we need to apply the same style when toggling modes even // when we are not on the styling-layout page. The only way to do this so far is // by hooking into the Toggle component. -export default function ColorModeToggle(props: Props): JSX.Element { +export default function ColorModeToggle(props: Props): ReactNode { return ( <OriginalToggle {...props} diff --git a/website/src/theme/DocCategoryGeneratedIndexPage/index.tsx b/website/src/theme/DocCategoryGeneratedIndexPage/index.tsx index 043356c195..518fca9fc8 100644 --- a/website/src/theme/DocCategoryGeneratedIndexPage/index.tsx +++ b/website/src/theme/DocCategoryGeneratedIndexPage/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import {useLayoutDoc} from '@docusaurus/plugin-content-docs/client'; import Link from '@docusaurus/Link'; import Translate from '@docusaurus/Translate'; @@ -34,7 +34,7 @@ function HintFooter() { export default function DocCategoryGeneratedIndexPageWrapper( props: Props, -): JSX.Element { +): ReactNode { return ( <> <DocCategoryGeneratedIndexPage {...props} /> diff --git a/website/src/theme/Layout/index.tsx b/website/src/theme/Layout/index.tsx index 44034528ed..84e154ec19 100644 --- a/website/src/theme/Layout/index.tsx +++ b/website/src/theme/Layout/index.tsx @@ -5,13 +5,13 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {type ReactNode} from 'react'; import Layout from '@theme-original/Layout'; import type {Props} from '@theme/Layout'; // This component is only used to test for CSS insertion order import './styles.module.css'; -export default function LayoutWrapper(props: Props): JSX.Element { +export default function LayoutWrapper(props: Props): ReactNode { return <Layout {...props} />; } diff --git a/website/src/theme/ReactLiveScope/components.tsx b/website/src/theme/ReactLiveScope/components.tsx index 5e7cd12878..404c4f3d2e 100644 --- a/website/src/theme/ReactLiveScope/components.tsx +++ b/website/src/theme/ReactLiveScope/components.tsx @@ -5,9 +5,9 @@ * LICENSE file in the root directory of this source tree. */ -import React, {type ComponentProps} from 'react'; +import React, {type ComponentProps, type ReactNode} from 'react'; -export function ButtonExample(props: ComponentProps<'button'>): JSX.Element { +export function ButtonExample(props: ComponentProps<'button'>): ReactNode { return ( <button type="button" diff --git a/website/static/img/docusaurus.svg b/website/static/img/docusaurus.svg index 250f2fce73..b5dd0fcd45 100644 --- a/website/static/img/docusaurus.svg +++ b/website/static/img/docusaurus.svg @@ -1 +1 @@ -<svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path fill="#FFF" d="M99 52h84v34H99z"/><path d="M23 163c-7.398 0-13.843-4.027-17.303-10A19.886 19.886 0 003 163c0 11.046 8.954 20 20 20h20v-20H23z" fill="#3ECC5F"/><path d="M112.98 57.376L183 53V43c0-11.046-8.954-20-20-20H73l-2.5-4.33c-1.112-1.925-3.889-1.925-5 0L63 23l-2.5-4.33c-1.111-1.925-3.889-1.925-5 0L53 23l-2.5-4.33c-1.111-1.925-3.889-1.925-5 0L43 23c-.022 0-.042.003-.065.003l-4.142-4.141c-1.57-1.571-4.252-.853-4.828 1.294l-1.369 5.104-5.192-1.392c-2.148-.575-4.111 1.389-3.535 3.536l1.39 5.193-5.102 1.367c-2.148.576-2.867 3.259-1.296 4.83l4.142 4.142c0 .021-.003.042-.003.064l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 53l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 63l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 73l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 83l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 93l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 103l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 113l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 123l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 133l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 143l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 153l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 163c0 11.046 8.954 20 20 20h120c11.046 0 20-8.954 20-20V83l-70.02-4.376A10.645 10.645 0 01103 68c0-5.621 4.37-10.273 9.98-10.624" fill="#3ECC5F"/><path fill="#3ECC5F" d="M143 183h30v-40h-30z"/><path d="M193 158c-.219 0-.428.037-.639.064-.038-.15-.074-.301-.116-.451A5 5 0 00190.32 148a4.96 4.96 0 00-3.016 1.036 26.531 26.531 0 00-.335-.336 4.955 4.955 0 001.011-2.987 5 5 0 00-9.599-1.959c-.148-.042-.297-.077-.445-.115.027-.211.064-.42.064-.639a5 5 0 00-5-5 5 5 0 00-5 5c0 .219.037.428.064.639-.148.038-.297.073-.445.115a4.998 4.998 0 00-9.599 1.959c0 1.125.384 2.151 1.011 2.987-3.717 3.632-6.031 8.693-6.031 14.3 0 11.046 8.954 20 20 20 9.339 0 17.16-6.41 19.361-15.064.211.027.42.064.639.064a5 5 0 005-5 5 5 0 00-5-5" fill="#44D860"/><path fill="#3ECC5F" d="M153 123h30v-20h-30z"/><path d="M193 115.5a2.5 2.5 0 100-5c-.109 0-.214.019-.319.032-.02-.075-.037-.15-.058-.225a2.501 2.501 0 00-.963-4.807c-.569 0-1.088.197-1.508.518a6.653 6.653 0 00-.168-.168c.314-.417.506-.931.506-1.494a2.5 2.5 0 00-4.8-.979A9.987 9.987 0 00183 103c-5.522 0-10 4.478-10 10s4.478 10 10 10c.934 0 1.833-.138 2.69-.377a2.5 2.5 0 004.8-.979c0-.563-.192-1.077-.506-1.494.057-.055.113-.111.168-.168.42.321.939.518 1.508.518a2.5 2.5 0 00.963-4.807c.021-.074.038-.15.058-.225.105.013.21.032.319.032" fill="#44D860"/><path d="M63 55.5a2.5 2.5 0 01-2.5-2.5c0-4.136-3.364-7.5-7.5-7.5s-7.5 3.364-7.5 7.5a2.5 2.5 0 11-5 0c0-6.893 5.607-12.5 12.5-12.5S65.5 46.107 65.5 53a2.5 2.5 0 01-2.5 2.5" fill="#000"/><path d="M103 183h60c11.046 0 20-8.954 20-20V93h-60c-11.046 0-20 8.954-20 20v70z" fill="#FFFF50"/><path d="M168.02 124h-50.04a1 1 0 110-2h50.04a1 1 0 110 2m0 20h-50.04a1 1 0 110-2h50.04a1 1 0 110 2m0 20h-50.04a1 1 0 110-2h50.04a1 1 0 110 2m0-49.814h-50.04a1 1 0 110-2h50.04a1 1 0 110 2m0 19.814h-50.04a1 1 0 110-2h50.04a1 1 0 110 2m0 20h-50.04a1 1 0 110-2h50.04a1 1 0 110 2M183 61.611c-.012 0-.022-.006-.034-.005-3.09.105-4.552 3.196-5.842 5.923-1.346 2.85-2.387 4.703-4.093 4.647-1.889-.068-2.969-2.202-4.113-4.46-1.314-2.594-2.814-5.536-5.963-5.426-3.046.104-4.513 2.794-5.807 5.167-1.377 2.528-2.314 4.065-4.121 3.994-1.927-.07-2.951-1.805-4.136-3.813-1.321-2.236-2.848-4.75-5.936-4.664-2.994.103-4.465 2.385-5.763 4.4-1.373 2.13-2.335 3.428-4.165 3.351-1.973-.07-2.992-1.51-4.171-3.177-1.324-1.873-2.816-3.993-5.895-3.89-2.928.1-4.399 1.97-5.696 3.618-1.232 1.564-2.194 2.802-4.229 2.724a1 1 0 00-.072 2c3.017.101 4.545-1.8 5.872-3.487 1.177-1.496 2.193-2.787 4.193-2.855 1.926-.082 2.829 1.115 4.195 3.045 1.297 1.834 2.769 3.914 5.731 4.021 3.103.104 4.596-2.215 5.918-4.267 1.182-1.834 2.202-3.417 4.15-3.484 1.793-.067 2.769 1.35 4.145 3.681 1.297 2.197 2.766 4.686 5.787 4.796 3.125.108 4.634-2.62 5.949-5.035 1.139-2.088 2.214-4.06 4.119-4.126 1.793-.042 2.728 1.595 4.111 4.33 1.292 2.553 2.757 5.445 5.825 5.556l.169.003c3.064 0 4.518-3.075 5.805-5.794 1.139-2.41 2.217-4.68 4.067-4.773v-2z" fill="#000"/><path fill="#3ECC5F" d="M83 183h40v-40H83z"/><path d="M143 158c-.219 0-.428.037-.639.064-.038-.15-.074-.301-.116-.451A5 5 0 00140.32 148a4.96 4.96 0 00-3.016 1.036 26.531 26.531 0 00-.335-.336 4.955 4.955 0 001.011-2.987 5 5 0 00-9.599-1.959c-.148-.042-.297-.077-.445-.115.027-.211.064-.42.064-.639a5 5 0 00-5-5 5 5 0 00-5 5c0 .219.037.428.064.639-.148.038-.297.073-.445.115a4.998 4.998 0 00-9.599 1.959c0 1.125.384 2.151 1.011 2.987-3.717 3.632-6.031 8.693-6.031 14.3 0 11.046 8.954 20 20 20 9.339 0 17.16-6.41 19.361-15.064.211.027.42.064.639.064a5 5 0 005-5 5 5 0 00-5-5" fill="#44D860"/><path fill="#3ECC5F" d="M83 123h40v-20H83z"/><path d="M133 115.5a2.5 2.5 0 100-5c-.109 0-.214.019-.319.032-.02-.075-.037-.15-.058-.225a2.501 2.501 0 00-.963-4.807c-.569 0-1.088.197-1.508.518a6.653 6.653 0 00-.168-.168c.314-.417.506-.931.506-1.494a2.5 2.5 0 00-4.8-.979A9.987 9.987 0 00123 103c-5.522 0-10 4.478-10 10s4.478 10 10 10c.934 0 1.833-.138 2.69-.377a2.5 2.5 0 004.8-.979c0-.563-.192-1.077-.506-1.494.057-.055.113-.111.168-.168.42.321.939.518 1.508.518a2.5 2.5 0 00.963-4.807c.021-.074.038-.15.058-.225.105.013.21.032.319.032" fill="#44D860"/><path d="M143 41.75c-.16 0-.33-.02-.49-.05a2.52 2.52 0 01-.47-.14c-.15-.06-.29-.14-.431-.23-.13-.09-.259-.2-.38-.31-.109-.12-.219-.24-.309-.38s-.17-.28-.231-.43a2.619 2.619 0 01-.189-.96c0-.16.02-.33.05-.49.03-.16.08-.31.139-.47.061-.15.141-.29.231-.43.09-.13.2-.26.309-.38.121-.11.25-.22.38-.31.141-.09.281-.17.431-.23.149-.06.31-.11.47-.14.32-.07.65-.07.98 0 .159.03.32.08.47.14.149.06.29.14.43.23.13.09.259.2.38.31.11.12.22.25.31.38.09.14.17.28.23.43.06.16.11.31.14.47.029.16.05.33.05.49 0 .66-.271 1.31-.73 1.77-.121.11-.25.22-.38.31-.14.09-.281.17-.43.23a2.565 2.565 0 01-.96.19m20-1.25c-.66 0-1.3-.27-1.771-.73a3.802 3.802 0 01-.309-.38c-.09-.14-.17-.28-.231-.43a2.619 2.619 0 01-.189-.96c0-.66.27-1.3.729-1.77.121-.11.25-.22.38-.31.141-.09.281-.17.431-.23.149-.06.31-.11.47-.14.32-.07.66-.07.98 0 .159.03.32.08.47.14.149.06.29.14.43.23.13.09.259.2.38.31.459.47.73 1.11.73 1.77 0 .16-.021.33-.05.49-.03.16-.08.32-.14.47-.07.15-.14.29-.23.43-.09.13-.2.26-.31.38-.121.11-.25.22-.38.31-.14.09-.281.17-.43.23a2.565 2.565 0 01-.96.19" fill="#000"/></g></svg> +<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"><g fill="#3ECC5F"><path d="M23 163c-7.4 0-14-4-17.3-10A20 20 0 003 163c0 11 9 20 20 20h20v-20H23zm141 20h9v-4h-8z"/><path d="M183 53V43c0-11-9-20-20-20H73c-4-8-6-8-10 0-4-8-6-8-10 0-4-8-6-8-10 0-7-9-9-5-10.3 2.3-9-3-10.3-1.7-7.3 7.3-9 2-10 3-2.4 10.4-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10 0 11 9 20 20 20h120c11 0 20-9 20-20"/></g><path fill="#FFF" d="M183 83l-70-4.3c-13.3-1.5-13.3-19.8 0-21.3l70-4.4"/><use href="#h" x="60"/><use href="#f" x="50"/><path d="M103 183h60c11 0 20-9 20-20V93h-60c-11 0-20 9-20 20v70z" fill="#FFFF50"/><g fill="none" stroke="#000" stroke-width="2" stroke-linecap="round"><path d="M63 53a1 1 0 10-20 0" stroke-width="5"/><path d="M183 62.6c-5 0-5 10-10 10.7-5 0-5-10-10-10s-5 9-10 9-5-8.5-10-8.5-5 8-10 8-5-7.25-10-7.25-5 6.5-10 6.5" stroke-linecap="butt"/><path d="M168 113h-50m50 10h-50m50 10h-50m50 10h-50m50 10h-50m50 10h-50"/></g><circle cx="143" cy="39.3" r="2.5"/><circle cx="163" cy="38" r="2.5"/><circle cx="113" cy="71" r="1"/><path d="M83 123h40v-20H83zm0 60h40v-40H83z" fill="#3ECC5F"/><g id="h" fill="#44D860"><circle cx="123" cy="113" r="10"/><circle cx="128" cy="104.3" r="2.4"/><circle cx="131.7" cy="108" r="2.4"/><circle cx="133" cy="113" r="2.4"/><circle cx="131.7" cy="118" r="2.4"/><circle cx="128" cy="121.7" r="2.4"/></g><g id="f" fill="#44D860"><circle cx="123" cy="163" r="20"/><circle cx="113" cy="145.7" r="5"/><circle cx="123" cy="143" r="5"/><circle cx="133" cy="145.7" r="5"/><circle cx="140.3" cy="153" r="5"/><circle cx="143" cy="163" r="5"/></g></svg> diff --git a/website/static/img/docusaurus_keytar.svg b/website/static/img/docusaurus_keytar.svg index f7f324fe0b..2e40e1de79 100644 --- a/website/static/img/docusaurus_keytar.svg +++ b/website/static/img/docusaurus_keytar.svg @@ -1 +1 @@ -<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path d="M4.883.09v1.08a1 1 0 01-1 1H1a1 1 0 01-1-1V.09h4.883z" id="a"/><path d="M4.883.09v1.08a1 1 0 01-1 1H1a1 1 0 01-1-1V.09h4.883z" id="b"/></defs><g fill="none" fill-rule="evenodd"><path fill="#FFF" d="M99 52h84v34H99z"/><path d="M23 163c-7.398 0-13.843-4.027-17.303-10A19.886 19.886 0 003 163c0 11.046 8.954 20 20 20h20v-20H23z" fill="#3ECC5F"/><path d="M112.98 57.376L183 53V43c0-11.046-8.954-20-20-20H73l-2.5-4.33c-1.112-1.925-3.889-1.925-5 0L63 23l-2.5-4.33c-1.111-1.925-3.889-1.925-5 0L53 23l-2.5-4.33c-1.111-1.925-3.889-1.925-5 0L43 23c-.022 0-.042.003-.065.003l-4.142-4.141c-1.57-1.571-4.252-.853-4.828 1.294l-1.369 5.104-5.192-1.392c-2.148-.575-4.111 1.389-3.535 3.536l1.39 5.193-5.102 1.367c-2.148.576-2.867 3.259-1.296 4.83l4.142 4.142c0 .021-.003.042-.003.064l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 53l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 63l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 73l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 83l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 93l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 103l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 113l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 123l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 133l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 143l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 153l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 163c0 11.046 8.954 20 20 20h120c11.046 0 20-8.954 20-20V83l-70.02-4.376A10.645 10.645 0 01103 68c0-5.621 4.37-10.273 9.98-10.624" fill="#3ECC5F"/><path fill="#3ECC5F" d="M143 183h30v-40h-30z"/><path d="M193 158c-.219 0-.428.037-.639.064-.038-.15-.074-.301-.116-.451A5 5 0 00190.32 148a4.96 4.96 0 00-3.016 1.036 26.531 26.531 0 00-.335-.336 4.955 4.955 0 001.011-2.987 5 5 0 00-9.599-1.959c-.148-.042-.297-.077-.445-.115.027-.211.064-.42.064-.639a5 5 0 00-5-5 5 5 0 00-5 5c0 .219.037.428.064.639-.148.038-.297.073-.445.115a4.998 4.998 0 00-9.599 1.959c0 1.125.384 2.151 1.011 2.987-3.717 3.632-6.031 8.693-6.031 14.3 0 11.046 8.954 20 20 20 9.339 0 17.16-6.41 19.361-15.064.211.027.42.064.639.064a5 5 0 005-5 5 5 0 00-5-5" fill="#44D860"/><path fill="#3ECC5F" d="M153 123h30v-20h-30z"/><path d="M193 115.5a2.5 2.5 0 100-5c-.109 0-.214.019-.319.032-.02-.075-.037-.15-.058-.225a2.501 2.501 0 00-.963-4.807c-.569 0-1.088.197-1.508.518a6.653 6.653 0 00-.168-.168c.314-.417.506-.931.506-1.494a2.5 2.5 0 00-4.8-.979A9.987 9.987 0 00183 103c-5.522 0-10 4.478-10 10s4.478 10 10 10c.934 0 1.833-.138 2.69-.377a2.5 2.5 0 004.8-.979c0-.563-.192-1.077-.506-1.494.057-.055.113-.111.168-.168.42.321.939.518 1.508.518a2.5 2.5 0 00.963-4.807c.021-.074.038-.15.058-.225.105.013.21.032.319.032" fill="#44D860"/><path d="M63 55.5a2.5 2.5 0 01-2.5-2.5c0-4.136-3.364-7.5-7.5-7.5s-7.5 3.364-7.5 7.5a2.5 2.5 0 11-5 0c0-6.893 5.607-12.5 12.5-12.5S65.5 46.107 65.5 53a2.5 2.5 0 01-2.5 2.5" fill="#000"/><path d="M103 183h60c11.046 0 20-8.954 20-20V93h-60c-11.046 0-20 8.954-20 20v70z" fill="#FFFF50"/><path d="M168.02 124h-50.04a1 1 0 110-2h50.04a1 1 0 110 2m0 20h-50.04a1 1 0 110-2h50.04a1 1 0 110 2m0 20h-50.04a1 1 0 110-2h50.04a1 1 0 110 2m0-49.814h-50.04a1 1 0 110-2h50.04a1 1 0 110 2m0 19.814h-50.04a1 1 0 110-2h50.04a1 1 0 110 2m0 20h-50.04a1 1 0 110-2h50.04a1 1 0 110 2M183 61.611c-.012 0-.022-.006-.034-.005-3.09.105-4.552 3.196-5.842 5.923-1.346 2.85-2.387 4.703-4.093 4.647-1.889-.068-2.969-2.202-4.113-4.46-1.314-2.594-2.814-5.536-5.963-5.426-3.046.104-4.513 2.794-5.807 5.167-1.377 2.528-2.314 4.065-4.121 3.994-1.927-.07-2.951-1.805-4.136-3.813-1.321-2.236-2.848-4.75-5.936-4.664-2.994.103-4.465 2.385-5.763 4.4-1.373 2.13-2.335 3.428-4.165 3.351-1.973-.07-2.992-1.51-4.171-3.177-1.324-1.873-2.816-3.993-5.895-3.89-2.928.1-4.399 1.97-5.696 3.618-1.232 1.564-2.194 2.802-4.229 2.724a1 1 0 00-.072 2c3.017.101 4.545-1.8 5.872-3.487 1.177-1.496 2.193-2.787 4.193-2.855 1.926-.082 2.829 1.115 4.195 3.045 1.297 1.834 2.769 3.914 5.731 4.021 3.103.104 4.596-2.215 5.918-4.267 1.182-1.834 2.202-3.417 4.15-3.484 1.793-.067 2.769 1.35 4.145 3.681 1.297 2.197 2.766 4.686 5.787 4.796 3.125.108 4.634-2.62 5.949-5.035 1.139-2.088 2.214-4.06 4.119-4.126 1.793-.042 2.728 1.595 4.111 4.33 1.292 2.553 2.757 5.445 5.825 5.556l.169.003c3.064 0 4.518-3.075 5.805-5.794 1.139-2.41 2.217-4.68 4.067-4.773v-2z" fill="#000"/><path fill="#3ECC5F" d="M83 183h40v-40H83z"/><g transform="rotate(-15 433.487 -340.892)"><rect fill="#D8D8D8" x=".046" y=".014" width="84.522" height="33.367" rx="2"/><g transform="translate(1 20.75)" fill="#4A4A4A"><rect x="15.818" y=".339" width="4.883" height="4.883" rx="1"/><rect x="21.605" y=".339" width="4.883" height="4.883" rx="1"/><rect x="27.392" y=".339" width="4.883" height="4.883" rx="1"/><rect x="33.179" y=".339" width="4.883" height="4.883" rx="1"/><rect x="38.966" y=".339" width="4.883" height="4.883" rx="1"/><rect x="44.753" y=".339" width="4.883" height="4.883" rx="1"/><rect x="50.54" y=".339" width="4.883" height="4.883" rx="1"/><rect x="56.327" y=".339" width="4.883" height="4.883" rx="1"/><rect x="62.114" y=".339" width="4.883" height="4.883" rx="1"/><path d="M1.447.34h12.286a1 1 0 011 1v2.882a1 1 0 01-1 1H1.447a1 1 0 01-1-1V1.339a1 1 0 011-1zm67.634 0h12.287a1 1 0 011 1v2.882a1 1 0 01-1 1H69.08a1 1 0 01-1-1V1.339a1 1 0 011-1z"/></g><g transform="translate(1 9)" fill="#4A4A4A"><path d="M1.447.404h4.69a1 1 0 011 1v2.882a1 1 0 01-1 1h-4.69a1 1 0 01-1-1V1.404a1 1 0 011-1z"/><rect x="8.042" y=".404" width="4.883" height="4.883" rx="1"/><rect x="13.829" y=".404" width="4.883" height="4.883" rx="1"/><rect x="19.616" y=".404" width="4.883" height="4.883" rx="1"/><rect x="25.403" y=".404" width="4.883" height="4.883" rx="1"/><rect x="31.19" y=".404" width="4.883" height="4.883" rx="1"/><rect x="36.977" y=".404" width="4.883" height="4.883" rx="1"/><rect x="42.764" y=".404" width="4.883" height="4.883" rx="1"/><rect x="48.551" y=".404" width="4.883" height="4.883" rx="1"/><rect x="54.337" y=".404" width="4.883" height="4.883" rx="1"/><rect x="60.124" y=".404" width="4.883" height="4.883" rx="1"/><rect x="65.911" y=".404" width="4.883" height="4.883" rx="1"/><rect x="71.698" y=".404" width="4.883" height="4.883" rx="1"/><rect x="77.485" y=".404" width="4.883" height="4.883" rx="1"/></g><g transform="rotate(-180 41.684 4.375)" fill="#4A4A4A"><path d="M1 0h4.691a1 1 0 011 1v2.883a1 1 0 01-1 1H1a1 1 0 01-1-1V1a1 1 0 011-1z"/><rect x="7.595" width="4.883" height="4.883" rx="1"/><rect x="13.382" width="4.883" height="4.883" rx="1"/><rect x="19.169" width="4.883" height="4.883" rx="1"/><rect x="24.956" width="4.883" height="4.883" rx="1"/><rect x="30.743" width="4.883" height="4.883" rx="1"/><rect x="36.53" width="4.883" height="4.883" rx="1"/><rect x="42.317" width="4.883" height="4.883" rx="1"/><rect x="48.104" width="4.883" height="4.883" rx="1"/><rect x="53.891" width="4.883" height="4.883" rx="1"/><rect x="59.678" width="4.883" height="4.883" rx="1"/><rect x="65.465" width="4.883" height="4.883" rx="1"/><rect x="71.252" width="4.883" height="4.883" rx="1"/><rect x="77.038" width="4.883" height="4.883" rx="1"/><rect x="7.595" width="4.883" height="4.883" rx="1"/><rect x="13.382" width="4.883" height="4.883" rx="1"/><rect x="19.169" width="4.883" height="4.883" rx="1"/><rect x="24.956" width="4.883" height="4.883" rx="1"/><rect x="30.743" width="4.883" height="4.883" rx="1"/><rect x="36.53" width="4.883" height="4.883" rx="1"/><rect x="42.317" width="4.883" height="4.883" rx="1"/><rect x="48.104" width="4.883" height="4.883" rx="1"/><rect x="53.891" width="4.883" height="4.883" rx="1"/><rect x="59.678" width="4.883" height="4.883" rx="1"/><rect x="65.465" width="4.883" height="4.883" rx="1"/><rect x="71.252" width="4.883" height="4.883" rx="1"/><rect x="77.038" width="4.883" height="4.883" rx="1"/></g><g fill="#4A4A4A"><path d="M2.447 15.19h6.68a1 1 0 011 1v2.883a1 1 0 01-1 1h-6.68a1 1 0 01-1-1v-2.882a1 1 0 011-1z"/><g transform="translate(11.212 15.19)"><rect width="4.883" height="4.883" rx="1"/><rect x="5.787" width="4.883" height="4.883" rx="1"/><rect x="11.574" width="4.883" height="4.883" rx="1"/><rect x="17.361" width="4.883" height="4.883" rx="1"/><rect x="23.148" width="4.883" height="4.883" rx="1"/><rect x="28.935" width="4.883" height="4.883" rx="1"/><rect x="34.722" width="4.883" height="4.883" rx="1"/><rect x="40.508" width="4.883" height="4.883" rx="1"/><rect x="46.295" width="4.883" height="4.883" rx="1"/><rect x="52.082" width="4.883" height="4.883" rx="1"/><rect x="57.869" width="4.883" height="4.883" rx="1"/></g><path d="M76.05 15.19h6.318a1 1 0 011 1v2.883a1 1 0 01-1 1h-6.319a1 1 0 01-1-1v-2.882a1 1 0 011-1z"/></g><g transform="translate(1 26)" fill="#4A4A4A"><rect x=".447" y="1.126" width="4.883" height="4.883" rx="1"/><rect x="6.234" y="1.126" width="4.883" height="4.883" rx="1"/><rect x="12.021" y="1.126" width="4.883" height="4.883" rx="1"/><rect x="17.808" y="1.126" width="4.883" height="4.883" rx="1"/><path d="M24.594 1.126h27.84a1 1 0 011 1V5.01a1 1 0 01-1 1h-27.84a1 1 0 01-1-1V2.126a1 1 0 011-1zm30.743 0h3.607a1 1 0 011 1V5.01a1 1 0 01-1 1h-3.607a1 1 0 01-1-1V2.126a1 1 0 011-1z"/><rect x="60.848" y="1.126" width="4.883" height="4.883" rx="1"/><rect x="66.635" y="1.126" width="4.883" height="4.883" rx="1"/><rect x="77.485" y="1.126" width="4.883" height="4.883" rx="1"/><use xlink:href="#a" transform="rotate(-180 38.471 1.648)"/><use xlink:href="#b" transform="translate(72.06 3.839)"/></g><rect fill="#4A4A4A" x="1.808" y="1.085" width="81.379" height="2.17" rx="1.085"/><rect fill="#D8D8D8" opacity=".136" x="3.798" y="1.447" width="4.563" height="1.447" rx=".723"/><rect fill="#D8D8D8" opacity=".136" x="10.042" y="1.447" width="4.563" height="1.447" rx=".723"/><rect fill="#D8D8D8" opacity=".136" x="14.846" y="1.447" width="4.563" height="1.447" rx=".723"/><rect fill="#D8D8D8" opacity=".136" x="19.649" y="1.447" width="4.563" height="1.447" rx=".723"/><rect fill="#D8D8D8" opacity=".136" x="24.453" y="1.447" width="4.563" height="1.447" rx=".723"/><rect fill="#D8D8D8" opacity=".136" x="30.457" y="1.447" width="4.563" height="1.447" rx=".723"/><rect fill="#D8D8D8" opacity=".136" x="35.26" y="1.447" width="4.563" height="1.447" rx=".723"/><rect fill="#D8D8D8" opacity=".136" x="40.064" y="1.447" width="4.563" height="1.447" rx=".723"/><rect fill="#D8D8D8" opacity=".136" x="44.867" y="1.447" width="4.563" height="1.447" rx=".723"/><rect fill="#D8D8D8" opacity=".136" x="50.872" y="1.447" width="4.563" height="1.447" rx=".723"/><rect fill="#D8D8D8" opacity=".136" x="55.675" y="1.447" width="4.563" height="1.447" rx=".723"/><rect fill="#D8D8D8" opacity=".136" x="60.479" y="1.447" width="4.563" height="1.447" rx=".723"/><rect fill="#D8D8D8" opacity=".136" x="66.483" y="1.447" width="4.563" height="1.447" rx=".723"/><rect fill="#D8D8D8" opacity=".136" x="71.286" y="1.447" width="4.563" height="1.447" rx=".723"/><rect fill="#D8D8D8" opacity=".136" x="76.09" y="1.447" width="4.563" height="1.447" rx=".723"/></g><path d="M143 158c-.219 0-.428.037-.639.064-.038-.15-.074-.301-.116-.451A5 5 0 00140.32 148a4.96 4.96 0 00-3.016 1.036 26.531 26.531 0 00-.335-.336 4.955 4.955 0 001.011-2.987 5 5 0 00-9.599-1.959c-.148-.042-.297-.077-.445-.115.027-.211.064-.42.064-.639a5 5 0 00-5-5 5 5 0 00-5 5c0 .219.037.428.064.639-.148.038-.297.073-.445.115a4.998 4.998 0 00-9.599 1.959c0 1.125.384 2.151 1.011 2.987-3.717 3.632-6.031 8.693-6.031 14.3 0 11.046 8.954 20 20 20 9.339 0 17.16-6.41 19.361-15.064.211.027.42.064.639.064a5 5 0 005-5 5 5 0 00-5-5" fill="#44D860"/><path fill="#3ECC5F" d="M83 123h40v-20H83z"/><path d="M133 115.5a2.5 2.5 0 100-5c-.109 0-.214.019-.319.032-.02-.075-.037-.15-.058-.225a2.501 2.501 0 00-.963-4.807c-.569 0-1.088.197-1.508.518a6.653 6.653 0 00-.168-.168c.314-.417.506-.931.506-1.494a2.5 2.5 0 00-4.8-.979A9.987 9.987 0 00123 103c-5.522 0-10 4.478-10 10s4.478 10 10 10c.934 0 1.833-.138 2.69-.377a2.5 2.5 0 004.8-.979c0-.563-.192-1.077-.506-1.494.057-.055.113-.111.168-.168.42.321.939.518 1.508.518a2.5 2.5 0 00.963-4.807c.021-.074.038-.15.058-.225.105.013.21.032.319.032" fill="#44D860"/><path d="M143 41.75c-.16 0-.33-.02-.49-.05a2.52 2.52 0 01-.47-.14c-.15-.06-.29-.14-.431-.23-.13-.09-.259-.2-.38-.31-.109-.12-.219-.24-.309-.38s-.17-.28-.231-.43a2.619 2.619 0 01-.189-.96c0-.16.02-.33.05-.49.03-.16.08-.31.139-.47.061-.15.141-.29.231-.43.09-.13.2-.26.309-.38.121-.11.25-.22.38-.31.141-.09.281-.17.431-.23.149-.06.31-.11.47-.14.32-.07.65-.07.98 0 .159.03.32.08.47.14.149.06.29.14.43.23.13.09.259.2.38.31.11.12.22.25.31.38.09.14.17.28.23.43.06.16.11.31.14.47.029.16.05.33.05.49 0 .66-.271 1.31-.73 1.77-.121.11-.25.22-.38.31-.14.09-.281.17-.43.23a2.565 2.565 0 01-.96.19m20-1.25c-.66 0-1.3-.27-1.771-.73a3.802 3.802 0 01-.309-.38c-.09-.14-.17-.28-.231-.43a2.619 2.619 0 01-.189-.96c0-.66.27-1.3.729-1.77.121-.11.25-.22.38-.31.141-.09.281-.17.431-.23.149-.06.31-.11.47-.14.32-.07.66-.07.98 0 .159.03.32.08.47.14.149.06.29.14.43.23.13.09.259.2.38.31.459.47.73 1.11.73 1.77 0 .16-.021.33-.05.49-.03.16-.08.32-.14.47-.07.15-.14.29-.23.43-.09.13-.2.26-.31.38-.121.11-.25.22-.38.31-.14.09-.281.17-.43.23a2.565 2.565 0 01-.96.19" fill="#000"/></g></svg> \ No newline at end of file +<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"><defs><rect id="k" x="0" width="4.883" height="4.883" rx="1"/><rect id="fn" x="0" y="1.447" width="4.563" height="1.447" rx=".723"/><path d="M4.883.09v1.08a1 1 0 01-1 1H1a1 1 0 01-1-1V.09h4.883z" id="a"/></defs><g fill="#3ECC5F"><path d="M23 163c-7.4 0-14-4-17.3-10A20 20 0 003 163c0 11 9 20 20 20h20v-20H23zM164 183h9v-4h-8z"/><path d="M183 53V43c0-11-9-20-20-20H73c-4-8-6-8-10 0-4-8-6-8-10 0-4-8-6-8-10 0-7-9-9-5-10.3 2.3-9-3-10.3-1.7-7.3 7.3-9 2-10 3-2.4 10.4-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10 0 11 9 20 20 20h120c11 0 20-9 20-20"/></g><path fill="#FFF" d="M183 83l-70-4.3c-13.3-1.5-13.3-19.8 0-21.3l70-4.4"/><use href="#h" x="60"/><use href="#f" x="50"/><path d="M103 183h60c11 0 20-9 20-20V93h-60c-11 0-20 9-20 20v70z" fill="#FFFF50"/><g fill="none" stroke="#000" stroke-width="2" stroke-linecap="round"><path d="M63 53a1 1 0 10-20 0" stroke-width="5"/><path d="M183 62.6c-5 0-5 10-10 10.7-5 0-5-10-10-10s-5 9-10 9-5-8.5-10-8.5-5 8-10 8-5-7.25-10-7.25-5 6.5-10 6.5" stroke-linecap="butt"/><path d="M168 113h-50m50 10h-50m50 10h-50m50 10h-50m50 10h-50m50 10h-50"/></g><circle cx="143" cy="39.3" r="2.5"/><circle cx="163" cy="38" r="2.5"/><circle cx="113" cy="71" r="1"/><g transform="rotate(-15 433.487 -340.892)"><rect fill="#D8D8D8" width="84.522" height="33.367" rx="2"/><rect fill="#4A4A4A" x="1.808" y="1.085" width="81.379" height="2.17" rx="1.085"/><g fill="#D8D8D8" opacity=".136"><use href="#fn" x="3.798"/><use href="#fn" x="10.042"/><use href="#fn" x="14.846"/><use href="#fn" x="19.649"/><use href="#fn" x="24.453"/><use href="#fn" x="30.457"/><use href="#fn" x="35.26"/><use href="#fn" x="40.064"/><use href="#fn" x="44.867"/><use href="#fn" x="50.872"/><use href="#fn" x="55.675"/><use href="#fn" x="60.479"/><use href="#fn" x="66.483"/><use href="#fn" x="71.286"/><use href="#fn" x="76.09"/></g><g transform="rotate(-180 41.684 4.375)" fill="#4A4A4A"><use href="#k" x="7.595"/><use href="#k" x="13.382"/><use href="#k" x="19.169"/><use href="#k" x="24.956"/><use href="#k" x="30.743"/><use href="#k" x="36.53"/><use href="#k" x="42.317"/><use href="#k" x="48.104"/><use href="#k" x="53.891"/><use href="#k" x="59.678"/><use href="#k" x="65.465"/><use href="#k" x="71.252"/><use href="#k" x="77.038"/><use href="#k" x="7.595"/><use href="#k" x="13.382"/><use href="#k" x="19.169"/><use href="#k" x="24.956"/><use href="#k" x="30.743"/><use href="#k" x="36.53"/><use href="#k" x="42.317"/><use href="#k" x="48.104"/><use href="#k" x="53.891"/><use href="#k" x="59.678"/><use href="#k" x="65.465"/><use href="#k" x="71.252"/><use href="#k" x="77.038"/><rect rx="1" width="6.7" height="4.883"/></g><g transform="translate(1 9.5)" fill="#4A4A4A"><use href="#k" x="8.042"/><use href="#k" x="13.829"/><use href="#k" x="19.616"/><use href="#k" x="25.403"/><use href="#k" x="31.19"/><use href="#k" x="36.977"/><use href="#k" x="42.764"/><use href="#k" x="48.551"/><use href="#k" x="54.337"/><use href="#k" x="60.124"/><use href="#k" x="65.911"/><use href="#k" x="71.698"/><use href="#k" x="77.485"/></g><g fill="#4A4A4A"><g transform="translate(11.212 15.19)"><use href="#k"/><use href="#k" x="5.787"/><use href="#k" x="11.574"/><use href="#k" x="17.361"/><use href="#k" x="23.148"/><use href="#k" x="28.935"/><use href="#k" x="34.722"/><use href="#k" x="40.508"/><use href="#k" x="46.295"/><use href="#k" x="52.082"/><use href="#k" x="57.869"/></g><rect x="75" y="15.2" rx="1" width="8.4" height="4.883"/></g><g transform="translate(1 21.144)" fill="#4A4A4A"><use href="#k" x="15.818"/><use href="#k" x="21.605"/><use href="#k" x="27.392"/><use href="#k" x="33.179"/><use href="#k" x="38.966"/><use href="#k" x="44.753"/><use href="#k" x="50.54"/><use href="#k" x="56.327"/><use href="#k" x="62.114"/><rect x=".5" rx="1" width="14.3" height="4.883"/><rect x="68" rx="1" width="14.3" height="4.883"/></g><g transform="translate(1 27.126)" fill="#4A4A4A"><use href="#k" x=".447"/><use href="#k" x="6.234"/><use href="#k" x="12.021"/><use href="#k" x="17.808"/><rect x="23.5" rx="1" width="30" height="4.883"/><rect x="54.4" rx="1" width="5.6" height="4.883"/><use href="#k" x="60.848"/><use href="#k" x="66.635"/><use href="#k" x="77.485"/><use href="#a" transform="rotate(-180 38.471 1.074)"/><use href="#a" transform="translate(72.06 2.713)"/></g></g><g fill="#3ECC5F"><path d="M83 123h40v-20H83zM83 183h40v-40H83z"/></g><g id="h" fill="#44D860"><circle cx="123" cy="113" r="10"/><circle cx="128" cy="104.3" r="2.4"/><circle cx="131.7" cy="108" r="2.4"/><circle cx="133" cy="113" r="2.4"/><circle cx="131.7" cy="118" r="2.4"/><circle cx="128" cy="121.7" r="2.4"/></g><g id="f" fill="#44D860"><circle cx="123" cy="163" r="20"/><circle cx="113" cy="145.7" r="5"/><circle cx="123" cy="143" r="5"/><circle cx="133" cy="145.7" r="5"/><circle cx="140.3" cy="153" r="5"/><circle cx="143" cy="163" r="5"/></g></svg> \ No newline at end of file diff --git a/website/static/img/docusaurus_speed.svg b/website/static/img/docusaurus_speed.svg index f619db4a6c..63250382a9 100644 --- a/website/static/img/docusaurus_speed.svg +++ b/website/static/img/docusaurus_speed.svg @@ -1 +1 @@ -<svg width="250" height="200" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g opacity=".361"><path d="M43 163c-7.398 0-13.843-4.027-17.303-10A19.886 19.886 0 0023 163c0 11.046 8.954 20 20 20h20v-20H43z" fill="#3ECC5F"/><path d="M132.98 57.376L203 53V43c0-11.046-8.954-20-20-20H93l-2.5-4.33c-1.112-1.925-3.889-1.925-5 0L83 23l-2.5-4.33c-1.111-1.925-3.889-1.925-5 0L73 23l-2.5-4.33c-1.111-1.925-3.889-1.925-5 0L63 23c-.022 0-.042.003-.065.003l-4.142-4.141c-1.57-1.571-4.252-.853-4.828 1.294l-1.369 5.104-5.192-1.392c-2.148-.575-4.112 1.389-3.536 3.536l1.391 5.193-5.103 1.367c-2.147.576-2.866 3.259-1.295 4.83l4.141 4.142L43 43l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L43 53l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L43 63l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L43 73l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L43 83l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L43 93l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L43 103l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L43 113l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L43 123l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L43 133l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L43 143l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L43 153l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L43 163c0 11.046 8.955 20 20 20h120c11.046 0 20-8.954 20-20V83l-70.02-4.376A10.645 10.645 0 01123 68c0-5.621 4.37-10.273 9.98-10.624" fill="#3ECC5F"/><path d="M203 53V33c0-11.046-8.954-20-20-20H67.112c-16.524 0-29.937 13.362-30 29.885-.121 31.68-.075 47.581.139 47.705h165.75V53z" fill="#D0021B"/></g><g opacity=".361"><path d="M23 163c-7.398 0-13.843-4.027-17.303-10A19.886 19.886 0 003 163c0 11.046 8.954 20 20 20h20v-20H23z" fill="#3ECC5F"/><path d="M112.98 57.376L183 53V43c0-11.046-8.954-20-20-20H73l-2.5-4.33c-1.112-1.925-3.889-1.925-5 0L63 23l-2.5-4.33c-1.111-1.925-3.889-1.925-5 0L53 23l-2.5-4.33c-1.111-1.925-3.889-1.925-5 0L43 23c-.022 0-.042.003-.065.003l-4.142-4.141c-1.57-1.571-4.252-.853-4.828 1.294l-1.369 5.104-5.192-1.392c-2.148-.575-4.111 1.389-3.535 3.536l1.39 5.193-5.102 1.367c-2.148.576-2.867 3.259-1.296 4.83l4.142 4.142c0 .021-.003.042-.003.064l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 53l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 63l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 73l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 83l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 93l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 103l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 113l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 123l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 133l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 143l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 153l-4.33 2.5c-1.925 1.111-1.925 3.889 0 5L23 163c0 11.046 8.954 20 20 20h120c11.046 0 20-8.954 20-20V83l-70.02-4.376A10.645 10.645 0 01103 68c0-5.621 4.37-10.273 9.98-10.624" fill="#3ECC5F"/><path d="M183 53V33c0-11.046-8.954-20-20-20H47.112c-16.524 0-29.937 13.362-30 29.885-.121 31.68-.075 47.581.139 47.705h165.75V53z" fill="#D0021B"/></g><path fill="#FFF" d="M139 52h84v34h-84z"/><path d="M63 163c-7.398 0-13.843-4.027-17.303-10A19.886 19.886 0 0043 163c0 11.046 8.954 20 20 20h20v-20H63z" fill="#3ECC5F"/><path d="M152.98 57.376L223 53V43c0-11.046-8.954-20-20-20h-90l-2.5-4.33c-1.112-1.925-3.889-1.925-5 0L103 23l-2.5-4.33c-1.111-1.925-3.889-1.925-5 0L93 23l-2.5-4.33c-1.111-1.925-3.889-1.925-5 0L83 23c-.022 0-.042.003-.065.003l-4.142-4.141c-1.57-1.571-4.253-.853-4.829 1.294l-1.368 5.104-5.193-1.392c-2.147-.575-4.11 1.389-3.535 3.536l1.391 5.193-5.102 1.367c-2.147.576-2.866 3.259-1.295 4.83l4.14 4.142-.001.064-4.331 2.5c-1.924 1.111-1.924 3.889 0 5L63 53l-4.33 2.5c-1.924 1.111-1.924 3.889 0 5L63 63l-4.33 2.5c-1.924 1.111-1.924 3.889 0 5L63 73l-4.33 2.5c-1.924 1.111-1.924 3.889 0 5L63 83l-4.33 2.5c-1.924 1.111-1.924 3.889 0 5L63 93l-4.33 2.5c-1.924 1.111-1.924 3.889 0 5L63 103l-4.33 2.5c-1.924 1.111-1.924 3.889 0 5L63 113l-4.33 2.5c-1.924 1.111-1.924 3.889 0 5L63 123l-4.33 2.5c-1.924 1.111-1.924 3.889 0 5L63 133l-4.33 2.5c-1.924 1.111-1.924 3.889 0 5L63 143l-4.33 2.5c-1.924 1.111-1.924 3.889 0 5L63 153l-4.33 2.5c-1.924 1.111-1.924 3.889 0 5L63 163c0 11.046 8.955 20 20 20h120c11.046 0 20-8.954 20-20V83l-70.02-4.376A10.645 10.645 0 01143 68c0-5.621 4.37-10.273 9.98-10.624" fill="#3ECC5F"/><path fill="#3ECC5F" d="M183 183h30v-40h-30z"/><path d="M233 158c-.219 0-.428.037-.639.064-.038-.15-.074-.301-.116-.451A5 5 0 00230.32 148a4.96 4.96 0 00-3.016 1.036 26.531 26.531 0 00-.335-.336 4.955 4.955 0 001.011-2.987 5 5 0 00-9.599-1.959c-.148-.042-.297-.077-.445-.115.027-.211.064-.42.064-.639a5 5 0 00-5-5 5 5 0 00-5 5c0 .219.037.428.064.639-.148.038-.297.073-.445.115a4.998 4.998 0 00-9.599 1.959c0 1.125.384 2.151 1.011 2.987-3.717 3.632-6.031 8.693-6.031 14.3 0 11.046 8.954 20 20 20 9.339 0 17.16-6.41 19.361-15.064.211.027.42.064.639.064a5 5 0 005-5 5 5 0 00-5-5" fill="#44D860"/><path fill="#3ECC5F" d="M193 123h30v-20h-30z"/><path d="M233 115.5a2.5 2.5 0 100-5c-.109 0-.214.019-.319.032-.02-.075-.037-.15-.058-.225a2.501 2.501 0 00-.963-4.807c-.569 0-1.088.197-1.508.518a6.653 6.653 0 00-.168-.168c.314-.417.506-.931.506-1.494a2.5 2.5 0 00-4.8-.979A9.987 9.987 0 00223 103c-5.522 0-10 4.478-10 10s4.478 10 10 10c.934 0 1.833-.138 2.69-.377a2.5 2.5 0 004.8-.979c0-.563-.192-1.077-.506-1.494.057-.055.113-.111.168-.168.42.321.939.518 1.508.518a2.5 2.5 0 00.963-4.807c.021-.074.038-.15.058-.225.105.013.21.032.319.032" fill="#44D860"/><path d="M143 183h60c11.046 0 20-8.954 20-20V93h-60c-11.046 0-20 8.954-20 20v70z" fill="#FFFF50"/><path d="M208.02 124h-50.04a1 1 0 110-2h50.04a1 1 0 110 2m0 20h-50.04a1 1 0 110-2h50.04a1 1 0 110 2m0 20h-50.04a1 1 0 110-2h50.04a1 1 0 110 2m0-49.814h-50.04a1 1 0 110-2h50.04a1 1 0 110 2m0 19.814h-50.04a1 1 0 110-2h50.04a1 1 0 110 2m0 20h-50.04a1 1 0 110-2h50.04a1 1 0 110 2M223 61.611c-.012 0-.022-.006-.034-.005-3.09.105-4.552 3.196-5.842 5.923-1.346 2.85-2.387 4.703-4.093 4.647-1.889-.068-2.969-2.202-4.113-4.46-1.314-2.594-2.814-5.536-5.963-5.426-3.046.104-4.513 2.794-5.807 5.167-1.377 2.528-2.314 4.065-4.121 3.994-1.927-.07-2.951-1.805-4.136-3.813-1.321-2.236-2.848-4.75-5.936-4.664-2.994.103-4.465 2.385-5.763 4.4-1.373 2.13-2.335 3.428-4.165 3.351-1.973-.07-2.992-1.51-4.171-3.177-1.324-1.873-2.816-3.993-5.895-3.89-2.928.1-4.399 1.97-5.696 3.618-1.232 1.564-2.194 2.802-4.229 2.724a1 1 0 00-.072 2c3.017.101 4.545-1.8 5.872-3.487 1.177-1.496 2.193-2.787 4.193-2.855 1.926-.082 2.829 1.115 4.195 3.045 1.297 1.834 2.769 3.914 5.731 4.021 3.103.104 4.596-2.215 5.918-4.267 1.182-1.834 2.202-3.417 4.15-3.484 1.793-.067 2.769 1.35 4.145 3.681 1.297 2.197 2.766 4.686 5.787 4.796 3.125.108 4.634-2.62 5.949-5.035 1.139-2.088 2.214-4.06 4.119-4.126 1.793-.042 2.728 1.595 4.111 4.33 1.292 2.553 2.757 5.445 5.825 5.556l.169.003c3.064 0 4.518-3.075 5.805-5.794 1.139-2.41 2.217-4.68 4.067-4.773v-2z" fill="#000"/><path fill="#3ECC5F" d="M123 183h40v-40h-40z"/><path d="M224.758 116H202v68h-5v-68h-31v-4h58.256a4.502 4.502 0 018.744 1.5 4.5 4.5 0 01-8.242 2.5z" fill="#D8D8D8"/><path d="M183 158c-.219 0-.428.037-.639.064-.038-.15-.074-.301-.116-.451A5 5 0 00180.32 148a4.96 4.96 0 00-3.016 1.036 26.531 26.531 0 00-.335-.336 4.955 4.955 0 001.011-2.987 5 5 0 00-9.599-1.959c-.148-.042-.297-.077-.445-.115.027-.211.064-.42.064-.639a5 5 0 00-5-5 5 5 0 00-5 5c0 .219.037.428.064.639-.148.038-.297.073-.445.115a4.998 4.998 0 00-9.599 1.959c0 1.125.384 2.151 1.011 2.987-3.717 3.632-6.031 8.693-6.031 14.3 0 11.046 8.954 20 20 20 9.339 0 17.16-6.41 19.361-15.064.211.027.42.064.639.064a5 5 0 005-5 5 5 0 00-5-5" fill="#44D860"/><path fill="#3ECC5F" d="M123 123h40v-20h-40z"/><path d="M173 115.5a2.5 2.5 0 100-5c-.109 0-.214.019-.319.032-.02-.075-.037-.15-.058-.225a2.501 2.501 0 00-.963-4.807c-.569 0-1.088.197-1.508.518a6.653 6.653 0 00-.168-.168c.314-.417.506-.931.506-1.494a2.5 2.5 0 00-4.8-.979A9.987 9.987 0 00163 103c-5.522 0-10 4.478-10 10s4.478 10 10 10c.934 0 1.833-.138 2.69-.377a2.5 2.5 0 004.8-.979c0-.563-.192-1.077-.506-1.494.057-.055.113-.111.168-.168.42.321.939.518 1.508.518a2.5 2.5 0 00.963-4.807c.021-.074.038-.15.058-.225.105.013.21.032.319.032" fill="#44D860"/><path d="M183 41.75c-.16 0-.33-.02-.49-.05a2.52 2.52 0 01-.47-.14c-.15-.06-.29-.14-.431-.23-.13-.09-.259-.2-.38-.31-.109-.12-.219-.24-.309-.38s-.17-.28-.231-.43a2.619 2.619 0 01-.189-.96c0-.16.02-.33.05-.49.03-.16.08-.31.139-.47.061-.15.141-.29.231-.43.09-.13.2-.26.309-.38.121-.11.25-.22.38-.31.141-.09.281-.17.431-.23.149-.06.31-.11.47-.14.32-.07.65-.07.98 0 .159.03.32.08.47.14.149.06.29.14.43.23.13.09.259.2.38.31.11.12.22.25.31.38.09.14.17.28.23.43.06.16.11.31.14.47.029.16.05.33.05.49 0 .66-.271 1.31-.73 1.77-.121.11-.25.22-.38.31-.14.09-.281.17-.43.23a2.565 2.565 0 01-.96.19m20-1.25c-.66 0-1.3-.27-1.771-.73a3.802 3.802 0 01-.309-.38c-.09-.14-.17-.28-.231-.43a2.619 2.619 0 01-.189-.96c0-.66.27-1.3.729-1.77.121-.11.25-.22.38-.31.141-.09.281-.17.431-.23.149-.06.31-.11.47-.14.32-.07.66-.07.98 0 .159.03.32.08.47.14.149.06.29.14.43.23.13.09.259.2.38.31.459.47.73 1.11.73 1.77 0 .16-.021.33-.05.49-.03.16-.08.32-.14.47-.07.15-.14.29-.23.43-.09.13-.2.26-.31.38-.121.11-.25.22-.38.31-.14.09-.281.17-.43.23a2.565 2.565 0 01-.96.19" fill="#000"/><path d="M223 53V33c0-11.046-8.954-20-20-20H87.112c-16.524 0-29.937 13.362-30 29.885-.121 31.68-.075 47.581.139 47.705h165.75V53z" fill="#D0021B"/><path d="M95 32h127.968v47.825H75V52c0-11.046 8.954-20 20-20z" fill="#000"/><path d="M103 55.5a2.5 2.5 0 01-2.5-2.5c0-4.136-3.364-7.5-7.5-7.5s-7.5 3.364-7.5 7.5a2.5 2.5 0 11-5 0c0-6.893 5.607-12.5 12.5-12.5s12.5 5.607 12.5 12.5a2.5 2.5 0 01-2.5 2.5" fill="#9B9B9B" opacity=".546"/><path fill="#D8D8D8" opacity=".436" d="M212 35h8v19h-8z"/><path d="M201 17l5.335-.28c7.17-.378 13.288 5.13 13.665 12.299a13 13 0 01.018.683v.316h-8.05v-3.065c0-5.523-4.477-10-10-10a10 10 0 00-.908.042L201 17z" fill="#D8D8D8" opacity=".538"/><path fill="#D8D8D8" opacity=".436" d="M212 56h8v4h-8z"/><ellipse fill="#930012" transform="rotate(-20 93.5 28)" cx="93.5" cy="28" rx="3.5" ry="1"/><path d="M95.52 24.747c-1.287-4.802-6.005-7.709-10.54-6.494m3.54 10.494c-1.287-4.802-6.005-7.709-10.54-6.494" stroke="#6D000D" opacity=".62"/><path fill="#D8D8D8" d="M74 184h135v3H74z"/><circle fill="#000" cx="209.5" cy="186.5" r="6.5"/><circle fill="#000" cx="71.5" cy="186.5" r="6.5"/><circle fill="#4A4A4A" cx="209.5" cy="186.5" r="2.5"/><circle fill="#4A4A4A" cx="71.5" cy="186.5" r="2.5"/></g></svg> \ No newline at end of file +<svg width="250" height="200" xmlns="http://www.w3.org/2000/svg"><use href="#e" x="-20" opacity=".361"/><use href="#e" x="-40" opacity=".361"/><g id="e"><g fill="#3ECC5F"><path d="M63 163c-7.4 0-14-4-17.3-10a20 20 0 00-2.7 10c0 11 9 20 20 20h20v-20H63z"/><path d="M223 83H63c-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10-8 4-8 6 0 10 0 11 9 20 20 20h120c11 0 20-9 20-20V83z"/></g><path d="M223 53V33c0-11.046-8.954-20-20-20H87.112c-16.524 0-29.937 13.362-30 29.885-.121 31.68-.075 47.581.139 47.705h165.75V53z" fill="#D0021B"/></g><use href="#h" x="60"/><use href="#f" x="50"/><path d="M143 183h60c11 0 20-9 20-20V93h-60c-11 0-20 9-20 20v70z" fill="#FFFF50"/><g fill="none" stroke="#000" stroke-width="2" stroke-linecap="round"><path d="M103 53a1 1 0 10-20 0" stroke-width="5"/><path d="M223 62.6c-5 0-5 10-10 10.7-5 0-5-10-10-10s-5 9-10 9-5-8.5-10-8.5-5 8-10 8-5-7.25-10-7.25-5 6.5-10 6.5" stroke-linecap="butt"/><path d="M208 113h-50m50 10h-50m50 10h-50m50 10h-50m50 10h-50m50 10h-50"/></g><circle cx="183" cy="39.3" r="2.5"/><circle cx="203" cy="38" r="2.5"/><circle cx="153" cy="71" r="1"/><path d="M225 116h-23v68h-5v-68h-31v-4h58.256a4.502 4.502 0 018.744 1.5 4.5 4.5 0 01-8.242 2.5z" fill="#D8D8D8"/><g fill="#3ECC5F"><path d="M123 123h40v-20h-30zM123 183h40v-40h-30z"/></g><g id="h" fill="#44D860"><circle cx="163" cy="113" r="10"/><circle cx="168" cy="104.3" r="2.4"/><circle cx="171.7" cy="108" r="2.4"/><circle cx="173" cy="113" r="2.4"/><circle cx="171.7" cy="118" r="2.4"/><circle cx="168" cy="121.7" r="2.4"/></g><g id="f" fill="#44D860"><circle cx="163" cy="163" r="20"/><circle cx="153" cy="145.7" r="5"/><circle cx="163" cy="143" r="5"/><circle cx="173" cy="145.7" r="5"/><circle cx="180.3" cy="153" r="5"/><circle cx="183" cy="163" r="5"/></g><path d="M95 32h128.2v48H75V52c0-11 9-20 20-20z"/><path d="M103 53a1 1 0 10-20 0" stroke-width="2" fill="none" stroke="#9B9B9B" stroke-linecap="round" opacity=".546"/><g fill="#D8D8D8"><path opacity=".436" d="M212 35h8v19h-8z"/><path d="M201 17h5.33c7.2-.38 13.3 5.13 13.6 12a13 13 0 01.018.683v.3h-8v-3c0-5.5-4.5-10-10-10a10 10 0 00-.9.04z" opacity=".538"/><path opacity=".436" d="M212 56h8v4h-8z"/></g><ellipse fill="#930012" transform="rotate(-20 93.5 28)" cx="93.5" cy="28" rx="3.5" ry="1"/><path d="M95.52 24.747c-1.3-4.8-6-7.7-10.5-6.5m3.5 10.5c-1.3-4.8-6-7.7-10.5-6.5" fill="none" stroke="#6D000D" opacity=".6"/><path fill="#D8D8D8" d="M74 184h135v3H74z"/><g id="w"><circle cx="71.5" cy="186.5" r="6.5"/><circle fill="#4A4A4A" cx="71.5" cy="186.5" r="2.5"/></g><use href="#w" x="138"/></svg> \ No newline at end of file diff --git a/website/svgo.config.js b/website/svgo.config.js new file mode 100644 index 0000000000..be70fc07fc --- /dev/null +++ b/website/svgo.config.js @@ -0,0 +1,29 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const path = require('path'); + +module.exports = { + plugins: [ + { + name: 'preset-default', + params: { + overrides: { + removeTitle: false, + removeViewBox: false, + }, + }, + }, + { + name: 'prefixIds', + params: { + delim: '', + prefix: (_, info) => path.parse(info.path).name, + }, + }, + ], +}; diff --git a/website/versioned_docs/version-2.x/api/themes/theme-live-codeblock.mdx b/website/versioned_docs/version-2.x/api/themes/theme-live-codeblock.mdx index be6f4da721..ebdae744ea 100644 --- a/website/versioned_docs/version-2.x/api/themes/theme-live-codeblock.mdx +++ b/website/versioned_docs/version-2.x/api/themes/theme-live-codeblock.mdx @@ -5,7 +5,7 @@ slug: /api/themes/@docusaurus/theme-live-codeblock # 📦 theme-live-codeblock -This theme provides a `@theme/CodeBlock` component that is powered by react-live. You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. +This theme provides a `@theme/CodeBlock` component that is powered by [react-live](https://commerce.nearform.com/open-source/react-live/). You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. ```bash npm2yarn npm install --save @docusaurus/theme-live-codeblock diff --git a/website/versioned_docs/version-2.x/migration/migration-manual.mdx b/website/versioned_docs/version-2.x/migration/migration-manual.mdx index 7f8984eab3..904e261144 100644 --- a/website/versioned_docs/version-2.x/migration/migration-manual.mdx +++ b/website/versioned_docs/version-2.x/migration/migration-manual.mdx @@ -207,7 +207,7 @@ Infima uses 7 shades of each color. We recommend using [ColorBox](https://www.colorbox.io/) to find the different shades of colors for your chosen primary color. -Alteratively, use the following tool to generate the different shades for your website and copy the variables into `src/css/custom.css`. +Alternatively, use the following tool to generate the different shades for your website and copy the variables into `src/css/custom.css`. import ColorGenerator from '@site/src/components/ColorGenerator'; diff --git a/website/versioned_docs/version-3.0.1/api/themes/theme-live-codeblock.mdx b/website/versioned_docs/version-3.0.1/api/themes/theme-live-codeblock.mdx index dd9fa7e327..212c910b3e 100644 --- a/website/versioned_docs/version-3.0.1/api/themes/theme-live-codeblock.mdx +++ b/website/versioned_docs/version-3.0.1/api/themes/theme-live-codeblock.mdx @@ -5,7 +5,7 @@ slug: /api/themes/@docusaurus/theme-live-codeblock # 📦 theme-live-codeblock -This theme provides a `@theme/CodeBlock` component that is powered by react-live. You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. +This theme provides a `@theme/CodeBlock` component that is powered by [react-live](https://commerce.nearform.com/open-source/react-live/). You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. ```bash npm2yarn npm install --save @docusaurus/theme-live-codeblock diff --git a/website/versioned_docs/version-3.1.1/api/themes/theme-live-codeblock.mdx b/website/versioned_docs/version-3.1.1/api/themes/theme-live-codeblock.mdx index dd9fa7e327..212c910b3e 100644 --- a/website/versioned_docs/version-3.1.1/api/themes/theme-live-codeblock.mdx +++ b/website/versioned_docs/version-3.1.1/api/themes/theme-live-codeblock.mdx @@ -5,7 +5,7 @@ slug: /api/themes/@docusaurus/theme-live-codeblock # 📦 theme-live-codeblock -This theme provides a `@theme/CodeBlock` component that is powered by react-live. You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. +This theme provides a `@theme/CodeBlock` component that is powered by [react-live](https://commerce.nearform.com/open-source/react-live/). You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. ```bash npm2yarn npm install --save @docusaurus/theme-live-codeblock diff --git a/website/versioned_docs/version-3.2.1/api/themes/theme-live-codeblock.mdx b/website/versioned_docs/version-3.2.1/api/themes/theme-live-codeblock.mdx index dd9fa7e327..212c910b3e 100644 --- a/website/versioned_docs/version-3.2.1/api/themes/theme-live-codeblock.mdx +++ b/website/versioned_docs/version-3.2.1/api/themes/theme-live-codeblock.mdx @@ -5,7 +5,7 @@ slug: /api/themes/@docusaurus/theme-live-codeblock # 📦 theme-live-codeblock -This theme provides a `@theme/CodeBlock` component that is powered by react-live. You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. +This theme provides a `@theme/CodeBlock` component that is powered by [react-live](https://commerce.nearform.com/open-source/react-live/). You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. ```bash npm2yarn npm install --save @docusaurus/theme-live-codeblock diff --git a/website/versioned_docs/version-3.3.2/api/themes/theme-live-codeblock.mdx b/website/versioned_docs/version-3.3.2/api/themes/theme-live-codeblock.mdx index dd9fa7e327..212c910b3e 100644 --- a/website/versioned_docs/version-3.3.2/api/themes/theme-live-codeblock.mdx +++ b/website/versioned_docs/version-3.3.2/api/themes/theme-live-codeblock.mdx @@ -5,7 +5,7 @@ slug: /api/themes/@docusaurus/theme-live-codeblock # 📦 theme-live-codeblock -This theme provides a `@theme/CodeBlock` component that is powered by react-live. You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. +This theme provides a `@theme/CodeBlock` component that is powered by [react-live](https://commerce.nearform.com/open-source/react-live/). You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. ```bash npm2yarn npm install --save @docusaurus/theme-live-codeblock diff --git a/website/versioned_docs/version-3.4.0/api/themes/theme-live-codeblock.mdx b/website/versioned_docs/version-3.4.0/api/themes/theme-live-codeblock.mdx index dd9fa7e327..212c910b3e 100644 --- a/website/versioned_docs/version-3.4.0/api/themes/theme-live-codeblock.mdx +++ b/website/versioned_docs/version-3.4.0/api/themes/theme-live-codeblock.mdx @@ -5,7 +5,7 @@ slug: /api/themes/@docusaurus/theme-live-codeblock # 📦 theme-live-codeblock -This theme provides a `@theme/CodeBlock` component that is powered by react-live. You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. +This theme provides a `@theme/CodeBlock` component that is powered by [react-live](https://commerce.nearform.com/open-source/react-live/). You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. ```bash npm2yarn npm install --save @docusaurus/theme-live-codeblock diff --git a/website/versioned_docs/version-3.5.2/api/themes/theme-live-codeblock.mdx b/website/versioned_docs/version-3.5.2/api/themes/theme-live-codeblock.mdx index dd9fa7e327..212c910b3e 100644 --- a/website/versioned_docs/version-3.5.2/api/themes/theme-live-codeblock.mdx +++ b/website/versioned_docs/version-3.5.2/api/themes/theme-live-codeblock.mdx @@ -5,7 +5,7 @@ slug: /api/themes/@docusaurus/theme-live-codeblock # 📦 theme-live-codeblock -This theme provides a `@theme/CodeBlock` component that is powered by react-live. You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. +This theme provides a `@theme/CodeBlock` component that is powered by [react-live](https://commerce.nearform.com/open-source/react-live/). You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. ```bash npm2yarn npm install --save @docusaurus/theme-live-codeblock diff --git a/website/versioned_docs/version-3.6.2/advanced/architecture.mdx b/website/versioned_docs/version-3.6.3/advanced/architecture.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/advanced/architecture.mdx rename to website/versioned_docs/version-3.6.3/advanced/architecture.mdx diff --git a/website/versioned_docs/version-3.6.2/advanced/client.mdx b/website/versioned_docs/version-3.6.3/advanced/client.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/advanced/client.mdx rename to website/versioned_docs/version-3.6.3/advanced/client.mdx diff --git a/website/versioned_docs/version-3.6.2/advanced/index.mdx b/website/versioned_docs/version-3.6.3/advanced/index.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/advanced/index.mdx rename to website/versioned_docs/version-3.6.3/advanced/index.mdx diff --git a/website/versioned_docs/version-3.6.2/advanced/plugins.mdx b/website/versioned_docs/version-3.6.3/advanced/plugins.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/advanced/plugins.mdx rename to website/versioned_docs/version-3.6.3/advanced/plugins.mdx diff --git a/website/versioned_docs/version-3.6.2/advanced/routing.mdx b/website/versioned_docs/version-3.6.3/advanced/routing.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/advanced/routing.mdx rename to website/versioned_docs/version-3.6.3/advanced/routing.mdx diff --git a/website/versioned_docs/version-3.6.2/advanced/ssg.mdx b/website/versioned_docs/version-3.6.3/advanced/ssg.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/advanced/ssg.mdx rename to website/versioned_docs/version-3.6.3/advanced/ssg.mdx diff --git a/website/versioned_docs/version-3.6.2/api/docusaurus.config.js.mdx b/website/versioned_docs/version-3.6.3/api/docusaurus.config.js.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/docusaurus.config.js.mdx rename to website/versioned_docs/version-3.6.3/api/docusaurus.config.js.mdx diff --git a/website/versioned_docs/version-3.6.2/api/misc/_category_.yml b/website/versioned_docs/version-3.6.3/api/misc/_category_.yml similarity index 100% rename from website/versioned_docs/version-3.6.2/api/misc/_category_.yml rename to website/versioned_docs/version-3.6.3/api/misc/_category_.yml diff --git a/website/versioned_docs/version-3.6.2/api/misc/create-docusaurus.mdx b/website/versioned_docs/version-3.6.3/api/misc/create-docusaurus.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/misc/create-docusaurus.mdx rename to website/versioned_docs/version-3.6.3/api/misc/create-docusaurus.mdx diff --git a/website/versioned_docs/version-3.6.2/api/misc/eslint-plugin/README.mdx b/website/versioned_docs/version-3.6.3/api/misc/eslint-plugin/README.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/misc/eslint-plugin/README.mdx rename to website/versioned_docs/version-3.6.3/api/misc/eslint-plugin/README.mdx diff --git a/website/versioned_docs/version-3.6.2/api/misc/eslint-plugin/no-html-links.mdx b/website/versioned_docs/version-3.6.3/api/misc/eslint-plugin/no-html-links.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/misc/eslint-plugin/no-html-links.mdx rename to website/versioned_docs/version-3.6.3/api/misc/eslint-plugin/no-html-links.mdx diff --git a/website/versioned_docs/version-3.6.2/api/misc/eslint-plugin/no-untranslated-text.mdx b/website/versioned_docs/version-3.6.3/api/misc/eslint-plugin/no-untranslated-text.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/misc/eslint-plugin/no-untranslated-text.mdx rename to website/versioned_docs/version-3.6.3/api/misc/eslint-plugin/no-untranslated-text.mdx diff --git a/website/versioned_docs/version-3.6.2/api/misc/eslint-plugin/prefer-docusaurus-heading.mdx b/website/versioned_docs/version-3.6.3/api/misc/eslint-plugin/prefer-docusaurus-heading.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/misc/eslint-plugin/prefer-docusaurus-heading.mdx rename to website/versioned_docs/version-3.6.3/api/misc/eslint-plugin/prefer-docusaurus-heading.mdx diff --git a/website/versioned_docs/version-3.6.2/api/misc/eslint-plugin/string-literal-i18n-messages.mdx b/website/versioned_docs/version-3.6.3/api/misc/eslint-plugin/string-literal-i18n-messages.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/misc/eslint-plugin/string-literal-i18n-messages.mdx rename to website/versioned_docs/version-3.6.3/api/misc/eslint-plugin/string-literal-i18n-messages.mdx diff --git a/website/versioned_docs/version-3.6.2/api/misc/logger/demo.png b/website/versioned_docs/version-3.6.3/api/misc/logger/demo.png similarity index 100% rename from website/versioned_docs/version-3.6.2/api/misc/logger/demo.png rename to website/versioned_docs/version-3.6.3/api/misc/logger/demo.png diff --git a/website/versioned_docs/version-3.6.2/api/misc/logger/logger.mdx b/website/versioned_docs/version-3.6.3/api/misc/logger/logger.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/misc/logger/logger.mdx rename to website/versioned_docs/version-3.6.3/api/misc/logger/logger.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugin-methods/README.mdx b/website/versioned_docs/version-3.6.3/api/plugin-methods/README.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugin-methods/README.mdx rename to website/versioned_docs/version-3.6.3/api/plugin-methods/README.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugin-methods/_category_.yml b/website/versioned_docs/version-3.6.3/api/plugin-methods/_category_.yml similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugin-methods/_category_.yml rename to website/versioned_docs/version-3.6.3/api/plugin-methods/_category_.yml diff --git a/website/versioned_docs/version-3.6.2/api/plugin-methods/extend-infrastructure.mdx b/website/versioned_docs/version-3.6.3/api/plugin-methods/extend-infrastructure.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugin-methods/extend-infrastructure.mdx rename to website/versioned_docs/version-3.6.3/api/plugin-methods/extend-infrastructure.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugin-methods/i18n-lifecycles.mdx b/website/versioned_docs/version-3.6.3/api/plugin-methods/i18n-lifecycles.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugin-methods/i18n-lifecycles.mdx rename to website/versioned_docs/version-3.6.3/api/plugin-methods/i18n-lifecycles.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugin-methods/lifecycle-apis.mdx b/website/versioned_docs/version-3.6.3/api/plugin-methods/lifecycle-apis.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugin-methods/lifecycle-apis.mdx rename to website/versioned_docs/version-3.6.3/api/plugin-methods/lifecycle-apis.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugin-methods/static-methods.mdx b/website/versioned_docs/version-3.6.3/api/plugin-methods/static-methods.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugin-methods/static-methods.mdx rename to website/versioned_docs/version-3.6.3/api/plugin-methods/static-methods.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugins/_category_.yml b/website/versioned_docs/version-3.6.3/api/plugins/_category_.yml similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugins/_category_.yml rename to website/versioned_docs/version-3.6.3/api/plugins/_category_.yml diff --git a/website/versioned_docs/version-3.6.2/api/plugins/_partial-tags-file-api-ref-section.mdx b/website/versioned_docs/version-3.6.3/api/plugins/_partial-tags-file-api-ref-section.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugins/_partial-tags-file-api-ref-section.mdx rename to website/versioned_docs/version-3.6.3/api/plugins/_partial-tags-file-api-ref-section.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugins/overview.mdx b/website/versioned_docs/version-3.6.3/api/plugins/overview.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugins/overview.mdx rename to website/versioned_docs/version-3.6.3/api/plugins/overview.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugins/plugin-client-redirects.mdx b/website/versioned_docs/version-3.6.3/api/plugins/plugin-client-redirects.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugins/plugin-client-redirects.mdx rename to website/versioned_docs/version-3.6.3/api/plugins/plugin-client-redirects.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugins/plugin-content-blog.mdx b/website/versioned_docs/version-3.6.3/api/plugins/plugin-content-blog.mdx similarity index 98% rename from website/versioned_docs/version-3.6.2/api/plugins/plugin-content-blog.mdx rename to website/versioned_docs/version-3.6.3/api/plugins/plugin-content-blog.mdx index 64da72ee3c..4307cd4069 100644 --- a/website/versioned_docs/version-3.6.2/api/plugins/plugin-content-blog.mdx +++ b/website/versioned_docs/version-3.6.3/api/plugins/plugin-content-blog.mdx @@ -250,6 +250,7 @@ Accepted fields: | `author_image_url` | `string` | `undefined` | ⚠️ Prefer using `authors`. The URL to the author's thumbnail image. | | `author_title` | `string` | `undefined` | ⚠️ Prefer using `authors`. A description of the author. | | `title` | `string` | Markdown title | The blog post title. | +| `title_meta` | `string` | `frontMatter.title` | The blog post SEO metadata title, used in `<head>` for `<title>` and `og:title`. Permits to override `title` when the displayed title and SEO title should be different. | | `date` | `string` | File name or file creation time | The blog post creation date. If not specified, this can be extracted from the file or folder name, e.g, `2021-04-15-blog-post.mdx`, `2021-04-15-blog-post/index.mdx`, `2021/04/15/blog-post.mdx`. Otherwise, it is the Markdown file creation time. | | `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your post. Strings can be a reference to keys of a [tags file](#tags-file) (usually `tags.yml`) | | `draft` | `boolean` | `false` | Draft blog posts will only be available during development. | diff --git a/website/versioned_docs/version-3.6.2/api/plugins/plugin-content-docs.mdx b/website/versioned_docs/version-3.6.3/api/plugins/plugin-content-docs.mdx similarity index 98% rename from website/versioned_docs/version-3.6.2/api/plugins/plugin-content-docs.mdx rename to website/versioned_docs/version-3.6.3/api/plugins/plugin-content-docs.mdx index b14df36827..fa9ddbf53e 100644 --- a/website/versioned_docs/version-3.6.2/api/plugins/plugin-content-docs.mdx +++ b/website/versioned_docs/version-3.6.3/api/plugins/plugin-content-docs.mdx @@ -278,7 +278,6 @@ Accepted fields: | --- | --- | --- | --- | | `id` | `string` | file path (including folders, without the extension) | A unique document ID. | | `title` | `string` | Markdown title or `id` | The text title of your document. Used for the page metadata and as a fallback value in multiple places (sidebar, next/previous buttons...). Automatically added at the top of your doc if it does not contain any Markdown title. | -| `title_meta` | `string` | `frontMatter.title` | The SEO metadata title of your document used in `<head>` for `<title>` and `og:title`. Permits to override `frontMatter.title` when the displayed title and SEO title should be different. | | `pagination_label` | `string` | `sidebar_label` or `title` | The text used in the document next/previous buttons for this document. | | `sidebar_label` | `string` | `title` | The text shown in the document sidebar for this document. | | `sidebar_position` | `number` | Default ordering | Controls the position of a doc inside the generated sidebar slice when using `autogenerated` sidebar items. See also [Autogenerated sidebar metadata](/docs/sidebar/autogenerated#autogenerated-sidebar-metadata). | diff --git a/website/versioned_docs/version-3.6.2/api/plugins/plugin-content-pages.mdx b/website/versioned_docs/version-3.6.3/api/plugins/plugin-content-pages.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugins/plugin-content-pages.mdx rename to website/versioned_docs/version-3.6.3/api/plugins/plugin-content-pages.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugins/plugin-debug.mdx b/website/versioned_docs/version-3.6.3/api/plugins/plugin-debug.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugins/plugin-debug.mdx rename to website/versioned_docs/version-3.6.3/api/plugins/plugin-debug.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugins/plugin-google-analytics.mdx b/website/versioned_docs/version-3.6.3/api/plugins/plugin-google-analytics.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugins/plugin-google-analytics.mdx rename to website/versioned_docs/version-3.6.3/api/plugins/plugin-google-analytics.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugins/plugin-google-gtag.mdx b/website/versioned_docs/version-3.6.3/api/plugins/plugin-google-gtag.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugins/plugin-google-gtag.mdx rename to website/versioned_docs/version-3.6.3/api/plugins/plugin-google-gtag.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugins/plugin-google-tag-manager.mdx b/website/versioned_docs/version-3.6.3/api/plugins/plugin-google-tag-manager.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugins/plugin-google-tag-manager.mdx rename to website/versioned_docs/version-3.6.3/api/plugins/plugin-google-tag-manager.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugins/plugin-ideal-image.mdx b/website/versioned_docs/version-3.6.3/api/plugins/plugin-ideal-image.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugins/plugin-ideal-image.mdx rename to website/versioned_docs/version-3.6.3/api/plugins/plugin-ideal-image.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugins/plugin-pwa.mdx b/website/versioned_docs/version-3.6.3/api/plugins/plugin-pwa.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugins/plugin-pwa.mdx rename to website/versioned_docs/version-3.6.3/api/plugins/plugin-pwa.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugins/plugin-rsdoctor.mdx b/website/versioned_docs/version-3.6.3/api/plugins/plugin-rsdoctor.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugins/plugin-rsdoctor.mdx rename to website/versioned_docs/version-3.6.3/api/plugins/plugin-rsdoctor.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugins/plugin-sitemap.mdx b/website/versioned_docs/version-3.6.3/api/plugins/plugin-sitemap.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugins/plugin-sitemap.mdx rename to website/versioned_docs/version-3.6.3/api/plugins/plugin-sitemap.mdx diff --git a/website/versioned_docs/version-3.6.2/api/plugins/plugin-vercel-analytics.mdx b/website/versioned_docs/version-3.6.3/api/plugins/plugin-vercel-analytics.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/plugins/plugin-vercel-analytics.mdx rename to website/versioned_docs/version-3.6.3/api/plugins/plugin-vercel-analytics.mdx diff --git a/website/versioned_docs/version-3.6.2/api/themes/_category_.yml b/website/versioned_docs/version-3.6.3/api/themes/_category_.yml similarity index 100% rename from website/versioned_docs/version-3.6.2/api/themes/_category_.yml rename to website/versioned_docs/version-3.6.3/api/themes/_category_.yml diff --git a/website/versioned_docs/version-3.6.2/api/themes/overview.mdx b/website/versioned_docs/version-3.6.3/api/themes/overview.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/themes/overview.mdx rename to website/versioned_docs/version-3.6.3/api/themes/overview.mdx diff --git a/website/versioned_docs/version-3.6.2/api/themes/theme-classic.mdx b/website/versioned_docs/version-3.6.3/api/themes/theme-classic.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/themes/theme-classic.mdx rename to website/versioned_docs/version-3.6.3/api/themes/theme-classic.mdx diff --git a/website/versioned_docs/version-3.6.2/api/themes/theme-configuration.mdx b/website/versioned_docs/version-3.6.3/api/themes/theme-configuration.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/themes/theme-configuration.mdx rename to website/versioned_docs/version-3.6.3/api/themes/theme-configuration.mdx diff --git a/website/versioned_docs/version-3.6.2/api/themes/theme-live-codeblock.mdx b/website/versioned_docs/version-3.6.3/api/themes/theme-live-codeblock.mdx similarity index 72% rename from website/versioned_docs/version-3.6.2/api/themes/theme-live-codeblock.mdx rename to website/versioned_docs/version-3.6.3/api/themes/theme-live-codeblock.mdx index dd9fa7e327..212c910b3e 100644 --- a/website/versioned_docs/version-3.6.2/api/themes/theme-live-codeblock.mdx +++ b/website/versioned_docs/version-3.6.3/api/themes/theme-live-codeblock.mdx @@ -5,7 +5,7 @@ slug: /api/themes/@docusaurus/theme-live-codeblock # 📦 theme-live-codeblock -This theme provides a `@theme/CodeBlock` component that is powered by react-live. You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. +This theme provides a `@theme/CodeBlock` component that is powered by [react-live](https://commerce.nearform.com/open-source/react-live/). You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. ```bash npm2yarn npm install --save @docusaurus/theme-live-codeblock diff --git a/website/versioned_docs/version-3.6.2/api/themes/theme-mermaid.mdx b/website/versioned_docs/version-3.6.3/api/themes/theme-mermaid.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/themes/theme-mermaid.mdx rename to website/versioned_docs/version-3.6.3/api/themes/theme-mermaid.mdx diff --git a/website/versioned_docs/version-3.6.2/api/themes/theme-search-algolia.mdx b/website/versioned_docs/version-3.6.3/api/themes/theme-search-algolia.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/api/themes/theme-search-algolia.mdx rename to website/versioned_docs/version-3.6.3/api/themes/theme-search-algolia.mdx diff --git a/website/versioned_docs/version-3.6.2/assets/docusaurus-asset-example-banner.png b/website/versioned_docs/version-3.6.3/assets/docusaurus-asset-example-banner.png similarity index 100% rename from website/versioned_docs/version-3.6.2/assets/docusaurus-asset-example-banner.png rename to website/versioned_docs/version-3.6.3/assets/docusaurus-asset-example-banner.png diff --git a/website/versioned_docs/version-3.6.2/assets/docusaurus-asset-example.docx b/website/versioned_docs/version-3.6.3/assets/docusaurus-asset-example.docx similarity index 100% rename from website/versioned_docs/version-3.6.2/assets/docusaurus-asset-example.docx rename to website/versioned_docs/version-3.6.3/assets/docusaurus-asset-example.docx diff --git a/website/versioned_docs/version-3.6.2/assets/docusaurus-asset-example.xyz b/website/versioned_docs/version-3.6.3/assets/docusaurus-asset-example.xyz similarity index 100% rename from website/versioned_docs/version-3.6.2/assets/docusaurus-asset-example.xyz rename to website/versioned_docs/version-3.6.3/assets/docusaurus-asset-example.xyz diff --git a/website/versioned_docs/version-3.6.2/blog.mdx b/website/versioned_docs/version-3.6.3/blog.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/blog.mdx rename to website/versioned_docs/version-3.6.3/blog.mdx diff --git a/website/versioned_docs/version-3.6.2/browser-support.mdx b/website/versioned_docs/version-3.6.3/browser-support.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/browser-support.mdx rename to website/versioned_docs/version-3.6.3/browser-support.mdx diff --git a/website/versioned_docs/version-3.6.2/cli.mdx b/website/versioned_docs/version-3.6.3/cli.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/cli.mdx rename to website/versioned_docs/version-3.6.3/cli.mdx diff --git a/website/versioned_docs/version-3.6.2/configuration.mdx b/website/versioned_docs/version-3.6.3/configuration.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/configuration.mdx rename to website/versioned_docs/version-3.6.3/configuration.mdx diff --git a/website/versioned_docs/version-3.6.2/deployment.mdx b/website/versioned_docs/version-3.6.3/deployment.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/deployment.mdx rename to website/versioned_docs/version-3.6.3/deployment.mdx diff --git a/website/versioned_docs/version-3.6.2/docusaurus-core.mdx b/website/versioned_docs/version-3.6.3/docusaurus-core.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/docusaurus-core.mdx rename to website/versioned_docs/version-3.6.3/docusaurus-core.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/creating-pages.mdx b/website/versioned_docs/version-3.6.3/guides/creating-pages.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/creating-pages.mdx rename to website/versioned_docs/version-3.6.3/guides/creating-pages.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/docs/docs-create-doc.mdx b/website/versioned_docs/version-3.6.3/guides/docs/docs-create-doc.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/docs/docs-create-doc.mdx rename to website/versioned_docs/version-3.6.3/guides/docs/docs-create-doc.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/docs/docs-introduction.mdx b/website/versioned_docs/version-3.6.3/guides/docs/docs-introduction.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/docs/docs-introduction.mdx rename to website/versioned_docs/version-3.6.3/guides/docs/docs-introduction.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/docs/docs-multi-instance.mdx b/website/versioned_docs/version-3.6.3/guides/docs/docs-multi-instance.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/docs/docs-multi-instance.mdx rename to website/versioned_docs/version-3.6.3/guides/docs/docs-multi-instance.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/docs/sidebar/autogenerated.mdx b/website/versioned_docs/version-3.6.3/guides/docs/sidebar/autogenerated.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/docs/sidebar/autogenerated.mdx rename to website/versioned_docs/version-3.6.3/guides/docs/sidebar/autogenerated.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/docs/sidebar/index.mdx b/website/versioned_docs/version-3.6.3/guides/docs/sidebar/index.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/docs/sidebar/index.mdx rename to website/versioned_docs/version-3.6.3/guides/docs/sidebar/index.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/docs/sidebar/items.mdx b/website/versioned_docs/version-3.6.3/guides/docs/sidebar/items.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/docs/sidebar/items.mdx rename to website/versioned_docs/version-3.6.3/guides/docs/sidebar/items.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/docs/sidebar/multiple-sidebars.mdx b/website/versioned_docs/version-3.6.3/guides/docs/sidebar/multiple-sidebars.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/docs/sidebar/multiple-sidebars.mdx rename to website/versioned_docs/version-3.6.3/guides/docs/sidebar/multiple-sidebars.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/docs/versioning.mdx b/website/versioned_docs/version-3.6.3/guides/docs/versioning.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/docs/versioning.mdx rename to website/versioned_docs/version-3.6.3/guides/docs/versioning.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/markdown-features/_markdown-partial-example.mdx b/website/versioned_docs/version-3.6.3/guides/markdown-features/_markdown-partial-example.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/markdown-features/_markdown-partial-example.mdx rename to website/versioned_docs/version-3.6.3/guides/markdown-features/_markdown-partial-example.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-admonitions.mdx b/website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-admonitions.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-admonitions.mdx rename to website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-admonitions.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-assets.mdx b/website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-assets.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-assets.mdx rename to website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-assets.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-code-blocks.mdx b/website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-code-blocks.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-code-blocks.mdx rename to website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-code-blocks.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-diagrams.mdx b/website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-diagrams.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-diagrams.mdx rename to website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-diagrams.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-head-metadata.mdx b/website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-head-metadata.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-head-metadata.mdx rename to website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-head-metadata.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-intro.mdx b/website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-intro.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-intro.mdx rename to website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-intro.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-links.mdx b/website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-links.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-links.mdx rename to website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-links.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-math-equations.mdx b/website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-math-equations.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-math-equations.mdx rename to website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-math-equations.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-plugins.mdx b/website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-plugins.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-plugins.mdx rename to website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-plugins.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-react.mdx b/website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-react.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-react.mdx rename to website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-react.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-react.module.css b/website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-react.module.css similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-react.module.css rename to website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-react.module.css diff --git a/website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-tabs-styles.module.css b/website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-tabs-styles.module.css similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-tabs-styles.module.css rename to website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-tabs-styles.module.css diff --git a/website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-tabs.mdx b/website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-tabs.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-tabs.mdx rename to website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-tabs.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-toc.mdx b/website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-toc.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/markdown-features/markdown-features-toc.mdx rename to website/versioned_docs/version-3.6.3/guides/markdown-features/markdown-features-toc.mdx diff --git a/website/versioned_docs/version-3.6.2/guides/whats-next.mdx b/website/versioned_docs/version-3.6.3/guides/whats-next.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/guides/whats-next.mdx rename to website/versioned_docs/version-3.6.3/guides/whats-next.mdx diff --git a/website/versioned_docs/version-3.6.2/i18n/i18n-crowdin.mdx b/website/versioned_docs/version-3.6.3/i18n/i18n-crowdin.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/i18n/i18n-crowdin.mdx rename to website/versioned_docs/version-3.6.3/i18n/i18n-crowdin.mdx diff --git a/website/versioned_docs/version-3.6.2/i18n/i18n-git.mdx b/website/versioned_docs/version-3.6.3/i18n/i18n-git.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/i18n/i18n-git.mdx rename to website/versioned_docs/version-3.6.3/i18n/i18n-git.mdx diff --git a/website/versioned_docs/version-3.6.2/i18n/i18n-introduction.mdx b/website/versioned_docs/version-3.6.3/i18n/i18n-introduction.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/i18n/i18n-introduction.mdx rename to website/versioned_docs/version-3.6.3/i18n/i18n-introduction.mdx diff --git a/website/versioned_docs/version-3.6.2/i18n/i18n-tutorial.mdx b/website/versioned_docs/version-3.6.3/i18n/i18n-tutorial.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/i18n/i18n-tutorial.mdx rename to website/versioned_docs/version-3.6.3/i18n/i18n-tutorial.mdx diff --git a/website/versioned_docs/version-3.6.2/installation.mdx b/website/versioned_docs/version-3.6.3/installation.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/installation.mdx rename to website/versioned_docs/version-3.6.3/installation.mdx diff --git a/website/versioned_docs/version-3.6.2/introduction.mdx b/website/versioned_docs/version-3.6.3/introduction.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/introduction.mdx rename to website/versioned_docs/version-3.6.3/introduction.mdx diff --git a/website/versioned_docs/version-3.6.2/migration/index.mdx b/website/versioned_docs/version-3.6.3/migration/index.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/migration/index.mdx rename to website/versioned_docs/version-3.6.3/migration/index.mdx diff --git a/website/versioned_docs/version-3.6.2/migration/v2/migration-automated.mdx b/website/versioned_docs/version-3.6.3/migration/v2/migration-automated.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/migration/v2/migration-automated.mdx rename to website/versioned_docs/version-3.6.3/migration/v2/migration-automated.mdx diff --git a/website/versioned_docs/version-3.6.2/migration/v2/migration-manual.mdx b/website/versioned_docs/version-3.6.3/migration/v2/migration-manual.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/migration/v2/migration-manual.mdx rename to website/versioned_docs/version-3.6.3/migration/v2/migration-manual.mdx diff --git a/website/versioned_docs/version-3.6.2/migration/v2/migration-overview.mdx b/website/versioned_docs/version-3.6.3/migration/v2/migration-overview.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/migration/v2/migration-overview.mdx rename to website/versioned_docs/version-3.6.3/migration/v2/migration-overview.mdx diff --git a/website/versioned_docs/version-3.6.2/migration/v2/migration-translated-sites.mdx b/website/versioned_docs/version-3.6.3/migration/v2/migration-translated-sites.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/migration/v2/migration-translated-sites.mdx rename to website/versioned_docs/version-3.6.3/migration/v2/migration-translated-sites.mdx diff --git a/website/versioned_docs/version-3.6.2/migration/v2/migration-versioned-sites.mdx b/website/versioned_docs/version-3.6.3/migration/v2/migration-versioned-sites.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/migration/v2/migration-versioned-sites.mdx rename to website/versioned_docs/version-3.6.3/migration/v2/migration-versioned-sites.mdx diff --git a/website/versioned_docs/version-3.6.2/migration/v3.mdx b/website/versioned_docs/version-3.6.3/migration/v3.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/migration/v3.mdx rename to website/versioned_docs/version-3.6.3/migration/v3.mdx diff --git a/website/versioned_docs/version-3.6.2/playground.mdx b/website/versioned_docs/version-3.6.3/playground.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/playground.mdx rename to website/versioned_docs/version-3.6.3/playground.mdx diff --git a/website/versioned_docs/version-3.6.2/search.mdx b/website/versioned_docs/version-3.6.3/search.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/search.mdx rename to website/versioned_docs/version-3.6.3/search.mdx diff --git a/website/versioned_docs/version-3.6.2/seo.mdx b/website/versioned_docs/version-3.6.3/seo.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/seo.mdx rename to website/versioned_docs/version-3.6.3/seo.mdx diff --git a/website/versioned_docs/version-3.6.2/static-assets.mdx b/website/versioned_docs/version-3.6.3/static-assets.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/static-assets.mdx rename to website/versioned_docs/version-3.6.3/static-assets.mdx diff --git a/website/versioned_docs/version-3.6.2/styling-layout.mdx b/website/versioned_docs/version-3.6.3/styling-layout.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/styling-layout.mdx rename to website/versioned_docs/version-3.6.3/styling-layout.mdx diff --git a/website/versioned_docs/version-3.6.2/swizzling.mdx b/website/versioned_docs/version-3.6.3/swizzling.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/swizzling.mdx rename to website/versioned_docs/version-3.6.3/swizzling.mdx diff --git a/website/versioned_docs/version-3.6.2/typescript-support.mdx b/website/versioned_docs/version-3.6.3/typescript-support.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/typescript-support.mdx rename to website/versioned_docs/version-3.6.3/typescript-support.mdx diff --git a/website/versioned_docs/version-3.6.2/using-plugins.mdx b/website/versioned_docs/version-3.6.3/using-plugins.mdx similarity index 100% rename from website/versioned_docs/version-3.6.2/using-plugins.mdx rename to website/versioned_docs/version-3.6.3/using-plugins.mdx diff --git a/website/versioned_docs/version-3.7.0/advanced/architecture.mdx b/website/versioned_docs/version-3.7.0/advanced/architecture.mdx new file mode 100644 index 0000000000..8d1f8bdb2d --- /dev/null +++ b/website/versioned_docs/version-3.7.0/advanced/architecture.mdx @@ -0,0 +1,28 @@ +--- +description: How Docusaurus works to build your app +--- + +# Architecture + +```mdx-code-block +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import Zoom from 'react-medium-image-zoom'; +``` + +<Zoom> + +![Architecture overview](/img/architecture.png) + +</Zoom> + +This diagram shows how Docusaurus works to build your app. Plugins each collect their content and emit JSON data; themes provide layout components which receive the JSON data as route modules. The bundler bundles all the components and emits a server bundle and a client bundle. + +Although you (either plugin authors or site creators) are writing JavaScript all the time, bear in mind that the JS is actually run in different environments: + +- All plugin lifecycle methods are run in Node. Therefore, until we support ES Modules in our codebase, plugin source code must be provided as ES modules that can be imported, or CommonJS that can be `require`'d. +- The theme code is built with Webpack. They can be provided as ESM—following React conventions. + +Plugin code and theme code never directly import each other: they only communicate through protocols (in our case, through JSON temp files and calls to `addRoute`). A useful mental model is to imagine that the plugins are not written in JavaScript, but in another language like Rust. The only way to interact with plugins for the user is through `docusaurus.config.js`, which itself is run in Node (hence you can use `require` and pass callbacks as plugin options). + +During bundling, the config file itself is serialized and bundled, allowing the theme to access config options like `themeConfig` or `baseUrl` through [`useDocusaurusContext()`](../docusaurus-core.mdx#useDocusaurusContext). However, the `siteConfig` object only contains **serializable values** (values that are preserved after `JSON.stringify()`). Functions, regexes, etc. would be lost on the client side. The `themeConfig` is designed to be entirely serializable. diff --git a/website/versioned_docs/version-3.7.0/advanced/client.mdx b/website/versioned_docs/version-3.7.0/advanced/client.mdx new file mode 100644 index 0000000000..f4d37d296d --- /dev/null +++ b/website/versioned_docs/version-3.7.0/advanced/client.mdx @@ -0,0 +1,184 @@ +--- +description: How the Docusaurus client is structured +--- + +# Client architecture + +## Theme aliases {#theme-aliases} + +A theme works by exporting a set of components, e.g. `Navbar`, `Layout`, `Footer`, to render the data passed down from plugins. Docusaurus and users use these components by importing them using the `@theme` webpack alias: + +```js +import Navbar from '@theme/Navbar'; +``` + +The alias `@theme` can refer to a few directories, in the following priority: + +1. A user's `website/src/theme` directory, which is a special directory that has the higher precedence. +2. A Docusaurus theme package's `theme` directory. +3. Fallback components provided by Docusaurus core (usually not needed). + +This is called a _layered architecture_: a higher-priority layer providing the component would shadow a lower-priority layer, making swizzling possible. Given the following structure: + +``` +website +├── node_modules +│ └── @docusaurus/theme-classic +│ └── theme +│ └── Navbar.js +└── src + └── theme + └── Navbar.js +``` + +`website/src/theme/Navbar.js` takes precedence whenever `@theme/Navbar` is imported. This behavior is called component swizzling. If you are familiar with Objective C where a function's implementation can be swapped during runtime, it's the exact same concept here with changing the target `@theme/Navbar` is pointing to! + +We already talked about how the "userland theme" in `src/theme` can re-use a theme component through the [`@theme-original`](../swizzling.mdx#wrapping) alias. One theme package can also wrap a component from another theme, by importing the component from the initial theme, using the `@theme-init` import. + +Here's an example of using this feature to enhance the default theme `CodeBlock` component with a `react-live` playground feature. + +```js +import InitialCodeBlock from '@theme-init/CodeBlock'; +import React from 'react'; + +export default function CodeBlock(props) { + return props.live ? ( + <ReactLivePlayground {...props} /> + ) : ( + <InitialCodeBlock {...props} /> + ); +} +``` + +Check the code of `@docusaurus/theme-live-codeblock` for details. + +:::warning + +Unless you want to publish a re-usable "theme enhancer" (like `@docusaurus/theme-live-codeblock`), you likely don't need `@theme-init`. + +::: + +It can be quite hard to wrap your mind around these aliases. Let's imagine the following case with a super convoluted setup with three themes/plugins and the site itself all trying to define the same component. Internally, Docusaurus loads these themes as a "stack". + +```text ++-------------------------------------------------+ +| `website/src/theme/CodeBlock.js` | <-- `@theme/CodeBlock` always points to the top ++-------------------------------------------------+ +| `theme-live-codeblock/theme/CodeBlock/index.js` | <-- `@theme-original/CodeBlock` points to the topmost non-swizzled component ++-------------------------------------------------+ +| `plugin-awesome-codeblock/theme/CodeBlock.js` | ++-------------------------------------------------+ +| `theme-classic/theme/CodeBlock/index.js` | <-- `@theme-init/CodeBlock` always points to the bottom ++-------------------------------------------------+ +``` + +The components in this "stack" are pushed in the order of `preset plugins > preset themes > plugins > themes > site`, so the swizzled component in `website/src/theme` always comes out on top because it's loaded last. + +`@theme/*` always points to the topmost component—when `CodeBlock` is swizzled, all other components requesting `@theme/CodeBlock` receive the swizzled version. + +`@theme-original/*` always points to the topmost non-swizzled component. That's why you can import `@theme-original/CodeBlock` in the swizzled component—it points to the next one in the "component stack", a theme-provided one. Plugin authors should not try to use this because your component could be the topmost component and cause a self-import. + +`@theme-init/*` always points to the bottommost component—usually, this comes from the theme or plugin that first provides this component. Individual plugins / themes trying to enhance code block can safely use `@theme-init/CodeBlock` to get its basic version. Site creators should generally not use this because you likely want to enhance the _topmost_ instead of the _bottommost_ component. It's also possible that the `@theme-init/CodeBlock` alias does not exist at all—Docusaurus only creates it when it points to a different one from `@theme-original/CodeBlock`, i.e. when it's provided by more than one theme. We don't waste aliases! + +## Client modules {#client-modules} + +Client modules are part of your site's bundle, just like theme components. However, they are usually side-effect-ful. Client modules are anything that can be `import`ed by Webpack—CSS, JS, etc. JS scripts usually work on the global context, like registering event listeners, creating global variables... + +These modules are imported globally before React even renders the initial UI. + +```js title="@docusaurus/core/App.tsx" +// How it works under the hood +import '@generated/client-modules'; +``` + +Plugins and sites can both declare client modules, through [`getClientModules`](../api/plugin-methods/lifecycle-apis.mdx#getClientModules) and [`siteConfig.clientModules`](../api/docusaurus.config.js.mdx#clientModules), respectively. + +Client modules are called during server-side rendering as well, so remember to check the [execution environment](./ssg.mdx#escape-hatches) before accessing client-side globals. + +```js title="mySiteGlobalJs.js" +import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; + +if (ExecutionEnvironment.canUseDOM) { + // As soon as the site loads in the browser, register a global event listener + window.addEventListener('keydown', (e) => { + if (e.code === 'Period') { + location.assign(location.href.replace('.com', '.dev')); + } + }); +} +``` + +CSS stylesheets imported as client modules are [global](../styling-layout.mdx#global-styles). + +```css title="mySiteGlobalCss.css" +/* This stylesheet is global. */ +.globalSelector { + color: red; +} +``` + +### Client module lifecycles {#client-module-lifecycles} + +Besides introducing side-effects, client modules can optionally export two lifecycle functions: `onRouteUpdate` and `onRouteDidUpdate`. + +Because Docusaurus builds a single-page application, `script` tags will only be executed the first time the page loads, but will not re-execute on page transitions. These lifecycles are useful if you have some imperative JS logic that should execute every time a new page has loaded, e.g., to manipulate DOM elements, to send analytics data, etc. + +For every route transition, there will be several important timings: + +1. The user clicks a link, which causes the router to change its current location. +2. Docusaurus preloads the next route's assets, while keeping displaying the current page's content. +3. The next route's assets have loaded. +4. The new location's route component gets rendered to DOM. + +`onRouteUpdate` will be called at event (2), and `onRouteDidUpdate` will be called at (4). They both receive the current location and the previous location (which can be `null`, if this is the first screen). + +`onRouteUpdate` can optionally return a "cleanup" callback, which will be called at (3). For example, if you want to display a progress bar, you can start a timeout in `onRouteUpdate`, and clear the timeout in the callback. (The classic theme already provides an `nprogress` integration this way.) + +Note that the new page's DOM is only available during event (4). If you need to manipulate the new page's DOM, you'll likely want to use `onRouteDidUpdate`, which will be fired as soon as the DOM on the new page has mounted. + +```js title="myClientModule.js" +export function onRouteDidUpdate({location, previousLocation}) { + // Don't execute if we are still on the same page; the lifecycle may be fired + // because the hash changes (e.g. when navigating between headings) + if (location.pathname !== previousLocation?.pathname) { + const title = document.getElementsByTagName('h1')[0]; + if (title) { + title.innerText += '❤️'; + } + } +} + +export function onRouteUpdate({location, previousLocation}) { + if (location.pathname !== previousLocation?.pathname) { + const progressBarTimeout = window.setTimeout(() => { + nprogress.start(); + }, delay); + return () => window.clearTimeout(progressBarTimeout); + } + return undefined; +} +``` + +Or, if you are using TypeScript and you want to leverage contextual typing: + +```ts title="myClientModule.ts" +import type {ClientModule} from '@docusaurus/types'; + +const module: ClientModule = { + onRouteUpdate({location, previousLocation}) { + // ... + }, + onRouteDidUpdate({location, previousLocation}) { + // ... + }, +}; +export default module; +``` + +Both lifecycles will fire on first render, but they will not fire on server-side, so you can safely access browser globals in them. + +:::tip Prefer using React + +Client module lifecycles are purely imperative, and you can't use React hooks or access React contexts within them. If your operations are state-driven or involve complicated DOM manipulations, you should consider [swizzling components](../swizzling.mdx) instead. + +::: diff --git a/website/versioned_docs/version-3.7.0/advanced/index.mdx b/website/versioned_docs/version-3.7.0/advanced/index.mdx new file mode 100644 index 0000000000..b5e5deb222 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/advanced/index.mdx @@ -0,0 +1,11 @@ +# Advanced Tutorials + +This section is not going to be very structured, but we will cover the following topics: + +```mdx-code-block +import DocCardList from '@theme/DocCardList'; + +<DocCardList /> +``` + +We will assume that you have finished the guides, and know the basics like how to configure plugins, how to write React components, etc. These sections will have plugin authors and code contributors in mind, so we may occasionally refer to [plugin APIs](../api/plugin-methods/README.mdx) or other architecture details. Don't panic if you don't understand everything😉 diff --git a/website/versioned_docs/version-3.7.0/advanced/plugins.mdx b/website/versioned_docs/version-3.7.0/advanced/plugins.mdx new file mode 100644 index 0000000000..1f09ea723a --- /dev/null +++ b/website/versioned_docs/version-3.7.0/advanced/plugins.mdx @@ -0,0 +1,129 @@ +# Plugins + +Plugins are the building blocks of features in a Docusaurus site. Each plugin handles its own individual feature. Plugins may work and be distributed as part of a bundle via presets. + +## Creating plugins {#creating-plugins} + +A plugin is a function that takes two parameters: `context` and `options`. It returns a plugin instance object (or a promise). You can create plugins as functions or modules. For more information, refer to the [plugin method references section](../api/plugin-methods/README.mdx). + +### Function definition {#function-definition} + +You can use a plugin as a function directly included in the Docusaurus config file: + +```js title="docusaurus.config.js" +export default { + // ... + plugins: [ + // highlight-start + async function myPlugin(context, options) { + // ... + return { + name: 'my-plugin', + async loadContent() { + // ... + }, + async contentLoaded({content, actions}) { + // ... + }, + /* other lifecycle API */ + }; + }, + // highlight-end + ], +}; +``` + +### Module definition {#module-definition} + +You can use a plugin as a module path referencing a separate file or npm package: + +```js title="docusaurus.config.js" +export default { + // ... + plugins: [ + // without options: + './my-plugin', + // or with options: + ['./my-plugin', options], + ], +}; +``` + +Then in the folder `my-plugin`, you can create an `index.js` such as this: + +```js title="my-plugin/index.js" +export default async function myPlugin(context, options) { + // ... + return { + name: 'my-plugin', + async loadContent() { + /* ... */ + }, + async contentLoaded({content, actions}) { + /* ... */ + }, + /* other lifecycle API */ + }; +} +``` + +--- + +You can view all plugins installed in your site using the [debug plugin's metadata panel](/__docusaurus/debug/metadata). + +Plugins come as several types: + +- `package`: an external package you installed +- `project`: a plugin you created in your project, given to Docusaurus as a local file path +- `local`: a plugin created using the function definition +- `synthetic`: a "fake plugin" Docusaurus created internally, so we take advantage of our modular architecture and don't let the core do much special work. You won't see this in the metadata because it's an implementation detail. + +You can access them on the client side with `useDocusaurusContext().siteMetadata.pluginVersions`. + +## Plugin design {#plugin-design} + +Docusaurus' implementation of the plugins system provides us with a convenient way to hook into the website's lifecycle to modify what goes on during development/build, which involves (but is not limited to) extending the webpack config, modifying the data loaded, and creating new components to be used in a page. + +### Theme design {#theme-design} + +When plugins have loaded their content, the data is made available to the client side through actions like [`createData` + `addRoute`](../api/plugin-methods/lifecycle-apis.mdx#addRoute) or [`setGlobalData`](../api/plugin-methods/lifecycle-apis.mdx#setGlobalData). This data has to be _serialized_ to plain strings, because [plugins and themes run in different environments](./architecture.mdx). Once the data arrives on the client side, the rest becomes familiar to React developers: data is passed along components, components are bundled with Webpack, and rendered to the window through `ReactDOM.render`... + +**Themes provide the set of UI components to render the content.** Most content plugins need to be paired with a theme in order to be actually useful. The UI is a separate layer from the data schema, which makes swapping designs easy. + +For example, a Docusaurus blog may consist of a blog plugin and a blog theme. + +:::note + +This is a contrived example: in practice, `@docusaurus/theme-classic` provides the theme for docs, blog, and layouts. + +::: + +```js title="docusaurus.config.js" +export default { + // highlight-next-line + themes: ['theme-blog'], + plugins: ['plugin-content-blog'], +}; +``` + +And if you want to use Bootstrap styling, you can swap out the theme with `theme-blog-bootstrap` (another fictitious non-existing theme): + +```js title="docusaurus.config.js" +export default { + // highlight-next-line + themes: ['theme-blog-bootstrap'], + plugins: ['plugin-content-blog'], +}; +``` + +Now, although the theme receives the same data from the plugin, how the theme chooses to _render_ the data as UI can be drastically different. + +While themes share the exact same lifecycle methods with plugins, themes' implementations can look very different from those of plugins based on themes' designed objectives. + +Themes are designed to complete the build of your Docusaurus site and supply the components used by your site, plugins, and the themes themselves. A theme still acts like a plugin and exposes some lifecycle methods, but most likely they would not use [`loadContent`](../api/plugin-methods/lifecycle-apis.mdx#loadContent), since they only receive data from plugins, but don't generate data themselves; themes are typically also accompanied by an `src/theme` directory full of components, which are made known to the core through the [`getThemePath`](../api/plugin-methods/extend-infrastructure.mdx#getThemePath) lifecycle. + +To summarize: + +- Themes share the same lifecycle methods with Plugins +- Themes are run after all existing Plugins +- Themes add component aliases by providing `getThemePath`. diff --git a/website/versioned_docs/version-3.7.0/advanced/routing.mdx b/website/versioned_docs/version-3.7.0/advanced/routing.mdx new file mode 100644 index 0000000000..ea62c06f35 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/advanced/routing.mdx @@ -0,0 +1,289 @@ +--- +description: "Docusaurus' routing system follows single-page application conventions: one route, one component." +--- + +# Routing + +```mdx-code-block +import Link from '@docusaurus/Link'; +import {useLatestVersion, useActiveDocContext} from '@docusaurus/plugin-content-docs/client'; +import {useLocation} from '@docusaurus/router'; +import BrowserWindow from '@site/src/components/BrowserWindow'; +``` + +Docusaurus' routing system follows single-page application conventions: one route, one component. In this section, we will begin by talking about routing within the three content plugins (docs, blog, and pages), and then go beyond to talk about the underlying routing system. + +## Routing in content plugins {#routing-in-content-plugins} + +Every content plugin provides a `routeBasePath` option. It defines where the plugins append their routes to. By default, the docs plugin puts its routes under `/docs`; the blog plugin, `/blog`; and the pages plugin, `/`. You can think about the route structure like this: + +```mermaid +graph LR; + A(["https://example.com/"]) + B(["/base-url/"]) + C(["/docs/"]) + D(["/blog/"]) + E(["/"]) + F["All docs <br/>routes"] + G["All blog <br/>routes"] + H["All pages <br/>routes"] + A---B; + B---C; + B---D; + B---E; + C---F; + D---G; + E---H; +``` + +Any route will be matched against this nested route config until a good match is found. For example, when given a route `/docs/configuration`, Docusaurus first enters the `/docs` branch, and then searches among the subroutes created by the docs plugin. + +Changing `routeBasePath` can effectively alter your site's route structure. For example, in [Docs-only mode](../guides/docs/docs-introduction.mdx#docs-only-mode), we mentioned that configuring `routeBasePath: '/'` for docs means that all routes that the docs plugin create would not have the `/docs` prefix, yet it doesn't prevent you from having more subroutes like `/blog` created by other plugins. + +Next, let's look at how the three plugins structure their own "boxes of subroutes". + +### Pages routing {#pages-routing} + +Pages routing are straightforward: the file paths directly map to URLs, without any other way to customize. See the [pages docs](../guides/creating-pages.mdx#routing) for more information. + +The component used for Markdown pages is `@theme/MDXPage`. React pages are directly used as the route's component. + +### Blog routing {#blog-routing} + +The blog creates the following routes: + +- **Posts list pages**: `/`, `/page/2`, `/page/3`... + - The route is customizable through the `pageBasePath` option. + - The component is `@theme/BlogListPage`. +- **Post pages**: `/2021/11/21/algolia-docsearch-migration`, `/2021/05/12/announcing-docusaurus-two-beta`... + - Generated from each Markdown post. + - The routes are fully customizable through the `slug` front matter. + - The component is `@theme/BlogPostPage`. +- **Tags list page**: `/tags` + - The route is customizable through the `tagsBasePath` option. + - The component is `@theme/BlogTagsListPage`. +- **Tag pages**: `/tags/adoption`, `/tags/beta`... + - Generated through the tags defined in each post's front matter. + - The routes always have base defined in `tagsBasePath`, but the subroutes are customizable through the tag's `permalink` field. + - The component is `@theme/BlogTagsPostsPage`. +- **Archive page**: `/archive` + - The route is customizable through the `archiveBasePath` option. + - The component is `@theme/BlogArchivePage`. + +### Docs routing {#docs-routing} + +The docs is the only plugin that creates **nested routes**. At the top, it registers [**version paths**](../guides/docs/versioning.mdx): `/`, `/next`, `/2.0.0-beta.13`... which provide the version context, including the layout and sidebar. This ensures that when switching between individual docs, the sidebar's state is preserved, and that you can switch between versions through the navbar dropdown while staying on the same doc. The component used is `@theme/DocPage`. + +```mdx-code-block +export const URLPath = () => <code>{useLocation().pathname}</code>; + +export const FilePath = () => { + const currentVersion = useActiveDocContext('default').activeVersion.name; + return <code>{currentVersion === 'current' ? './docs/' : `./versioned_docs/version-${currentVersion}/`}advanced/routing.md</code>; +} +``` + +The individual docs are rendered in the remaining space after the navbar, footer, sidebar, etc. have all been provided by the `DocPage` component. For example, this page, <URLPath />, is generated from the file at <FilePath />. The component used is `@theme/DocItem`. + +The doc's `slug` front matter customizes the last part of the route, but the base route is always defined by the plugin's `routeBasePath` and the version's `path`. + +### File paths and URL paths {#file-paths-and-url-paths} + +Throughout the documentation, we always try to be unambiguous about whether we are talking about file paths or URL paths. Content plugins usually map file paths directly to URL paths, for example, `./docs/advanced/routing.md` will become `/docs/advanced/routing`. However, with `slug`, you can make URLs totally decoupled from the file structure. + +When writing links in Markdown, you could either mean a _file path_, or a _URL path_, which Docusaurus would use several heuristics to determine. + +- If the path has a `@site` prefix, it is _always_ an asset file path. +- If the path has an `http(s)://` prefix, it is _always_ a URL path. +- If the path doesn't have an extension, it is a URL path. For example, a link `[page](../plugins)` on a page with URL `/docs/advanced/routing` will link to `/docs/plugins`. Docusaurus will only detect broken links when building your site (when it knows the full route structure), but will make no assumptions about the existence of a file. It is exactly equivalent to writing `<a href="../plugins">page</a>` in a JSX file. +- If the path has an `.md(x)` extension, Docusaurus would try to resolve that Markdown file to a URL, and replace the file path with a URL path. +- If the path has any other extension, Docusaurus would treat it as [an asset](../guides/markdown-features/markdown-features-assets.mdx) and bundle it. + +The following directory structure may help you visualize this file → URL mapping. Assume that there's no slug customization in any page. + +<details> + +<summary>A sample site structure</summary> + +```bash +. +├── blog # blog plugin has routeBasePath: '/blog' +│ ├── 2019-05-28-first-blog-post.md # -> /blog/2019/05/28/first-blog-post +│ ├── 2019-05-29-long-blog-post.md # -> /blog/2019/05/29/long-blog-post +│ ├── 2021-08-01-mdx-blog-post.mdx # -> /blog/2021/08/01/mdx-blog-post +│ └── 2021-08-26-welcome +│ ├── docusaurus-plushie-banner.jpeg +│ └── index.md # -> /blog/2021/08/26/welcome +├── docs # docs plugin has routeBasePath: '/docs'; current version has base path '/' +│ ├── intro.md # -> /docs/intro +│ ├── tutorial-basics +│ │ ├── _category_.json +│ │ ├── congratulations.md # -> /docs/tutorial-basics/congratulations +│ │ └── markdown-features.mdx # -> /docs/tutorial-basics/markdown-features +│ └── tutorial-extras +│ ├── _category_.json +│ ├── manage-docs-versions.md # -> /docs/tutorial-extras/manage-docs-versions +│ └── translate-your-site.md # -> /docs/tutorial-extras/translate-your-site +├── src +│ └── pages # pages plugin has routeBasePath: '/' +│ ├── index.module.css +│ ├── index.tsx # -> / +│ └── markdown-page.md # -> /markdown-page +└── versioned_docs + └── version-1.0.0 # version has base path '/1.0.0' + ├── intro.md # -> /docs/1.0.0/intro + ├── tutorial-basics + │ ├── _category_.json + │ ├── congratulations.md # -> /docs/1.0.0/tutorial-basics/congratulations + │ └── markdown-features.mdx # -> /docs/1.0.0/tutorial-basics/markdown-features + └── tutorial-extras + ├── _category_.json + ├── manage-docs-versions.md # -> /docs/1.0.0/tutorial-extras/manage-docs-versions + └── translate-your-site.md # -> /docs/1.0.0/tutorial-extras/translate-your-site +``` + +</details> + +So much about content plugins. Let's take one step back and talk about how routing works in a Docusaurus app in general. + +## Routes become HTML files {#routes-become-html-files} + +Because Docusaurus is a server-side rendering framework, all routes generated will be server-side rendered into static HTML files. If you are familiar with the behavior of HTTP servers like [Apache2](https://httpd.apache.org/docs/trunk/getting-started.html), you will understand how this is done: when the browser sends a request to the route `/docs/advanced/routing`, the server interprets that as request for the HTML file `/docs/advanced/routing/index.html`, and returns that. + +The `/docs/advanced/routing` route can correspond to either `/docs/advanced/routing/index.html` or `/docs/advanced/routing.html`. Some hosting providers differentiate between them using the presence of a trailing slash, and may or may not tolerate the other. Read more in the [trailing slash guide](https://github.com/slorber/trailing-slash-guide). + +For example, the build output of the directory above is (ignoring other assets and JS bundle): + +<details> + +<summary>Output of the above workspace</summary> + +```bash +build +├── 404.html # /404/ +├── blog +│ ├── archive +│ │ └── index.html # /blog/archive/ +│ ├── first-blog-post +│ │ └── index.html # /blog/first-blog-post/ +│ ├── index.html # /blog/ +│ ├── long-blog-post +│ │ └── index.html # /blog/long-blog-post/ +│ ├── mdx-blog-post +│ │ └── index.html # /blog/mdx-blog-post/ +│ ├── tags +│ │ ├── docusaurus +│ │ │ └── index.html # /blog/tags/docusaurus/ +│ │ ├── hola +│ │ │ └── index.html # /blog/tags/hola/ +│ │ └── index.html # /blog/tags/ +│ └── welcome +│ └── index.html # /blog/welcome/ +├── docs +│ ├── 1.0.0 +│ │ ├── intro +│ │ │ └── index.html # /docs/1.0.0/intro/ +│ │ ├── tutorial-basics +│ │ │ ├── congratulations +│ │ │ │ └── index.html # /docs/1.0.0/tutorial-basics/congratulations/ +│ │ │ └── markdown-features +│ │ │ └── index.html # /docs/1.0.0/tutorial-basics/markdown-features/ +│ │ └── tutorial-extras +│ │ ├── manage-docs-versions +│ │ │ └── index.html # /docs/1.0.0/tutorial-extras/manage-docs-versions/ +│ │ └── translate-your-site +│ │ └── index.html # /docs/1.0.0/tutorial-extras/translate-your-site/ +│ ├── intro +│ │ └── index.html # /docs/1.0.0/intro/ +│ ├── tutorial-basics +│ │ ├── congratulations +│ │ │ └── index.html # /docs/tutorial-basics/congratulations/ +│ │ └── markdown-features +│ │ └── index.html # /docs/tutorial-basics/markdown-features/ +│ └── tutorial-extras +│ ├── manage-docs-versions +│ │ └── index.html # /docs/tutorial-extras/manage-docs-versions/ +│ └── translate-your-site +│ └── index.html # /docs/tutorial-extras/translate-your-site/ +├── index.html # / +└── markdown-page + └── index.html # /markdown-page/ +``` + +</details> + +If `trailingSlash` is set to `false`, the build would emit `intro.html` instead of `intro/index.html`. + +All HTML files will reference its JS assets using absolute URLs, so in order for the correct assets to be located, you have to configure the `baseUrl` field. Note that `baseUrl` doesn't affect the emitted bundle's file structure: the base URL is one level above the Docusaurus routing system. You can see the aggregate of `url` and `baseUrl` as the actual location of your Docusaurus site. + +For example, the emitted HTML would contain links like `<link rel="preload" href="/assets/js/runtime~main.7ed5108a.js" as="script">`. Because absolute URLs are resolved from the host, if the bundle placed under the path `https://example.com/base/`, the link will point to `https://example.com/assets/js/runtime~main.7ed5108a.js`, which is, well, non-existent. By specifying `/base/` as base URL, the link will correctly point to `/base/assets/js/runtime~main.7ed5108a.js`. + +Localized sites have the locale as part of the base URL as well. For example, `https://docusaurus.io/zh-CN/docs/advanced/routing/` has base URL `/zh-CN/`. + +## Generating and accessing routes {#generating-and-accessing-routes} + +The `addRoute` lifecycle action is used to generate routes. It registers a piece of route config to the route tree, giving a route, a component, and props that the component needs. The props and the component are both provided as paths for the bundler to `require`, because as explained in the [architecture overview](architecture.mdx), server and client only communicate through temp files. + +All routes are aggregated in `.docusaurus/routes.js`, which you can view with the debug plugin's [routes panel](/__docusaurus/debug/routes). + +On the client side, we offer `@docusaurus/router` to access the page's route. `@docusaurus/router` is a re-export of the [`react-router-dom`](https://www.npmjs.com/package/react-router-dom/v/5.3.0) package. For example, you can use `useLocation` to get the current page's [location](https://developer.mozilla.org/en-US/docs/Web/API/Location), and `useHistory` to access the [history object](https://developer.mozilla.org/en-US/docs/Web/API/History). (They are not the same as the browser API, although similar in functionality. Refer to the React Router documentation for specific APIs.) + +This API is **SSR safe**, as opposed to the browser-only `window.location`. + +```jsx title="myComponent.js" +import React from 'react'; +import {useLocation} from '@docusaurus/router'; + +export function PageRoute() { + // React router provides the current component's route, even in SSR + const location = useLocation(); + return ( + <span> + We are currently on <code>{location.pathname}</code> + </span> + ); +} +``` + +```mdx-code-block +export function PageRoute() { + const location = useLocation(); + return ( + <span> + We are currently on <code>{location.pathname}</code> + </span> + ); +} + +<BrowserWindow> + +<PageRoute /> + +</BrowserWindow> +``` + +## Escaping from SPA redirects {#escaping-from-spa-redirects} + +Docusaurus builds a [single-page application](https://developer.mozilla.org/en-US/docs/Glossary/SPA), where route transitions are done through the `history.push()` method of React router. This operation is done on the client side. However, the prerequisite for a route transition to happen this way is that the target URL is known to our router. Otherwise, the router catches this path and displays a 404 page instead. + +If you put some HTML pages under the `static` folder, they will be copied to the build output and therefore become accessible as part of your website, yet it's not part of the Docusaurus route system. We provide a `pathname://` protocol that allows you to redirect to another part of your domain in a non-SPA fashion, as if this route is an external link. + +```md +- [pathname:///pure-html](pathname:///pure-html) +``` + +<BrowserWindow> + +- [`pathname:///pure-html`](pathname:///pure-html) + +</BrowserWindow> + +The `pathname://` protocol is useful for referencing any content in the static folder. For example, Docusaurus would convert [all Markdown static assets to require() calls](../guides/markdown-features/markdown-features-assets.mdx#static-assets). You can use `pathname://` to keep it a regular link instead of being hashed by Webpack. + +```md title="my-doc.md" +![An image from the static](pathname:///img/docusaurus.png) + +[An asset from the static](pathname:///files/asset.pdf) +``` + +Docusaurus will only strip the `pathname://` prefix without processing the content. diff --git a/website/versioned_docs/version-3.7.0/advanced/ssg.mdx b/website/versioned_docs/version-3.7.0/advanced/ssg.mdx new file mode 100644 index 0000000000..07931249bb --- /dev/null +++ b/website/versioned_docs/version-3.7.0/advanced/ssg.mdx @@ -0,0 +1,218 @@ +--- +sidebar_label: Static site generation +description: Docusaurus statically renders your React code into HTML, allowing faster load speed and better SEO. +--- + +# Static site generation (SSG) + +In [architecture](architecture.mdx), we mentioned that the theme is run in Webpack. But beware: that doesn't mean it always has access to browser globals! The theme is built twice: + +- During **server-side rendering**, the theme is compiled in a sandbox called [React DOM Server](https://reactjs.org/docs/react-dom-server.html). You can see this as a "headless browser", where there is no `window` or `document`, only React. SSR produces static HTML pages. +- During **client-side rendering**, the theme is compiled to JavaScript that gets eventually executed in the browser, so it has access to browser variables. + +:::info SSR or SSG? + +_Server-side rendering_ and _static site generation_ can be different concepts, but we use them interchangeably. + +Strictly speaking, Docusaurus is a static site generator, because there's no server-side runtime—we statically render to HTML files that are deployed on a CDN, instead of dynamically pre-rendering on each request. This differs from the working model of [Next.js](https://nextjs.org/). + +::: + +Therefore, while you probably know not to access Node globals like `process` ([or can we?](#node-env)) or the `'fs'` module, you can't freely access browser globals either. + +```jsx +import React from 'react'; + +export default function WhereAmI() { + return <span>{window.location.href}</span>; +} +``` + +This looks like idiomatic React, but if you run `docusaurus build`, you will get an error: + +``` +ReferenceError: window is not defined +``` + +This is because during server-side rendering, the Docusaurus app isn't actually run in browser, and it doesn't know what `window` is. + +```mdx-code-block +<details id="node-env"> +<summary>What about <code>process.env.NODE_ENV</code>?</summary> +``` + +One exception to the "no Node globals" rule is `process.env.NODE_ENV`. In fact, you can use it in React, because Webpack injects this variable as a global: + +```jsx +import React from 'react'; + +export default function expensiveComp() { + if (process.env.NODE_ENV === 'development') { + return <>This component is not shown in development</>; + } + const res = someExpensiveOperationThatLastsALongTime(); + return <>{res}</>; +} +``` + +During Webpack build, the `process.env.NODE_ENV` will be replaced with the value, either `'development'` or `'production'`. You will then get different build results after dead code elimination: + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +```mdx-code-block +<Tabs> +<TabItem value="Development"> +``` + +```diff +import React from 'react'; + +export default function expensiveComp() { + // highlight-next-line + if ('development' === 'development') { ++ return <>This component is not shown in development</>; + } +- const res = someExpensiveOperationThatLastsALongTime(); +- return <>{res}</>; +} +``` + +```mdx-code-block +</TabItem> +<TabItem value="Production"> +``` + +```diff +import React from 'react'; + +export default function expensiveComp() { + // highlight-next-line +- if ('production' === 'development') { +- return <>This component is not shown in development</>; +- } ++ const res = someExpensiveOperationThatLastsALongTime(); ++ return <>{res}</>; +} +``` + +```mdx-code-block +</TabItem> +</Tabs> +</details> +``` + +## Understanding SSR {#understanding-ssr} + +React is not just a dynamic UI runtime—it's also a templating engine. Because Docusaurus sites mostly contain static contents, it should be able to work without any JavaScript (which React runs in), but only plain HTML/CSS. And that's what server-side rendering offers: statically rendering your React code into HTML, without any dynamic content. An HTML file has no concept of client state (it's purely markup), hence it shouldn't rely on browser APIs. + +These HTML files are the first to arrive at the user's browser screen when a URL is visited (see [routing](routing.mdx)). Afterwards, the browser fetches and runs other JS code to provide the "dynamic" parts of your site—anything implemented with JavaScript. However, before that, the main content of your page is already visible, allowing faster loading. + +In CSR-only apps, all DOM elements are generated on client side with React, and the HTML file only ever contains one root element for React to mount DOM to; in SSR, React is already facing a fully built HTML page, and it only needs to correlate the DOM elements with the virtual DOM in its model. This step is called "hydration". After React has hydrated the static markup, the app starts to work as any normal React app. + +Note that Docusaurus is ultimately a single-page application, so static site generation is only an optimization (_progressive enhancement_, as it's called), but our functionality does not fully depend on those HTML files. This is contrary to site generators like [Jekyll](https://jekyllrb.com/) and [Docusaurus v1](https://v1.docusaurus.io/), where all files are statically transformed to markup, and interactiveness is added through external JavaScript linked with `<script>` tags. If you inspect the build output, you will still see JS assets under `build/assets/js`, which are, really, the core of Docusaurus. + +## Escape hatches {#escape-hatches} + +If you want to render any dynamic content on your screen that relies on the browser API to be functional at all, for example: + +- Our [live codeblock](../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor), which runs in the browser's JS runtime +- Our [themed image](../guides/markdown-features/markdown-features-assets.mdx#themed-images) that detects the user's color scheme to display different images +- The JSON viewer of our debug panel which uses the `window` global for styling + +You may need to escape from SSR since static HTML can't display anything useful without knowing the client state. + +:::warning + +It is important for the first client-side render to produce the exact same DOM structure as server-side rendering, otherwise, React will correlate virtual DOM with the wrong DOM elements. + +Therefore, the naïve attempt of `if (typeof window !== 'undefined) {/* render something */}` won't work appropriately as a browser vs. server detection, because the first client render would instantly render different markup from the server-generated one. + +You can read more about this pitfall in [The Perils of Rehydration](https://www.joshwcomeau.com/react/the-perils-of-rehydration/). + +::: + +We provide several more reliable ways to escape SSR. + +### `<BrowserOnly>` {#browseronly} + +If you need to render some component in browser only (for example, because the component relies on browser specifics to be functional at all), one common approach is to wrap your component with [`<BrowserOnly>`](../docusaurus-core.mdx#browseronly) to make sure it's invisible during SSR and only rendered in CSR. + +```jsx +import BrowserOnly from '@docusaurus/BrowserOnly'; + +function MyComponent(props) { + return ( + // highlight-start + <BrowserOnly fallback={<div>Loading...</div>}> + {() => { + const LibComponent = + require('some-lib-that-accesses-window').LibComponent; + return <LibComponent {...props} />; + }} + </BrowserOnly> + // highlight-end + ); +} +``` + +It's important to realize that the children of `<BrowserOnly>` is not a JSX element, but a function that _returns_ an element. This is a design decision. Consider this code: + +```jsx +import BrowserOnly from '@docusaurus/BrowserOnly'; + +function MyComponent() { + return ( + <BrowserOnly> + {/* highlight-start */} + {/* DON'T DO THIS - doesn't actually work */} + <span>page url = {window.location.href}</span> + {/* highlight-end */} + </BrowserOnly> + ); +} +``` + +While you may expect that `BrowserOnly` hides away the children during server-side rendering, it actually can't. When the React renderer tries to render this JSX tree, it does see the `{window.location.href}` variable as a node of this tree and tries to render it, although it's actually not used! Using a function ensures that we only let the renderer see the browser-only component when it's needed. + +### `useIsBrowser` {#useisbrowser} + +You can also use the `useIsBrowser()` hook to test if the component is currently in a browser environment. It returns `false` in SSR and `true` is CSR, after first client render. Use this hook if you only need to perform certain conditional operations on client-side, but not render an entirely different UI. + +```jsx +import useIsBrowser from '@docusaurus/useIsBrowser'; + +function MyComponent() { + const isBrowser = useIsBrowser(); + const location = isBrowser ? window.location.href : 'fetching location...'; + return <span>{location}</span>; +} +``` + +### `useEffect` {#useeffect} + +Lastly, you can put your logic in `useEffect()` to delay its execution until after first CSR. This is most appropriate if you are only performing side-effects but don't _get_ data from the client state. + +```jsx +function MyComponent() { + useEffect(() => { + // Only logged in the browser console; nothing is logged during server-side rendering + console.log("I'm now in the browser"); + }, []); + return <span>Some content...</span>; +} +``` + +### `ExecutionEnvironment` {#executionenvironment} + +The [`ExecutionEnvironment`](../docusaurus-core.mdx#executionenvironment) namespace contains several values, and `canUseDOM` is an effective way to detect browser environment. + +Beware that it essentially checked `typeof window !== 'undefined'` under the hood, so you should not use it for rendering-related logic, but only imperative code, like reacting to user input by sending web requests, or dynamically importing libraries, where DOM isn't updated at all. + +```js title="a-client-module.js" +import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; + +if (ExecutionEnvironment.canUseDOM) { + document.title = "I'm loaded!"; +} +``` diff --git a/website/versioned_docs/version-3.7.0/api/docusaurus.config.js.mdx b/website/versioned_docs/version-3.7.0/api/docusaurus.config.js.mdx new file mode 100644 index 0000000000..fb358955dc --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/docusaurus.config.js.mdx @@ -0,0 +1,758 @@ +--- +sidebar_position: 0 +description: API reference for Docusaurus configuration file. +slug: /api/docusaurus-config +--- + +# `docusaurus.config.js` + +import APITable from '@site/src/components/APITable'; + +:::info + +Refer to the Getting Started [**Configuration**](../configuration.mdx) for examples. + +::: + +## Overview {#overview} + +`docusaurus.config.js` contains configurations for your site and is placed in the root directory of your site. + +:::note + +With a [TypeScript](../typescript-support.mdx) Docusaurus codebase your config file may be called `docusaurus.config.ts`. The syntax is broadly identical to the `js` config file with the addition of types. You can see an example on the [Docusaurus Website](https://github.com/facebook/docusaurus/blob/main/website/docusaurus.config.ts) itself. + +::: + +This file is **run in Node.js** and should export a site configuration object, or a function that creates it. + +The `docusaurus.config.js` file supports: + +- [**ES Modules**](https://flaviocopes.com/es-modules/) +- [**CommonJS**](https://flaviocopes.com/commonjs/) +- [**TypeScript**](../typescript-support.mdx#typing-config) + +Examples: + +```js title="docusaurus.config.js" +export default { + title: 'Docusaurus', + url: 'https://docusaurus.io', + // your site config ... +}; +``` + +```js title="docusaurus.config.js" +export default async function createConfigAsync() { + return { + title: 'Docusaurus', + url: 'https://docusaurus.io', + // your site config ... + }; +} +``` + +:::tip + +Refer to [**Syntax to declare `docusaurus.config.js`**](../configuration.mdx#syntax-to-declare-docusaurus-config) for a more exhaustive list of examples and explanations. + +::: + +## Required fields {#required-fields} + +### `title` {#title} + +- Type: `string` + +Title for your website. Will be used in metadata and as browser tab title. + +```js title="docusaurus.config.js" +export default { + title: 'Docusaurus', +}; +``` + +### `url` {#url} + +- Type: `string` + +URL for your website. This can also be considered the top-level hostname. For example, `https://facebook.github.io` is the URL of https://facebook.github.io/metro/, and `https://docusaurus.io` is the URL for https://docusaurus.io. This field is related to the [`baseUrl`](#baseUrl) field. + +```js title="docusaurus.config.js" +export default { + url: 'https://docusaurus.io', +}; +``` + +### `baseUrl` {#baseUrl} + +- Type: `string` + +Base URL for your site. Can be considered as the path after the host. For example, `/metro/` is the base URL of https://facebook.github.io/metro/. For URLs that have no path, the baseUrl should be set to `/`. This field is related to the [`url`](#url) field. Always has both leading and trailing slash. + +```js title="docusaurus.config.js" +export default { + baseUrl: '/', +}; +``` + +## Optional fields {#optional-fields} + +### `favicon` {#favicon} + +- Type: `string | undefined` + +Path to your site favicon; must be a URL that can be used in link's href. For example, if your favicon is in `static/img/favicon.ico`: + +```js title="docusaurus.config.js" +export default { + favicon: '/img/favicon.ico', +}; +``` + +### `trailingSlash` {#trailingSlash} + +- Type: `boolean | undefined` + +Allow to customize the presence/absence of a trailing slash at the end of URLs/links, and how static HTML files are generated: + +- `undefined` (default): keeps URLs untouched, and emit `/docs/myDoc/index.html` for `/docs/myDoc.md` +- `true`: add trailing slashes to URLs/links, and emit `/docs/myDoc/index.html` for `/docs/myDoc.md` +- `false`: remove trailing slashes from URLs/links, and emit `/docs/myDoc.html` for `/docs/myDoc.md` + +:::tip + +Each static hosting provider serves static files differently (this behavior may even change over time). + +Refer to the [deployment guide](../deployment.mdx) and [slorber/trailing-slash-guide](https://github.com/slorber/trailing-slash-guide) to choose the appropriate setting. + +::: + +### `i18n` {#i18n} + +- Type: `Object` + +The i18n configuration object to [localize your site](../i18n/i18n-introduction.mdx). + +Example: + +{/* cSpell:ignore فارسی */} + +```js title="docusaurus.config.js" +export default { + i18n: { + defaultLocale: 'en', + locales: ['en', 'fa'], + path: 'i18n', + localeConfigs: { + en: { + label: 'English', + direction: 'ltr', + htmlLang: 'en-US', + calendar: 'gregory', + path: 'en', + }, + fa: { + label: 'فارسی', + direction: 'rtl', + htmlLang: 'fa-IR', + calendar: 'persian', + path: 'fa', + }, + }, + }, +}; +``` + +- `defaultLocale`: The locale that (1) does not have its name in the base URL (2) gets started with `docusaurus start` without `--locale` option (3) will be used for the `<link hrefLang="x-default">` tag +- `locales`: List of locales deployed on your site. Must contain `defaultLocale`. +- `path`: Root folder which all locale folders are relative to. Can be absolute or relative to the config file. Defaults to `i18n`. +- `localeConfigs`: Individual options for each locale. + - `label`: The label displayed for this locale in the locales dropdown. + - `direction`: `ltr` (default) or `rtl` (for [right-to-left languages](https://developer.mozilla.org/en-US/docs/Glossary/rtl) like Farsi, Arabic, Hebrew, etc.). Used to select the locale's CSS and HTML meta attribute. + - `htmlLang`: BCP 47 language tag to use in `<html lang="...">` (or any other DOM tag name) and in `<link ... hreflang="...">` + - `calendar`: the [calendar](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/calendar) used to calculate the date era. Note that it doesn't control the actual string displayed: `MM/DD/YYYY` and `DD/MM/YYYY` are both `gregory`. To choose the format (`DD/MM/YYYY` or `MM/DD/YYYY`), set your locale name to `en-GB` or `en-US` (`en` means `en-US`). + - `path`: Root folder that all plugin localization folders of this locale are relative to. Will be resolved against `i18n.path`. Defaults to the locale's name. Note: this has no effect on the locale's `baseUrl`—customization of base URL is a work-in-progress. + +### `future` {#future} + +- Type: `Object` + +The `future` configuration object permits to opt-in for upcoming/unstable/experimental Docusaurus features that are not ready for prime time. + +It is also a way to opt-in for upcoming breaking changes coming in the next major versions, enabling you to prepare your site for the next version while staying on the previous one. The [Remix Future Flags blog post](https://remix.run/blog/future-flags) greatly explains this idea. + +:::danger Breaking changes in minor versions + +Features prefixed by `experimental_` or `unstable_` are subject to changes in **minor versions**, and not considered as [Semantic Versioning breaking changes](/community/release-process). + +Features prefixed by `v<MajorVersion>_` (`v6_` `v7_`, etc.) are future flags that are expected to be turned on by default in the next major versions. These are less likely to change, but we keep the possibility to do so. + +`future` API breaking changes should be easy to handle, and will be documented in minor/major version blog posts. + +::: + +Example: + +```js title="docusaurus.config.js" +export default { + future: { + experimental_faster: { + swcJsLoader: true, + swcJsMinimizer: true, + swcHtmlMinimizer: true, + lightningCssMinimizer: true, + rspackBundler: true, + mdxCrossCompilerCache: true, + }, + experimental_storage: { + type: 'localStorage', + namespace: true, + }, + experimental_router: 'hash', + }, +}; +``` + +- `experimental_faster`: An object containing feature flags to make the Docusaurus build faster. This requires adding the `@docusaurus/faster` package to your site's dependencies. Use `true` as a shorthand to enable all flags. Read more on the [Docusaurus Faster](https://github.com/facebook/docusaurus/issues/10556) issue. Available feature flags: + - [`swcJsLoader`](https://github.com/facebook/docusaurus/pull/10435): Use [SWC](https://swc.rs/) to transpile JS (instead of [Babel](https://babeljs.io/)). + - [`swcJsMinimizer`](https://github.com/facebook/docusaurus/pull/10441): Use [SWC](https://swc.rs/) to minify JS (instead of [Terser](https://github.com/terser/terser)). + - [`swcHtmlMinimizer `](https://github.com/facebook/docusaurus/pull/10554): Use [SWC](https://swc.rs/) to minify HTML and inlined JS/CSS (instead of [html-minifier-terser](https://github.com/terser/html-minifier-terser)). + - [`lightningCssMinimizer`](https://github.com/facebook/docusaurus/pull/10522): Use [Lightning CSS](https://lightningcss.dev/) to minify CSS (instead of [cssnano](https://github.com/cssnano/cssnano) and [clean-css](https://github.com/clean-css/clean-css)). + - [`rspackBundler`](https://github.com/facebook/docusaurus/pull/10402): Use [Rspack](https://rspack.dev/) to bundle your app (instead of [webpack](https://webpack.js.org/)). + - [`mdxCrossCompilerCache`](https://github.com/facebook/docusaurus/pull/10479): Compile MDX files only once for both browser/Node.js environments instead of twice. +- `experimental_storage`: Site-wide browser storage options that theme authors should strive to respect. + - `type`: The browser storage theme authors should use. Possible values are `localStorage` and `sessionStorage`. Defaults to `localStorage`. + - `namespace`: Whether to namespace the browser storage keys to avoid storage key conflicts when Docusaurus sites are hosted under the same domain, or on localhost. Possible values are `string | boolean`. The namespace is appended at the end of the storage keys `key-namespace`. Use `true` to automatically generate a random namespace from your site `url + baseUrl`. Defaults to `false` (no namespace, historical behavior). +- `experimental_router`: The router type to use. Possible values are `browser` and `hash`. Defaults to `browser`. The `hash` router is only useful for rare cases where you want to opt-out of static site generation, have a fully client-side app with a single `index.html` entrypoint file. This can be useful to distribute a Docusaurus site as a `.zip` archive that you can [browse locally without running a web server](https://github.com/facebook/docusaurus/issues/3825). + +### `noIndex` {#noIndex} + +- Type: `boolean` + +This option adds `<meta name="robots" content="noindex, nofollow">` to every page to tell search engines to avoid indexing your site (more information [here](https://moz.com/learn/seo/robots-meta-directives)). + +Example: + +```js title="docusaurus.config.js" +export default { + noIndex: true, // Defaults to `false` +}; +``` + +### `onBrokenLinks` {#onBrokenLinks} + +- Type: `'ignore' | 'log' | 'warn' | 'throw'` + +The behavior of Docusaurus when it detects any broken link. + +By default, it throws an error, to ensure you never ship any broken link. + +:::note + +The broken links detection is only available for a production build (`docusaurus build`). + +::: + +### `onBrokenAnchors` {#onBrokenAnchors} + +- Type: `'ignore' | 'log' | 'warn' | 'throw'` + +The behavior of Docusaurus when it detects any broken anchor declared with the `Heading` component of Docusaurus. + +By default, it prints a warning, to let you know about your broken anchors. + +### `onBrokenMarkdownLinks` {#onBrokenMarkdownLinks} + +- Type: `'ignore' | 'log' | 'warn' | 'throw'` + +The behavior of Docusaurus when it detects any broken Markdown link. + +By default, it prints a warning, to let you know about your broken Markdown link. + +### `onDuplicateRoutes` {#onDuplicateRoutes} + +- Type: `'ignore' | 'log' | 'warn' | 'throw'` + +The behavior of Docusaurus when it detects any [duplicate routes](/guides/creating-pages.mdx#duplicate-routes). + +By default, it displays a warning after you run `yarn start` or `yarn build`. + +### `tagline` {#tagline} + +- Type: `string` + +The tagline for your website. + +```js title="docusaurus.config.js" +export default { + tagline: + 'Docusaurus makes it easy to maintain Open Source documentation websites.', +}; +``` + +### `organizationName` {#organizationName} + +- Type: `string` + +The GitHub user or organization that owns the repository. You don't need this if you are not using the `docusaurus deploy` command. + +```js title="docusaurus.config.js" +export default { + // Docusaurus' organization is facebook + organizationName: 'facebook', +}; +``` + +### `projectName` {#projectName} + +- Type: `string` + +The name of the GitHub repository. You don't need this if you are not using the `docusaurus deploy` command. + +```js title="docusaurus.config.js" +export default { + projectName: 'docusaurus', +}; +``` + +### `deploymentBranch` {#deploymentBranch} + +- Type: `string` + +The name of the branch to deploy the static files to. You don't need this if you are not using the `docusaurus deploy` command. + +```js title="docusaurus.config.js" +export default { + deploymentBranch: 'gh-pages', +}; +``` + +### `githubHost` {#githubHost} + +- Type: `string` + +The hostname of your server. Useful if you are using GitHub Enterprise. You don't need this if you are not using the `docusaurus deploy` command. + +```js title="docusaurus.config.js" +export default { + githubHost: 'github.com', +}; +``` + +### `githubPort` {#githubPort} + +- Type: `string` + +The port of your server. Useful if you are using GitHub Enterprise. You don't need this if you are not using the `docusaurus deploy` command. + +```js title="docusaurus.config.js" +export default { + githubPort: '22', +}; +``` + +### `themeConfig` {#themeConfig} + +- Type: `Object` + +The [theme configuration](./themes/theme-configuration.mdx) object to customize your site UI like navbar and footer. + +Example: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + docs: { + sidebar: { + hideable: false, + autoCollapseCategories: false, + }, + }, + colorMode: { + defaultMode: 'light', + disableSwitch: false, + respectPrefersColorScheme: true, + }, + navbar: { + title: 'Site Title', + logo: { + alt: 'Site Logo', + src: 'img/logo.svg', + width: 32, + height: 32, + }, + items: [ + { + to: 'docs/docusaurus.config.js', + activeBasePath: 'docs', + label: 'docusaurus.config.js', + position: 'left', + }, + // ... other links + ], + }, + footer: { + style: 'dark', + links: [ + { + title: 'Docs', + items: [ + { + label: 'Docs', + to: 'docs/doc1', + }, + ], + }, + // ... other links + ], + logo: { + alt: 'Meta Open Source Logo', + src: 'img/meta_oss_logo.png', + href: 'https://opensource.fb.com', + width: 160, + height: 51, + }, + copyright: `Copyright © ${new Date().getFullYear()} Facebook, Inc.`, // You can also put own HTML here + }, + }, +}; +``` + +### `plugins` {#plugins} + +- Type: `PluginConfig[]` + +```ts +type PluginConfig = string | [string, any] | PluginModule | [PluginModule, any]; +``` + +See [plugin method references](./plugin-methods/README.mdx) for the shape of a `PluginModule`. + +```js title="docusaurus.config.js" +export default { + plugins: [ + 'docusaurus-plugin-awesome', + ['docusuarus-plugin-confetti', {fancy: false}], + () => ({ + postBuild() { + console.log('Build finished'); + }, + }), + ], +}; +``` + +### `themes` {#themes} + +- Type: `PluginConfig[]` + +```js title="docusaurus.config.js" +export default { + themes: ['@docusaurus/theme-classic'], +}; +``` + +### `presets` {#presets} + +- Type: `PresetConfig[]` + +```ts +type PresetConfig = string | [string, any]; +``` + +```js title="docusaurus.config.js" +export default { + presets: [], +}; +``` + +### `markdown` {#markdown} + +The global Docusaurus Markdown config. + +- Type: `MarkdownConfig` + +```ts +type MarkdownPreprocessor = (args: { + filePath: string; + fileContent: string; +}) => string; + +type MDX1CompatOptions = + | boolean + | { + comments: boolean; + admonitions: boolean; + headingIds: boolean; + }; + +export type ParseFrontMatter = (params: { + filePath: string; + fileContent: string; + defaultParseFrontMatter: ParseFrontMatter; +}) => Promise<{ + frontMatter: {[key: string]: unknown}; + content: string; +}>; + +type MarkdownAnchorsConfig = { + maintainCase: boolean; +}; + +type MarkdownConfig = { + format: 'mdx' | 'md' | 'detect'; + mermaid: boolean; + preprocessor?: MarkdownPreprocessor; + parseFrontMatter?: ParseFrontMatter; + mdx1Compat: MDX1CompatOptions; + remarkRehypeOptions: object; // see https://github.com/remarkjs/remark-rehype#options + anchors: MarkdownAnchorsConfig; +}; +``` + +Example: + +```js title="docusaurus.config.js" +export default { + markdown: { + format: 'mdx', + mermaid: true, + preprocessor: ({filePath, fileContent}) => { + return fileContent.replaceAll('{{MY_VAR}}', 'MY_VALUE'); + }, + parseFrontMatter: async (params) => { + const result = await params.defaultParseFrontMatter(params); + result.frontMatter.description = + result.frontMatter.description?.replaceAll('{{MY_VAR}}', 'MY_VALUE'); + return result; + }, + mdx1Compat: { + comments: true, + admonitions: true, + headingIds: true, + }, + anchors: { + maintainCase: true, + }, + }, +}; +``` + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `format` | `'mdx' \| 'md' \| 'detect'` | `'mdx'` | The default parser format to use for Markdown content. Using 'detect' will select the appropriate format automatically based on file extensions: `.md` vs `.mdx`. | +| `mermaid` | `boolean` | `false` | When `true`, allows Docusaurus to render Markdown code blocks with `mermaid` language as Mermaid diagrams. | +| `preprocessor` | `MarkdownPreprocessor` | `undefined` | Gives you the ability to alter the Markdown content string before parsing. Use it as a last-resort escape hatch or workaround: it is almost always better to implement a Remark/Rehype plugin. | +| `parseFrontMatter` | `ParseFrontMatter` | `undefined` | Gives you the ability to provide your own front matter parser, or to enhance the default parser. Read our [front matter guide](../guides/markdown-features/markdown-features-intro.mdx#front-matter) for details. | +| `mdx1Compat` | `MDX1CompatOptions` | `{comments: true, admonitions: true, headingIds: true}` | Compatibility options to make it easier to upgrade to Docusaurus v3+. | +| `anchors` | `MarkdownAnchorsConfig` | `{maintainCase: false}` | Options to control the behavior of anchors generated from Markdown headings | +| `remarkRehypeOptions` | `object` | `undefined` | Makes it possible to pass custom [`remark-rehype` options](https://github.com/remarkjs/remark-rehype#options). | + +```mdx-code-block +</APITable> +``` + +### `customFields` {#customFields} + +Docusaurus guards `docusaurus.config.js` from unknown fields. To add a custom field, define it on `customFields`. + +- Type: `Object` + +```js title="docusaurus.config.js" +export default { + customFields: { + admin: 'endi', + superman: 'lol', + }, +}; +``` + +Attempting to add unknown fields in the config will lead to errors during build time: + +```bash +Error: The field(s) 'foo', 'bar' are not recognized in docusaurus.config.js +``` + +### `staticDirectories` {#staticDirectories} + +An array of paths, relative to the site's directory or absolute. Files under these paths will be copied to the build output as-is. + +- Type: `string[]` + +Example: + +```js title="docusaurus.config.js" +export default { + staticDirectories: ['static'], +}; +``` + +### `headTags` {#headTags} + +An array of tags that will be inserted in the HTML `<head>`. The values must be objects that contain two properties; `tagName` and `attributes`. `tagName` must be a string that determines the tag being created; eg `"link"`. `attributes` must be an attribute-value map. + +- Type: `{ tagName: string; attributes: Object; }[]` + +Example: + +```js title="docusaurus.config.js" +export default { + headTags: [ + { + tagName: 'link', + attributes: { + rel: 'icon', + href: '/img/docusaurus.png', + }, + }, + ], +}; +``` + +This would become `<link rel="icon" href="img/docusaurus.png" />` in the generated HTML. + +### `scripts` {#scripts} + +An array of scripts to load. The values can be either strings or plain objects of attribute-value maps. The `<script>` tags will be inserted in the HTML `<head>`. If you use a plain object, the only required attribute is `src`, and any other attributes are permitted (each one should have boolean/string values). + +Note that `<script>` added here are render-blocking, so you might want to add `async: true`/`defer: true` to the objects. + +- Type: `(string | Object)[]` + +Example: + +```js title="docusaurus.config.js" +export default { + scripts: [ + // String format. + 'https://docusaurus.io/script.js', + // Object format. + { + src: 'https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js', + async: true, + }, + ], +}; +``` + +### `stylesheets` {#stylesheets} + +An array of CSS sources to load. The values can be either strings or plain objects of attribute-value maps. The `<link>` tags will be inserted in the HTML `<head>`. If you use an object, the only required attribute is `href`, and any other attributes are permitted (each one should have boolean/string values). + +- Type: `(string | Object)[]` + +Example: + +```js title="docusaurus.config.js" +export default { + stylesheets: [ + // String format. + 'https://docusaurus.io/style.css', + // Object format. + { + href: 'http://mydomain.com/style.css', + }, + ], +}; +``` + +:::info + +By default, the `<link>` tags will have `rel="stylesheet"`, but you can explicitly add a custom `rel` value to inject any kind of `<link>` tag, not necessarily stylesheets. + +::: + +### `clientModules` {#clientModules} + +An array of [client modules](../advanced/client.mdx#client-modules) to load globally on your site. + +Example: + +```js title="docusaurus.config.js" +export default { + clientModules: ['./mySiteGlobalJs.js', './mySiteGlobalCss.css'], +}; +``` + +### `ssrTemplate` {#ssrTemplate} + +An HTML template written in [Eta's syntax](https://eta.js.org/docs/syntax#syntax-overview) that will be used to render your application. This can be used to set custom attributes on the `body` tags, additional `meta` tags, customize the `viewport`, etc. Please note that Docusaurus will rely on the template to be correctly structured in order to function properly, once you do customize it, you will have to make sure that your template is compliant with the requirements from upstream. + +- Type: `string` + +Example: + +```js title="docusaurus.config.js" +export default { + ssrTemplate: `<!DOCTYPE html> +<html <%~ it.htmlAttributes %>> + <head> + <meta charset="UTF-8"> + <meta name="generator" content="Docusaurus v<%= it.version %>"> + <% it.metaAttributes.forEach((metaAttribute) => { %> + <%~ metaAttribute %> + <% }); %> + <%~ it.headTags %> + <% it.stylesheets.forEach((stylesheet) => { %> + <link rel="stylesheet" href="<%= it.baseUrl %><%= stylesheet %>" /> + <% }); %> + <% it.scripts.forEach((script) => { %> + <link rel="preload" href="<%= it.baseUrl %><%= script %>" as="script"> + <% }); %> + </head> + <body <%~ it.bodyAttributes %>> + <%~ it.preBodyTags %> + <div id="__docusaurus"> + <%~ it.appHtml %> + </div> + <% it.scripts.forEach((script) => { %> + <script src="<%= it.baseUrl %><%= script %>"></script> + <% }); %> + <%~ it.postBodyTags %> + </body> +</html>`, +}; +``` + +### `titleDelimiter` {#titleDelimiter} + +- Type: `string` + +Will be used as title delimiter in the generated `<title>` tag. + +Example: + +```js title="docusaurus.config.js" +export default { + titleDelimiter: '🦖', // Defaults to `|` +}; +``` + +### `baseUrlIssueBanner` {#baseUrlIssueBanner} + +- Type: `boolean` + +When enabled, will show a banner in case your site can't load its CSS or JavaScript files, which is a very common issue, often related to a wrong `baseUrl` in site config. + +Example: + +```js title="docusaurus.config.js" +export default { + baseUrlIssueBanner: true, // Defaults to `true` +}; +``` + +![A sample base URL issue banner. The style is very raw since the stylesheets failed to load. The text says "Your Docusaurus site did not load properly... Current configured baseUrl = / (default value); We suggest trying baseUrl = /build/](/img/baseUrlIssueBanner.png) + +:::warning + +This banner needs to inline CSS / JS in case all asset loading fails due to wrong base URL. + +If you have a strict [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), you should rather disable it. + +::: diff --git a/website/versioned_docs/version-3.7.0/api/misc/_category_.yml b/website/versioned_docs/version-3.7.0/api/misc/_category_.yml new file mode 100644 index 0000000000..2fb3073764 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/misc/_category_.yml @@ -0,0 +1,2 @@ +label: Miscellaneous +position: 4 diff --git a/website/versioned_docs/version-3.7.0/api/misc/create-docusaurus.mdx b/website/versioned_docs/version-3.7.0/api/misc/create-docusaurus.mdx new file mode 100644 index 0000000000..c79540e564 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/misc/create-docusaurus.mdx @@ -0,0 +1,58 @@ +--- +sidebar_position: 0 +slug: /api/misc/create-docusaurus +--- + +# 📦 create-docusaurus + +A scaffolding utility to help you instantly set up a functional Docusaurus app. + +## Usage {#usage} + +```bash +npx create-docusaurus@latest [name] [template] [rootDir] +``` + +The `name` argument will be used as the site's path as well as the `name` field in the created app's package.json. It can be an absolute path, or a path relative to `rootDir`. + +The `template` argument can be one of the following: + +- `classic`: Uses the classic template (recommended) +- `facebook`: Uses the Facebook/Meta template, which contains some Meta-specific setup +- A git repo URL (beginning with `https://` or `git@`), which can be cloned to the destination +- A local file path relative to CWD, which contains the files to be copied to destination + +The `rootDir` will be used to resolve the absolute path to the site directory. The default is CWD. + +:::warning + +This command should be preferably used in an interactive shell so all features are available. + +::: + +## Options {#options} + +### `-t, --typescript` {#typescript} + +Used when the template argument is a recognized name. Currently, only `classic` provides a TypeScript variant. + +### `-g, --git-strategy` {#git-strategy} + +Used when the template argument is a git repo. It needs to be one of: + +- `deep`: preserves full git history +- `shallow`: clones with `--depth=1` +- `copy`: does a shallow clone, but does not create a git repo +- `custom`: enter your custom git clone command. We will prompt you for it. You can write something like `git clone --depth 10`, and we will append the repository URL and destination directory. + +### `-p, --package-manager` {#package-manager} + +Value should be one of `npm`, `yarn`, `pnpm`, or `bun`. If it's not explicitly provided, Docusaurus will infer one based on: + +- The lockfile already present in the CWD (e.g. if you are setting up website in an existing project) +- The command used to invoke `create-docusaurus` (e.g. `npm init`, `npx`, `yarn create`, `bunx`, etc.) +- Interactive prompting, in case all heuristics are not present + +### `-s, --skip-install` {#skip-install} + +If provided, Docusaurus will not automatically install dependencies after creating the app. The `--package-manager` option is only useful when you are actually installing dependencies. diff --git a/website/versioned_docs/version-3.7.0/api/misc/eslint-plugin/README.mdx b/website/versioned_docs/version-3.7.0/api/misc/eslint-plugin/README.mdx new file mode 100644 index 0000000000..a0d41ee4d4 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/misc/eslint-plugin/README.mdx @@ -0,0 +1,74 @@ +--- +sidebar_position: 1 +slug: /api/misc/@docusaurus/eslint-plugin +--- + +# 📦 eslint-plugin + +[ESLint](https://eslint.org/) is a tool that statically analyzes your code and reports problems or suggests best practices through editor hints and command line. Docusaurus provides an ESLint plugin to enforce best Docusaurus practices. + +## Installation + +```bash npm2yarn +npm install --save-dev @docusaurus/eslint-plugin +``` + +## Usage + +### Recommended config + +Add `plugin:@docusaurus/recommended` to the `extends` section of your `.eslintrc` configuration file: + +```json title=".eslintrc" +{ + "extends": ["plugin:@docusaurus/recommended"] +} +``` + +This will enable the `@docusaurus` eslint plugin and use the `recommended` config. See [Supported rules](#supported-rules) below for a list of rules that this will enable. + +### Manual config + +For more fine-grained control, you can also enable the plugin manually and configure the rules you want to use directly: + +```json title=".eslintrc" +{ + "plugins": ["@docusaurus"], + "rules": { + "@docusaurus/string-literal-i18n-messages": "error", + "@docusaurus/no-untranslated-text": "warn" + } +} +``` + +## Supported configs + +- Recommended: recommended rule set for most Docusaurus sites that should be extended from. +- All: **all** rules enabled. This will change between minor versions, so you should not use this if you want to avoid unexpected breaking changes. + +## Supported rules + +| Name | Description | | +| --- | --- | --- | +| [`@docusaurus/no-untranslated-text`](./no-untranslated-text.mdx) | Enforce text labels in JSX to be wrapped by translate calls | | +| [`@docusaurus/string-literal-i18n-messages`](./string-literal-i18n-messages.mdx) | Enforce translate APIs to be called on plain text labels | ✅ | +| [`@docusaurus/no-html-links`](./no-html-links.mdx) | Ensures @docusaurus/Link is used instead of `<a>` tags | ✅ | +| [`@docusaurus/prefer-docusaurus-heading`](./prefer-docusaurus-heading.mdx) | Ensures @theme/Heading is used instead of `<hn>` tags for headings | ✅ | + +✅ = recommended + +## Example configuration + +Here's an example configuration: + +```js title=".eslintrc.js" +module.exports = { + extends: ['plugin:@docusaurus/recommended'], + rules: { + '@docusaurus/no-untranslated-text': [ + 'warn', + {ignoredStrings: ['·', '—', '×']}, + ], + }, +}; +``` diff --git a/website/versioned_docs/version-3.7.0/api/misc/eslint-plugin/no-html-links.mdx b/website/versioned_docs/version-3.7.0/api/misc/eslint-plugin/no-html-links.mdx new file mode 100644 index 0000000000..2c01a5c114 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/misc/eslint-plugin/no-html-links.mdx @@ -0,0 +1,47 @@ +--- +slug: /api/misc/@docusaurus/eslint-plugin/no-html-links +--- + +# no-html-links + +import APITable from '@site/src/components/APITable'; + +Ensure that the Docusaurus [`<Link>`](../../../docusaurus-core.mdx#link) component is used instead of `<a>` tags. + +The `<Link>` component has prefetching and preloading built-in. It also does build-time broken link detection, and helps Docusaurus understand your site's structure better. + +## Rule Details {#details} + +Examples of **incorrect** code for this rule: + +```html +<a href="/page">go to page!</a> + +<a href="https://x.com/docusaurus" target="_blank">X</a> +``` + +Examples of **correct** code for this rule: + +```js +import Link from '@docusaurus/Link' + +<Link to="/page">go to page!</Link> + +<Link to="https://x.com/docusaurus">X</Link> +``` + +## Rule Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `ignoreFullyResolved` | `boolean` | `false` | Set to true will not report any `<a>` tags with absolute URLs including a protocol. | + +```mdx-code-block +</APITable> +``` diff --git a/website/versioned_docs/version-3.7.0/api/misc/eslint-plugin/no-untranslated-text.mdx b/website/versioned_docs/version-3.7.0/api/misc/eslint-plugin/no-untranslated-text.mdx new file mode 100644 index 0000000000..589d90e4a2 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/misc/eslint-plugin/no-untranslated-text.mdx @@ -0,0 +1,54 @@ +--- +slug: /api/misc/@docusaurus/eslint-plugin/no-untranslated-text +--- + +# no-untranslated-text + +import APITable from '@site/src/components/APITable'; + +Enforce text labels in JSX to be wrapped by translate calls. + +When the [i18n feature](../../../i18n/i18n-introduction.mdx) is used, this rule ensures that all labels appearing on the website are translatable, so no string accidentally slips through untranslated. + +## Rule Details {#details} + +Examples of **incorrect** code for this rule: + +```js +// Hello World is not translated +<Component>Hello World</Component> +``` + +Examples of **correct** code for this rule: + +```js +// Hello World is translated +<Component> + <Translate>Hello World</Translate> +</Component> +``` + +## Rule Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `ignoredStrings` | `string[]` | `[]` | Text labels that only contain strings in this list will not be reported. | + +```mdx-code-block +</APITable> +``` + +## When Not To Use It {#when-not-to-use} + +If you're not using the [i18n feature](../../../i18n/i18n-introduction.mdx), you can disable this rule. You can also disable this rule where the text is not supposed to be translated. + +## Further Reading {#further-reading} + +- https://docusaurus.io/docs/docusaurus-core#translate +- https://docusaurus.io/docs/docusaurus-core#translate-imperative diff --git a/website/versioned_docs/version-3.7.0/api/misc/eslint-plugin/prefer-docusaurus-heading.mdx b/website/versioned_docs/version-3.7.0/api/misc/eslint-plugin/prefer-docusaurus-heading.mdx new file mode 100644 index 0000000000..e1d758898d --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/misc/eslint-plugin/prefer-docusaurus-heading.mdx @@ -0,0 +1,31 @@ +--- +slug: /api/misc/@docusaurus/eslint-plugin/prefer-docusaurus-heading +--- + +# prefer-docusaurus-heading + +Ensures that the `@theme/Heading` theme component provided by Docusaurus [`theme-classic`](../../themes/theme-classic.mdx) is used instead of `<hn>` tags for headings. + +## Rule Details {#details} + +Examples of **incorrect** code for this rule: + +```html +<h1>This is heading 1</h1> + +<h2>This is heading 2</h2> + +<h3>This is heading 3</h3> +``` + +Examples of **correct** code for this rule: + +```javascript +import Heading from '@theme/Heading' + +<Heading as='h1'>This is heading 1</Heading> + +<Heading as='h2'>This is heading 2</Heading> + +<Heading as='h3'>This is heading 3</Heading> +``` diff --git a/website/versioned_docs/version-3.7.0/api/misc/eslint-plugin/string-literal-i18n-messages.mdx b/website/versioned_docs/version-3.7.0/api/misc/eslint-plugin/string-literal-i18n-messages.mdx new file mode 100644 index 0000000000..0d5fb2f53d --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/misc/eslint-plugin/string-literal-i18n-messages.mdx @@ -0,0 +1,50 @@ +--- +slug: /api/misc/@docusaurus/eslint-plugin/string-literal-i18n-messages +--- + +# string-literal-i18n-messages + +Enforce translate APIs to be called on plain text labels. + +Docusaurus offers the [`docusaurus write-translations`](../../../cli.mdx#docusaurus-write-translations-sitedir) API, which statically extracts the text labels marked as translatable. Dynamic values used in `<Translate>` or `translate()` calls will fail to be extracted. This rule will ensure that all translate calls are statically extractable. + +## Rule Details {#details} + +Examples of **incorrect** code for this rule: + +```js +const text = 'Some text to be translated' + +// Invalid <Translate> child +<Translate>{text}</Translate> + +// Invalid message attribute +translate({message: text}) +``` + +Examples of **correct** code for this rule: + +```js +// Valid <Translate> child +<Translate>Some text to be translated</Translate> + +// Valid message attribute +translate({message: 'Some text to be translated'}) + +// Valid <Translate> child using values object as prop +<Translate values={{firstName: 'Sébastien'}}> + {'Welcome, {firstName}! How are you?'} +</Translate> + +// Valid message attribute using values object as second argument +translate({message: 'The logo of site {siteName}'}, {siteName: 'Docusaurus'}) +``` + +## When Not To Use It {#when-not-to-use} + +If you're not using the [i18n feature](../../../i18n/i18n-introduction.mdx), you can disable this rule. + +## Further Reading {#further-reading} + +- https://docusaurus.io/docs/docusaurus-core#translate +- https://docusaurus.io/docs/docusaurus-core#translate-imperative diff --git a/website/versioned_docs/version-3.7.0/api/misc/logger/demo.png b/website/versioned_docs/version-3.7.0/api/misc/logger/demo.png new file mode 100644 index 0000000000..f387755210 Binary files /dev/null and b/website/versioned_docs/version-3.7.0/api/misc/logger/demo.png differ diff --git a/website/versioned_docs/version-3.7.0/api/misc/logger/logger.mdx b/website/versioned_docs/version-3.7.0/api/misc/logger/logger.mdx new file mode 100644 index 0000000000..4c0b37371e --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/misc/logger/logger.mdx @@ -0,0 +1,71 @@ +--- +sidebar_position: 2 +slug: /api/misc/@docusaurus/logger +--- + +# 📦 logger + +An encapsulated logger for semantically formatting console messages. + +Authors of packages in the Docusaurus ecosystem are encouraged to use this package to provide unified log formats. + +## APIs + +It exports a single object as default export: `logger`. `logger` has the following properties: + +- Some useful colors. + - `red` + - `yellow` + - `green` + - `bold` + - `dim` +- Formatters. These functions all have the signature `(msg: unknown) => string`. Note that their implementations are not guaranteed. You should only care about their semantics. + - `path`: formats a file path. + - `url`: formats a URL. + - `name`: formats an identifier. + - `code`: formats a code snippet. + - `subdue`: subdues the text. + - `num`: formats a number. +- The `interpolate` function. It is a template literal tag. The syntax can be found below. +- Logging functions. All logging functions can both be used as normal functions (similar to the `console.log` family, but only accepts one parameter) or template literal tags. + - `info`: prints information. + - `warn`: prints a warning that should be paid attention to. + - `error`: prints an error (not necessarily halting the program) that signals significant problems. + - `success`: prints a success message. +- The `report` function. It takes a `ReportingSeverity` value (`ignore`, `log`, `warn`, `throw`) and reports a message according to the severity. + +:::warning A word on the `error` formatter + +Beware that an `error` message, even when it doesn't hang the program, is likely going to cause confusion. When users inspect logs and find an `[ERROR]`, even when the build succeeds, they will assume something is going wrong. Use it sparingly. + +Docusaurus only uses `logger.error` when printing messages immediately before throwing an error, or when user has set the reporting severity of `onBrokenLink`, etc. to `"error"`. + +In addition, `warn` and `error` will color the **entire** message for better attention. If you are printing large blocks of help text about an error, better use `logger.info`. + +::: + +### Using the template literal tag + +The template literal tag evaluates the template and expressions embedded. `interpolate` returns a new string, while other logging functions prints it. Below is a typical usage: + +```js +import logger from '@docusaurus/logger'; + +logger.info`Hello name=${name}! You have number=${money} dollars. Here are the ${ + items.length > 1 ? 'items' : 'item' +} on the shelf: ${items} +To buy anything, enter code=${'buy x'} where code=${'x'} is the item's name; to quit, press code=${'Ctrl + C'}.`; +``` + +An embedded expression is optionally preceded by a flag in the form `[a-z]+=` (a few lowercase letters, followed by an equals sign, directly preceding the embedded expression). If the expression is not preceded by any flag, it's printed out as-is. Otherwise, it's formatted with one of the formatters: + +- `path=`: `path` +- `url=`: `url` +- `name=`: `name` +- `code=`: `code` +- `subdue=`: `subdue` +- `number=`: `num` + +If the expression is an array, it's formatted by `` `\n- ${array.join('\n- ')}\n` `` (note it automatically gets a leading line end). Each member is formatted by itself and the bullet is not formatted. So you would see the above message printed as: + +![Some text output in the terminal, containing array, code, name, and number formatting](./demo.png) diff --git a/website/versioned_docs/version-3.7.0/api/plugin-methods/README.mdx b/website/versioned_docs/version-3.7.0/api/plugin-methods/README.mdx new file mode 100644 index 0000000000..e25bc9246e --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugin-methods/README.mdx @@ -0,0 +1,144 @@ +# Plugin Method References + +:::warning + +This section is a work in progress. Anchor links or even URLs are not guaranteed to be stable. + +::: + +Plugin APIs are shared by themes and plugins—themes are loaded just like plugins. + +## Plugin module {#plugin-module} + +Every plugin is imported as a module. The module is expected to have the following members: + +- A **default export**: the constructor function for the plugin. +- **Named exports**: the [static methods](./static-methods.mdx) called before plugins are initialized. + +## Plugin constructor {#plugin-constructor} + +The plugin module's default export is a constructor function with the signature `(context: LoadContext, options: PluginOptions) => Plugin | Promise<Plugin>`. + +### `context` {#context} + +`context` is plugin-agnostic, and the same object will be passed into all plugins used for a Docusaurus website. The `context` object contains the following fields: + +```ts +type LoadContext = { + siteDir: string; + generatedFilesDir: string; + siteConfig: DocusaurusConfig; + outDir: string; + baseUrl: string; +}; +``` + +### `options` {#options} + +`options` are the [second optional parameter when the plugins are used](../../using-plugins.mdx#configuring-plugins). `options` are plugin-specific and are specified by users when they use them in `docusaurus.config.js`. If there's a [`validateOptions`](./static-methods.mdx#validateOptions) function exported, the `options` will be validated and normalized beforehand. + +Alternatively, if a preset contains the plugin, the preset will then be in charge of passing the correct options into the plugin. It is up to the individual plugin to define what options it takes. + +## Example {#example} + +Here's a mental model for a presumptuous plugin implementation. + +```js +// A JavaScript function that returns an object. +// `context` is provided by Docusaurus. Example: siteConfig can be accessed from context. +// `opts` is the user-defined options. +export default async function myPlugin(context, opts) { + return { + // A compulsory field used as the namespace for directories to cache + // the intermediate data for each plugin. + // If you're writing your own local plugin, you will want it to + // be unique in order not to potentially conflict with imported plugins. + // A good way will be to add your own project name within. + name: 'docusaurus-my-project-cool-plugin', + + async loadContent() { + // The loadContent hook is executed after siteConfig and env has been loaded. + // You can return a JavaScript object that will be passed to contentLoaded hook. + }, + + async contentLoaded({content, actions}) { + // The contentLoaded hook is done after loadContent hook is done. + // `actions` are set of functional API provided by Docusaurus (e.g. addRoute) + }, + + async postBuild(props) { + // After docusaurus <build> finish. + }, + + // TODO + async postStart(props) { + // docusaurus <start> finish + }, + + // TODO + afterDevServer(app, server) { + // https://webpack.js.org/configuration/dev-server/#devserverbefore + }, + + // TODO + beforeDevServer(app, server) { + // https://webpack.js.org/configuration/dev-server/#devserverafter + }, + + configureWebpack(config, isServer, utils, content) { + // Modify internal webpack config. If returned value is an Object, it + // will be merged into the final config using webpack-merge; + // If the returned value is a function, it will receive the config as the 1st argument and an isServer flag as the 2nd argument. + }, + + getPathsToWatch() { + // Paths to watch. + }, + + getThemePath() { + // Returns the path to the directory where the theme components can + // be found. + }, + + getClientModules() { + // Return an array of paths to the modules that are to be imported + // in the client bundle. These modules are imported globally before + // React even renders the initial UI. + }, + + extendCli(cli) { + // Register an extra command to enhance the CLI of Docusaurus + }, + + injectHtmlTags({content}) { + // Inject head and/or body HTML tags. + }, + + async getTranslationFiles({content}) { + // Return translation files + }, + + translateContent({content, translationFiles}) { + // translate the plugin content here + }, + + translateThemeConfig({themeConfig, translationFiles}) { + // translate the site themeConfig here + }, + + async getDefaultCodeTranslationMessages() { + // return default theme translations here + }, + }; +} + +export function validateOptions({options, validate}) { + const validatedOptions = validate(myValidationSchema, options); + return validatedOptions; +} + +export function validateThemeConfig({themeConfig, validate}) { + const validatedThemeConfig = validate(myValidationSchema, options); + return validatedThemeConfig; +} +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugin-methods/_category_.yml b/website/versioned_docs/version-3.7.0/api/plugin-methods/_category_.yml new file mode 100644 index 0000000000..86cb36c246 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugin-methods/_category_.yml @@ -0,0 +1,2 @@ +label: Plugin method references +position: 1 diff --git a/website/versioned_docs/version-3.7.0/api/plugin-methods/extend-infrastructure.mdx b/website/versioned_docs/version-3.7.0/api/plugin-methods/extend-infrastructure.mdx new file mode 100644 index 0000000000..ec0b0542cf --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugin-methods/extend-infrastructure.mdx @@ -0,0 +1,132 @@ +--- +sidebar_position: 2 +--- + +# Extending infrastructure + +Docusaurus has some infrastructure like hot reloading, CLI, and swizzling, that can be extended by external plugins. + +## `getPathsToWatch()` {#getPathsToWatch} + +Specifies the paths to watch for plugins and themes. The paths are watched by the dev server so that the plugin lifecycles are reloaded when contents in the watched paths change. Note that the plugins and themes modules are initially called with `context` and `options` from Node, which you may use to find the necessary directory information about the site. + +Use this for files that are consumed server-side, because theme files are automatically watched by Webpack dev server. + +Example: + +```js title="docusaurus-plugin/src/index.js" +import path from 'path'; + +export default function (context, options) { + return { + name: 'docusaurus-plugin', + // highlight-start + getPathsToWatch() { + const contentPath = path.resolve(context.siteDir, options.path); + return [`${contentPath}/**/*.{ts,tsx}`]; + }, + // highlight-end + }; +} +``` + +## `extendCli(cli)` {#extendCli} + +Register an extra command to enhance the CLI of Docusaurus. `cli` is a [commander](https://www.npmjs.com/package/commander/v/5.1.0) object. + +:::warning + +The commander version matters! We use commander v5, and make sure you are referring to the right version documentation for available APIs. + +::: + +Example: + +```js title="docusaurus-plugin/src/index.js" +export default function (context, options) { + return { + name: 'docusaurus-plugin', + // highlight-start + extendCli(cli) { + cli + .command('roll') + .description('Roll a random number between 1 and 1000') + .action(() => { + console.log(Math.floor(Math.random() * 1000 + 1)); + }); + }, + // highlight-end + }; +} +``` + +## `getThemePath()` {#getThemePath} + +Returns the path to the directory where the theme components can be found. When your users call `swizzle`, `getThemePath` is called and its returned path is used to find your theme components. Relative paths are resolved against the folder containing the entry point. + +For example, your `getThemePath` can be: + +```js title="my-theme/src/index.js" +export default function (context, options) { + return { + name: 'my-theme', + // highlight-start + getThemePath() { + return './theme'; + }, + // highlight-end + }; +} +``` + +## `getTypeScriptThemePath()` {#getTypeScriptThemePath} + +Similar to `getThemePath()`, it should return the path to the directory where the source code of TypeScript theme components can be found. This path is purely for swizzling TypeScript theme components, and theme components under this path will **not** be resolved by Webpack. Therefore, it is not a replacement for `getThemePath()`. Typically, you can make the path returned by `getTypeScriptThemePath()` be your source directory, and make the path returned by `getThemePath()` be the compiled JavaScript output. + +:::tip + +For TypeScript theme authors: you are strongly advised to make your compiled output as human-readable as possible. Only strip type annotations and don't transpile any syntaxes, because they will be handled by Webpack's Babel loader based on the targeted browser versions. + +You should also format these files with Prettier. Remember—JS files can and will be directly consumed by your users. + +::: + +Example: + +```js title="my-theme/src/index.js" +export default function (context, options) { + return { + name: 'my-theme', + // highlight-start + getThemePath() { + // Where compiled JavaScript output lives + return '../lib/theme'; + }, + getTypeScriptThemePath() { + // Where TypeScript source code lives + return '../src/theme'; + }, + // highlight-end + }; +} +``` + +## `getSwizzleComponentList()` {#getSwizzleComponentList} + +**This is a static method, not attached to any plugin instance.** + +Returns a list of stable components that are considered safe for swizzling. These components will be swizzlable without `--danger`. All components are considered unstable by default. If an empty array is returned, all components are considered unstable. If `undefined` is returned, all components are considered stable. + +```js title="my-theme/src/index.js" +export function getSwizzleComponentList() { + return [ + 'CodeBlock', + 'DocSidebar', + 'Footer', + 'NotFound', + 'SearchBar', + 'hooks/useTheme', + 'prism-include-languages', + ]; +} +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugin-methods/i18n-lifecycles.mdx b/website/versioned_docs/version-3.7.0/api/plugin-methods/i18n-lifecycles.mdx new file mode 100644 index 0000000000..d9a6297569 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugin-methods/i18n-lifecycles.mdx @@ -0,0 +1,121 @@ +--- +sidebar_position: 3 +--- + +# I18n lifecycles + +Plugins use these lifecycles to load i18n-related data. + +## `getTranslationFiles({content})` {#getTranslationFiles} + +Plugins declare the JSON translation files they want to use. + +Returns translation files `{path: string, content: ChromeI18nJSON}`: + +- `path`: relative to the plugin localized folder `i18n/[locale]/[pluginName]`. Extension `.json` should be omitted to remain generic. +- `content`: using the Chrome i18n JSON format. + +These files will be written by the [`write-translations` CLI](../../cli.mdx#docusaurus-write-translations-sitedir) to the plugin i18n subfolder, and will be read in the appropriate locale before calling [`translateContent()`](#translateContent) and [`translateThemeConfig()`](#translateThemeConfig) + +Example: + +```js title="my-plugin.js" +export default function (context, options) { + return { + name: 'my-plugin', + // highlight-start + async getTranslationFiles({content}) { + return [ + { + path: 'sidebar-labels', + content: { + someSidebarLabel: { + message: 'Some Sidebar Label', + description: 'A label used in my plugin in the sidebar', + }, + someLabelFromContent: content.myLabel, + }, + }, + ]; + }, + // highlight-end + }; +} +``` + +## `translateContent({content,translationFiles})` {#translateContent} + +Translate the plugin content, using the localized translation files. + +Returns the localized plugin content. + +The `contentLoaded()` lifecycle will be called with the localized plugin content returned by `translateContent()`. + +Example: + +```js title="my-plugin.js" +export default function (context, options) { + return { + name: 'my-plugin', + // highlight-start + translateContent({content, translationFiles}) { + const myTranslationFile = translationFiles.find( + (f) => f.path === 'myTranslationFile', + ); + return { + ...content, + someContentLabel: myTranslationFile.someContentLabel.message, + }; + }, + // highlight-end + }; +} +``` + +## `translateThemeConfig({themeConfig,translationFiles})` {#translateThemeConfig} + +Translate the site `themeConfig` labels, using the localized translation files. + +Returns the localized `themeConfig`. + +Example: + +```js title="my-plugin.js" +export default function (context, options) { + return { + name: 'my-theme', + // highlight-start + translateThemeConfig({themeConfig, translationFiles}) { + const myTranslationFile = translationFiles.find( + (f) => f.path === 'myTranslationFile', + ); + return { + ...themeConfig, + someThemeConfigLabel: myTranslationFile.someThemeConfigLabel.message, + }; + }, + // highlight-end + }; +} +``` + +## `async getDefaultCodeTranslationMessages()` {#getDefaultCodeTranslationMessages} + +Themes using the `<Translate>` API can provide default code translation messages. + +It should return messages in `Record<string, string>`, where keys are translation IDs and values are messages (without the description) localized using the site's current locale. + +Example: + +```js title="my-plugin.js" +export default function (context, options) { + return { + name: 'my-theme', + // highlight-start + async getDefaultCodeTranslationMessages() { + return readJsonFile(`${context.i18n.currentLocale}.json`); + }, + // highlight-end + }; +} +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugin-methods/lifecycle-apis.mdx b/website/versioned_docs/version-3.7.0/api/plugin-methods/lifecycle-apis.mdx new file mode 100644 index 0000000000..4606eb6775 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugin-methods/lifecycle-apis.mdx @@ -0,0 +1,492 @@ +--- +sidebar_position: 1 +toc_max_heading_level: 4 +--- + +# Lifecycle APIs + +During the build, plugins are loaded in parallel to fetch their own contents and render them to routes. Plugins may also configure webpack or post-process the generated files. + +## `async loadContent()` {#loadContent} + +Plugins should use this lifecycle to fetch from data sources (filesystem, remote API, headless CMS, etc.) or do some server processing. The return value is the content it needs. + +For example, this plugin below returns a random integer between 1 and 10 as content. + +```js title="docusaurus-plugin/src/index.js" +export default function (context, options) { + return { + name: 'docusaurus-plugin', + // highlight-start + async loadContent() { + return 1 + Math.floor(Math.random() * 10); + }, + // highlight-end + }; +} +``` + +## `async contentLoaded({content, actions})` {#contentLoaded} + +The data that was loaded in `loadContent` will be consumed in `contentLoaded`. It can be rendered to routes, registered as global data, etc. + +### `content` {#content} + +`contentLoaded` will be called _after_ `loadContent` is done. The return value of `loadContent()` will be passed to `contentLoaded` as `content`. + +### `actions` {#actions} + +`actions` contain three functions: + +#### `addRoute(config: RouteConfig): void` {#addRoute} + +Create a route to add to the website. + +```ts +export type RouteConfig = { + /** + * With leading slash. Trailing slash will be normalized by config. + */ + path: string; + /** + * Component used to render this route, a path that the bundler can `require`. + */ + component: string; + /** + * Props. Each entry should be `[propName]: pathToPropModule` (created with + * `createData`) + */ + modules?: RouteModules; + /** + * The route context will wrap the `component`. Use `useRouteContext` to + * retrieve what's declared here. Note that all custom route context declared + * here will be namespaced under {@link RouteContext.data}. + */ + context?: RouteModules; + /** + * Nested routes config, useful for "layout routes" having subroutes. + */ + routes?: RouteConfig[]; + /** + * React router config option: `exact` routes would not match subroutes. + */ + exact?: boolean; + /** + * React router config option: `strict` routes are sensitive to the presence + * of a trailing slash. + */ + strict?: boolean; + /** + * Used to sort routes. + * Higher-priority routes will be matched first. + */ + priority?: number; + /** + * Optional route metadata + */ + metadata?: RouteMetadata; + /** + * Extra props; will be available on the client side. + */ + [propName: string]: unknown; +}; + +/** + * Plugin authors can assign extra metadata to the created routes + * It is only available on the Node.js side, and not sent to the browser + * Optional: plugin authors are encouraged but not required to provide it + * + * Some plugins might use this data to provide additional features. + * This is the case of the sitemap plugin to provide support for "lastmod". + * See also: https://github.com/facebook/docusaurus/pull/9954 + */ +export type RouteMetadata = { + /** + * The source code file path that led to the creation of the current route + * In official content plugins, this is usually a Markdown or React file + * This path is expected to be relative to the site directory + */ + sourceFilePath?: string; + /** + * The last updated date of this route + * This is generally read from the Git history of the sourceFilePath + * but can also be provided through other means (usually front matter) + * + * This has notably been introduced for adding "lastmod" support to the + * sitemap plugin, see https://github.com/facebook/docusaurus/pull/9954 + */ + lastUpdatedAt?: number; +}; + +type RouteModules = { + [module: string]: Module | RouteModules | RouteModules[]; +}; + +type Module = + | { + path: string; + __import?: boolean; + query?: ParsedUrlQueryInput; + } + | string; +``` + +#### `createData(name: string, data: any): Promise<string>` {#createData} + +A declarative callback to create static data (generally JSON or string) which can later be provided to your routes as props. Takes the file name and data to be stored, and returns the actual data file's path. + +For example, this plugin below creates a `/friends` page which displays `Your friends are: Yangshun, Sebastien`: + +```jsx title="website/src/components/Friends.js" +import React from 'react'; + +export default function FriendsComponent({friends}) { + return <div>Your friends are {friends.join(',')}</div>; +} +``` + +```js title="docusaurus-friends-plugin/src/index.js" +export default function friendsPlugin(context, options) { + return { + name: 'docusaurus-friends-plugin', + // highlight-start + async contentLoaded({content, actions}) { + const {createData, addRoute} = actions; + // Create friends.json + const friends = ['Yangshun', 'Sebastien']; + const friendsJsonPath = await createData( + 'friends.json', + JSON.stringify(friends), + ); + + // Add the '/friends' routes, and ensure it receives the friends props + addRoute({ + path: '/friends', + component: '@site/src/components/Friends.js', + modules: { + // propName -> JSON file path + friends: friendsJsonPath, + }, + exact: true, + }); + }, + // highlight-end + }; +} +``` + +#### `setGlobalData(data: any): void` {#setGlobalData} + +This function permits one to create some global plugin data that can be read from any page, including the pages created by other plugins, and your theme layout. + +This data becomes accessible to your client-side/theme code through the [`useGlobalData`](../../docusaurus-core.mdx#useGlobalData) and [`usePluginData`](../../docusaurus-core.mdx#usePluginData) hooks. + +:::warning + +Global data is... global: its size affects the loading time of all pages of your site, so try to keep it small. Prefer `createData` and page-specific data whenever possible. + +::: + +For example, this plugin below creates a `/friends` page which displays `Your friends are: Yangshun, Sebastien`: + +```jsx title="website/src/components/Friends.js" +import React from 'react'; +import {usePluginData} from '@docusaurus/useGlobalData'; + +export default function FriendsComponent() { + const {friends} = usePluginData('docusaurus-friends-plugin'); + return <div>Your friends are {friends.join(',')}</div>; +} +``` + +```js title="docusaurus-friends-plugin/src/index.js" +export default function friendsPlugin(context, options) { + return { + name: 'docusaurus-friends-plugin', + // highlight-start + async contentLoaded({content, actions}) { + const {setGlobalData, addRoute} = actions; + // Create friends global data + setGlobalData({friends: ['Yangshun', 'Sebastien']}); + + // Add the '/friends' routes + addRoute({ + path: '/friends', + component: '@site/src/components/Friends.js', + exact: true, + }); + }, + // highlight-end + }; +} +``` + +## `configureWebpack(config, isServer, utils, content)` {#configureWebpack} + +Modifies the internal webpack config. If the return value is a JavaScript object, it will be merged into the final config using [`webpack-merge`](https://github.com/survivejs/webpack-merge). If it is a function, it will be called and receive `config` as the first argument and an `isServer` flag as the second argument. + +:::warning + +The API of `configureWebpack` will be modified in the future to accept an object (`configureWebpack({config, isServer, utils, content})`) + +::: + +### `config` {#config} + +`configureWebpack` is called with `config` generated according to client/server build. You may treat this as the base config to be merged with. + +### `isServer` {#isServer} + +`configureWebpack` will be called both in server build and in client build. The server build receives `true` and the client build receives `false` as `isServer`. + +### `utils` {#utils} + +`configureWebpack` also receives an util object: + +- `getStyleLoaders(isServer: boolean, cssOptions: {[key: string]: any}): Loader[]` +- `getJSLoader(isServer: boolean, cacheOptions?: {}): Loader | null` + +You may use them to return your webpack configuration conditionally. + +For example, this plugin below modify the webpack config to transpile `.foo` files. + +```js title="docusaurus-plugin/src/index.js" +export default function (context, options) { + return { + name: 'custom-docusaurus-plugin', + // highlight-start + configureWebpack(config, isServer, utils) { + const {getJSLoader} = utils; + return { + module: { + rules: [ + { + test: /\.foo$/, + use: [getJSLoader(isServer), 'my-custom-webpack-loader'], + }, + ], + }, + }; + }, + // highlight-end + }; +} +``` + +### `content` {#content-1} + +`configureWebpack` will be called both with the content loaded by the plugin. + +### Merge strategy {#merge-strategy} + +We merge the Webpack configuration parts of plugins into the global Webpack config using [webpack-merge](https://github.com/survivejs/webpack-merge). + +It is possible to specify the merge strategy. For example, if you want a webpack rule to be prepended instead of appended: + +```js title="docusaurus-plugin/src/index.js" +export default function (context, options) { + return { + name: 'custom-docusaurus-plugin', + configureWebpack(config, isServer, utils) { + return { + // highlight-start + mergeStrategy: {'module.rules': 'prepend'}, + module: {rules: [myRuleToPrepend]}, + // highlight-end + }; + }, + }; +} +``` + +Read the [webpack-merge strategy doc](https://github.com/survivejs/webpack-merge#merging-with-strategies) for more details. + +### Configuring dev server {#configuring-dev-server} + +The dev server can be configured through returning a `devServer` field. + +```js title="docusaurus-plugin/src/index.js" +export default function (context, options) { + return { + name: 'custom-docusaurus-plugin', + configureWebpack(config, isServer, utils) { + return { + // highlight-start + devServer: { + open: '/docs', // Opens localhost:3000/docs instead of localhost:3000/ + }, + // highlight-end + }; + }, + }; +} +``` + +## `configurePostCss(options)` {#configurePostCss} + +Modifies [`postcssOptions` of `postcss-loader`](https://webpack.js.org/loaders/postcss-loader/#postcssoptions) during the generation of the client bundle. + +Should return the mutated `postcssOptions`. + +By default, `postcssOptions` looks like this: + +```js +const postcssOptions = { + ident: 'postcss', + plugins: [require('autoprefixer')], +}; +``` + +Example: + +```js title="docusaurus-plugin/src/index.js" +export default function (context, options) { + return { + name: 'docusaurus-plugin', + // highlight-start + configurePostCss(postcssOptions) { + // Appends new PostCSS plugin. + postcssOptions.plugins.push(require('postcss-import')); + return postcssOptions; + }, + // highlight-end + }; +} +``` + +## `postBuild(props)` {#postBuild} + +Called when a (production) build finishes. + +```ts +interface Props { + siteDir: string; + generatedFilesDir: string; + siteConfig: DocusaurusConfig; + outDir: string; + baseUrl: string; + headTags: string; + preBodyTags: string; + postBodyTags: string; + routesPaths: string[]; + plugins: Plugin<any>[]; + content: Content; +} +``` + +Example: + +```js title="docusaurus-plugin/src/index.js" +export default function (context, options) { + return { + name: 'docusaurus-plugin', + // highlight-start + async postBuild({siteConfig = {}, routesPaths = [], outDir}) { + // Print out to console all the rendered routes. + routesPaths.map((route) => { + console.log(route); + }); + }, + // highlight-end + }; +} +``` + +## `injectHtmlTags({content})` {#injectHtmlTags} + +Inject head and/or body HTML tags to Docusaurus generated HTML. + +`injectHtmlTags` will be called both with the content loaded by the plugin. + +```ts +function injectHtmlTags(): { + headTags?: HtmlTags; + preBodyTags?: HtmlTags; + postBodyTags?: HtmlTags; +}; + +type HtmlTags = string | HtmlTagObject | (string | HtmlTagObject)[]; + +type HtmlTagObject = { + /** + * Attributes of the HTML tag + * E.g. `{'disabled': true, 'value': 'demo', 'rel': 'preconnect'}` + */ + attributes?: { + [attributeName: string]: string | boolean; + }; + /** + * The tag name e.g. `div`, `script`, `link`, `meta` + */ + tagName: string; + /** + * The inner HTML + */ + innerHTML?: string; +}; +``` + +Example: + +```js title="docusaurus-plugin/src/index.js" +export default function (context, options) { + return { + name: 'docusaurus-plugin', + loadContent: async () => { + return {remoteHeadTags: await fetchHeadTagsFromAPI()}; + }, + // highlight-start + injectHtmlTags({content}) { + return { + headTags: [ + { + tagName: 'link', + attributes: { + rel: 'preconnect', + href: 'https://www.github.com', + }, + }, + ...content.remoteHeadTags, + ], + preBodyTags: [ + { + tagName: 'script', + attributes: { + charset: 'utf-8', + src: '/noflash.js', + }, + }, + ], + postBodyTags: [`<div> This is post body </div>`], + }; + }, + // highlight-end + }; +} +``` + +Tags will be added as follows: + +- `headTags` will be inserted before the closing `</head>` tag after scripts added by config. +- `preBodyTags` will be inserted after the opening `<body>` tag before any child elements. +- `postBodyTags` will be inserted before the closing `</body>` tag after all child elements. + +## `getClientModules()` {#getClientModules} + +Returns an array of paths to the [client modules](../../advanced/client.mdx#client-modules) that are to be imported into the client bundle. + +As an example, to make your theme load a `customCss` or `customJs` file path from `options` passed in by the user: + +```js title="my-theme/src/index.js" +export default function (context, options) { + const {customCss, customJs} = options || {}; + return { + name: 'name-of-my-theme', + // highlight-start + getClientModules() { + return [customCss, customJs]; + }, + // highlight-end + }; +} +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugin-methods/static-methods.mdx b/website/versioned_docs/version-3.7.0/api/plugin-methods/static-methods.mdx new file mode 100644 index 0000000000..1ae95185b3 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugin-methods/static-methods.mdx @@ -0,0 +1,83 @@ +--- +sidebar_position: 4 +--- + +# Static methods + +Static methods are not part of the plugin instance—they are attached to the constructor function. These methods are used to validate and normalize the plugin options and theme config, which are then used as constructor parameters to initialize the plugin instance. + +## `validateOptions({options, validate})` {#validateOptions} + +Returns validated and normalized options for the plugin. This method is called before the plugin is initialized. You must return the options since they will be passed to the plugin during initialization. + +### `options` {#options} + +`validateOptions` is called with `options` passed to plugin for validation and normalization. + +### `validate` {#validate} + +`validateOptions` is called with `validate` function which takes a **[Joi](https://www.npmjs.com/package/joi)** schema and options as the arguments, returns validated and normalized options. `validate` will automatically handle error and validation config. + +:::tip + +[Joi](https://www.npmjs.com/package/joi) is recommended for validation and normalization of options. + +To avoid mixing Joi versions, use `import {Joi} from '@docusaurus/utils-validation'` + +::: + +If you don't use **[Joi](https://www.npmjs.com/package/joi)** for validation you can throw an Error in case of invalid options and return options in case of success. + +```js title="my-plugin/src/index.js" +export default function myPlugin(context, options) { + return { + name: 'docusaurus-plugin', + // rest of methods + }; +} + +// highlight-start +export function validateOptions({options, validate}) { + const validatedOptions = validate(myValidationSchema, options); + return validatedOptions; +} +// highlight-end +``` + +## `validateThemeConfig({themeConfig, validate})` {#validateThemeConfig} + +Return validated and normalized configuration for the theme. + +### `themeConfig` {#themeConfig} + +`validateThemeConfig` is called with `themeConfig` provided in `docusaurus.config.js` for validation and normalization. + +### `validate` {#validate-1} + +`validateThemeConfig` is called with `validate` function which takes a **[Joi](https://www.npmjs.com/package/joi)** schema and `themeConfig` as the arguments, returns validated and normalized options. `validate` will automatically handle error and validation config. + +:::tip + +[Joi](https://www.npmjs.com/package/joi) is recommended for validation and normalization of theme config. + +To avoid mixing Joi versions, use `import {Joi} from '@docusaurus/utils-validation'` + +::: + +If you don't use **[Joi](https://www.npmjs.com/package/joi)** for validation you can throw an Error in case of invalid options. + +```js title="my-theme/src/index.js" +export default function myPlugin(context, options) { + return { + name: 'docusaurus-plugin', + // rest of methods + }; +} + +// highlight-start +export function validateThemeConfig({themeConfig, validate}) { + const validatedThemeConfig = validate(myValidationSchema, options); + return validatedThemeConfig; +} +// highlight-end +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugins/_category_.yml b/website/versioned_docs/version-3.7.0/api/plugins/_category_.yml new file mode 100644 index 0000000000..cffabddbd5 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/_category_.yml @@ -0,0 +1,5 @@ +label: Plugins +position: 2 +link: + type: doc + id: api/plugins/plugins-overview # Dogfood using a "qualified id" diff --git a/website/versioned_docs/version-3.7.0/api/plugins/_partial-tags-file-api-ref-section.mdx b/website/versioned_docs/version-3.7.0/api/plugins/_partial-tags-file-api-ref-section.mdx new file mode 100644 index 0000000000..f6d247c70f --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/_partial-tags-file-api-ref-section.mdx @@ -0,0 +1,54 @@ +## Tags File {#tags-file} + +Use the [`tags` plugin option](#tags) to configure the path of a YAML tags file. + +By convention, the plugin will look for a `tags.yml` file at the root of your content folder(s). + +This file can contain a list of predefined tags. You can reference these tags by their keys in Markdown files thanks to the [`tags` front matter](#markdown-front-matter). + +:::tip Keeping tags consistent + +Using a tags file, you can ensure that your tags usage is consistent across your plugin content set. Use the [`onInlineTags: 'throw'`](#onInlineTags) plugin option to enforce this consistency and prevent usage of inline tags declared on the fly. + +::: + +### Types {#tags-file-types} + +The YAML content of the provided tags file should respect the following shape: + +```tsx +type Tag = { + label?: string; // Tag display label + permalink?: string; // Tag URL pathname segment + description?: string; // Tag description displayed in the tag page +}; + +type TagsFileInput = Record<string, Partial<Tag> | null>; +``` + +### Example {#tags-file-example} + +```yml title="tags.yml" +releases: + label: 'Product releases' + permalink: '/product-releases' + description: 'Content related to product releases.' + +# A partial tag definition is also valid +announcements: + label: 'Announcements' + +# An empty tag definition is also valid +# Other attributes will be inferred from the key +emptyTag: +``` + +```md title="content.md" +--- +tags: [releases, announcements, emptyTag] +--- + +# Title + +Content +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugins/overview.mdx b/website/versioned_docs/version-3.7.0/api/plugins/overview.mdx new file mode 100644 index 0000000000..23eb708929 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/overview.mdx @@ -0,0 +1,33 @@ +--- +sidebar_position: 0 +id: plugins-overview +sidebar_label: Plugins overview +slug: /api/plugins +--- + +# Docusaurus plugins + +We provide official Docusaurus plugins. + +## Content plugins {#content-plugins} + +These plugins are responsible for loading your site's content, and creating pages for your theme to render. + +- [@docusaurus/plugin-content-docs](./plugin-content-docs.mdx) +- [@docusaurus/plugin-content-blog](./plugin-content-blog.mdx) +- [@docusaurus/plugin-content-pages](./plugin-content-pages.mdx) + +## Behavior plugins {#behavior-plugins} + +These plugins will add a useful behavior to your Docusaurus site. + +- [@docusaurus/plugin-debug](./plugin-debug.mdx) +- [@docusaurus/plugin-sitemap](./plugin-sitemap.mdx) +- [@docusaurus/plugin-svgr](./plugin-svgr.mdx) +- [@docusaurus/plugin-rsdoctor](./plugin-rsdoctor.mdx) +- [@docusaurus/plugin-pwa](./plugin-pwa.mdx) +- [@docusaurus/plugin-client-redirects](./plugin-client-redirects.mdx) +- [@docusaurus/plugin-ideal-image](./plugin-ideal-image.mdx) +- [@docusaurus/plugin-google-analytics](./plugin-google-analytics.mdx) +- [@docusaurus/plugin-google-gtag](./plugin-google-gtag.mdx) +- [@docusaurus/plugin-google-tag-manager](./plugin-google-tag-manager.mdx) diff --git a/website/versioned_docs/version-3.7.0/api/plugins/plugin-client-redirects.mdx b/website/versioned_docs/version-3.7.0/api/plugins/plugin-client-redirects.mdx new file mode 100644 index 0000000000..baca3a6bb9 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/plugin-client-redirects.mdx @@ -0,0 +1,127 @@ +--- +sidebar_position: 4 +slug: /api/plugins/@docusaurus/plugin-client-redirects +--- + +# 📦 plugin-client-redirects + +import APITable from '@site/src/components/APITable'; + +Docusaurus Plugin to generate **client-side redirects**. + +This plugin will write additional HTML pages to your static site that redirect the user to your existing Docusaurus pages with JavaScript. + +:::warning production only + +This plugin is always inactive in development and **only active in production** because it works on the build output. + +::: + +:::warning + +It is better to use server-side redirects whenever possible. + +Before using this plugin, you should look if your hosting provider doesn't offer this feature. + +::: + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-client-redirects +``` + +## Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `fromExtensions` | `string[]` | `[]` | The extensions to be removed from the route after redirecting. | +| `toExtensions` | `string[]` | `[]` | The extensions to be appended to the route after redirecting. | +| `redirects` | <code>[RedirectRule](#RedirectRule)[]</code> | `[]` | The list of redirect rules. | +| `createRedirects` | <code>[CreateRedirectsFn](#CreateRedirectsFn)</code> | `undefined` | A callback to create a redirect rule. Docusaurus query this callback against every path it has created, and use its return value to output more paths. | + +```mdx-code-block +</APITable> +``` + +:::note + +This plugin will also read the [`siteConfig.onDuplicateRoutes`](../docusaurus.config.js.mdx#onDuplicateRoutes) config to adjust its logging level when multiple files will be emitted to the same location. + +::: + +### Types {#types} + +#### `RedirectRule` {#RedirectRule} + +```ts +type RedirectRule = { + to: string; + from: string | string[]; +}; +``` + +:::note + +The idea of "from" and "to" is central in this plugin. "From" means a path that you want to _create_, i.e. an extra HTML file that will be written; "to" means a path to want to redirect _to_, usually a route that Docusaurus already knows about. + +This is why you can have multiple "from" for the same "to": we will create multiple HTML files that all redirect to the same destination. On the other hand, one "from" can never have more than one "to": the written HTML file needs to have a determinate destination. + +::: + +#### `CreateRedirectsFn` {#CreateRedirectsFn} + +```ts +// The parameter `path` is a route that Docusaurus has already created. It can +// be seen as the "to", and your return value is the "from". Returning a falsy +// value will not create any redirect pages for this particular path. +type CreateRedirectsFn = (path: string) => string[] | string | null | undefined; +``` + +### Example configuration {#ex-config} + +Here's an example configuration: + +```js title="docusaurus.config.js" +export default { + plugins: [ + [ + '@docusaurus/plugin-client-redirects', + // highlight-start + { + fromExtensions: ['html', 'htm'], // /myPage.html -> /myPage + toExtensions: ['exe', 'zip'], // /myAsset -> /myAsset.zip (if latter exists) + redirects: [ + // /docs/oldDoc -> /docs/newDoc + { + to: '/docs/newDoc', + from: '/docs/oldDoc', + }, + // Redirect from multiple old paths to the new path + { + to: '/docs/newDoc2', + from: ['/docs/oldDocFrom2019', '/docs/legacyDocFrom2016'], + }, + ], + createRedirects(existingPath) { + if (existingPath.includes('/community')) { + // Redirect from /docs/team/X to /community/X and /docs/support/X to /community/X + return [ + existingPath.replace('/community', '/docs/team'), + existingPath.replace('/community', '/docs/support'), + ]; + } + return undefined; // Return a falsy value: no redirect created + }, + }, + // highlight-end + ], + ], +}; +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugins/plugin-content-blog.mdx b/website/versioned_docs/version-3.7.0/api/plugins/plugin-content-blog.mdx new file mode 100644 index 0000000000..1a1703b7c4 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/plugin-content-blog.mdx @@ -0,0 +1,417 @@ +--- +sidebar_position: 2 +slug: /api/plugins/@docusaurus/plugin-content-blog +--- + +# 📦 plugin-content-blog + +import APITable from '@site/src/components/APITable'; + +Provides the [Blog](blog.mdx) feature and is the default blog plugin for Docusaurus. + +:::warning some features production only + +The [feed feature](../../blog.mdx#feed) works by extracting the build output, and is **only active in production**. + +::: + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-content-blog +``` + +:::tip + +If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. + +You can configure this plugin through the [preset options](../../using-plugins.mdx#docusauruspreset-classic). + +::: + +## Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `path` | `string` | `'blog'` | Path to the blog content directory on the file system, relative to site dir. | +| `editUrl` | <code>string \| [EditUrlFn](#EditUrlFn)</code> | `undefined` | Base URL to edit your site. The final URL is computed by `editUrl + relativePostPath`. Using a function allows more nuanced control for each file. Omitting this variable entirely will disable edit links. | +| `editLocalizedFiles` | `boolean` | `false` | The edit URL will target the localized file, instead of the original unlocalized file. Ignored when `editUrl` is a function. | +| `blogTitle` | `string` | `'Blog'` | Blog page title for better SEO. | +| `blogDescription` | `string` | `'Blog'` | Blog page meta description for better SEO. | +| `blogSidebarCount` | <code>number \| 'ALL'</code> | `5` | Number of blog post elements to show in the blog sidebar. `'ALL'` to show all blog posts; `0` to disable. | +| `blogSidebarTitle` | `string` | `'Recent posts'` | Title of the blog sidebar. | +| `routeBasePath` | `string` | `'blog'` | URL route for the blog section of your site. **DO NOT** include a trailing slash. Use `/` to put the blog at root path. | +| `tagsBasePath` | `string` | `'tags'` | URL route for the tags section of your blog. Will be appended to `routeBasePath`. | +| `pageBasePath` | `string` | `'page'` | URL route for the pages section of your blog. Will be appended to `routeBasePath`. | +| `archiveBasePath` | <code>string \| null</code> | `'archive'` | URL route for the archive section of your blog. Will be appended to `routeBasePath`. **DO NOT** include a trailing slash. Use `null` to disable generation of archive. | +| `authorsBasePath` | `string` | `'authors'` | URL route for the authors pages of your blog. Will be appended to `path`. | +| `include` | `string[]` | `['**/*.{md,mdx}']` | Array of glob patterns matching Markdown files to be built, relative to the content path. | +| `exclude` | `string[]` | _See example configuration_ | Array of glob patterns matching Markdown files to be excluded. Serves as refinement based on the `include` option. | +| `postsPerPage` | <code>number \| 'ALL'</code> | `10` | Number of posts to show per page in the listing page. Use `'ALL'` to display all posts on one listing page. | +| `blogListComponent` | `string` | `'@theme/BlogListPage'` | Root component of the blog listing page. | +| `blogPostComponent` | `string` | `'@theme/BlogPostPage'` | Root component of each blog post page. | +| `blogTagsListComponent` | `string` | `'@theme/BlogTagsListPage'` | Root component of the tags list page. | +| `blogTagsPostsComponent` | `string` | `'@theme/BlogTagsPostsPage'` | Root component of the "posts containing tag" page. | +| `blogArchiveComponent` | `string` | `'@theme/BlogArchivePage'` | Root component of the blog archive page. | +| `blogAuthorsPostsComponent` | `string` | `'@theme/Blog/Pages/BlogAuthorsPostsPage'` | Root component of the blog author page. | +| `blogAuthorsListComponent` | `string` | `'@theme/Blog/Pages/BlogAuthorsListPage'` | Root component of the blog authors page index. | +| `remarkPlugins` | `any[]` | `[]` | Remark plugins passed to MDX. | +| `rehypePlugins` | `any[]` | `[]` | Rehype plugins passed to MDX. | +| `rehypePlugins` | `any[]` | `[]` | Recma plugins passed to MDX. | +| `beforeDefaultRemarkPlugins` | `any[]` | `[]` | Custom Remark plugins passed to MDX before the default Docusaurus Remark plugins. | +| `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. | +| `truncateMarker` | `RegExp` | `/<!--\s*truncate\s*-->/` \| `\{\/\*\s*truncate\s*\*\/\}/` | Truncate marker marking where the summary ends. | +| `showReadingTime` | `boolean` | `true` | Show estimated reading time for the blog post. | +| `readingTime` | `ReadingTimeFn` | The default reading time | A callback to customize the reading time number displayed. | +| `authorsMapPath` | `string` | `'authors.yml'` | Path to the authors map file, relative to the blog content directory. | +| `feedOptions` | _See below_ | `{type: ['rss', 'atom']}` | Blog feed. | +| `feedOptions.type` | <code>[FeedType](#FeedType) \| [FeedType](#FeedType)[] \| 'all' \| null</code> | **Required** | Type of feed to be generated. Use `null` to disable generation. | +| `feedOptions.createFeedItems` | <code>[CreateFeedItemsFn](#CreateFeedItemsFn) \| undefined</code> | `undefined` | An optional function which can be used to transform and / or filter the items in the feed. | +| `feedOptions.limit` | `number \| null \| false` | `20` | Limits the feed to the specified number of posts, `false` or `null` for all entries. Defaults to `20`. | +| `feedOptions.title` | `string` | `siteConfig.title` | Title of the feed. | +| `feedOptions.description` | `string` | <code>\`$\{siteConfig.title} Blog\`</code> | Description of the feed. | +| `feedOptions.copyright` | `string` | `undefined` | Copyright message. | +| `feedOptions.xslt` | <code>boolean \| [FeedXSLTOptions](#FeedXSLTOptions)</code> | `undefined` | Permits to style the blog XML feeds with XSLT so that browsers render them nicely. | +| `feedOptions.language` | `string` (See [documentation](http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes) for possible values) | `undefined` | Language metadata of the feed. | +| `sortPosts` | <code>'descending' \| 'ascending' </code> | `'descending'` | Governs the direction of blog post sorting. | +| `processBlogPosts` | <code>[ProcessBlogPostsFn](#ProcessBlogPostsFn)</code> | `undefined` | An optional function which can be used to transform blog posts (filter, modify, delete, etc...). | +| `showLastUpdateAuthor` | `boolean` | `false` | Whether to display the author who last updated the blog post. | +| `showLastUpdateTime` | `boolean` | `false` | Whether to display the last date the blog post was updated. This requires access to git history during the build, so will not work correctly with shallow clones (a common default for CI systems). With GitHub `actions/checkout`, use`fetch-depth: 0`. | +| `tags` | `string \| false \| null \| undefined` | `tags.yml` | Path to the YAML tags file listing pre-defined tags. Relative to the blog content directory. | +| `onInlineTags` | `'ignore' \| 'log' \| 'warn' \| 'throw'` | `warn` | The plugin behavior when blog posts contain inline tags (not appearing in the list of pre-defined tags, usually `tags.yml`). | +| `onUntruncatedBlogPosts` | `'ignore' \| 'log' \| 'warn' \| 'throw'` | `warn` | The plugin behavior when blog posts do not contain a truncate marker. | + +```mdx-code-block +</APITable> +``` + +### Types {#types} + +#### `EditUrlFn` {#EditUrlFn} + +```ts +type EditUrlFunction = (params: { + blogDirPath: string; + blogPath: string; + permalink: string; + locale: string; +}) => string | undefined; +``` + +#### `ReadingTimeFn` {#ReadingTimeFn} + +```ts +type ReadingTimeOptions = { + wordsPerMinute: number; + wordBound: (char: string) => boolean; +}; + +type ReadingTimeCalculator = (params: { + content: string; + frontMatter?: BlogPostFrontMatter & Record<string, unknown>; + options?: ReadingTimeOptions; +}) => number; + +type ReadingTimeFn = (params: { + content: string; + frontMatter: BlogPostFrontMatter & Record<string, unknown>; + defaultReadingTime: ReadingTimeCalculator; +}) => number | undefined; +``` + +#### `FeedType` {#FeedType} + +```ts +type FeedType = 'rss' | 'atom' | 'json'; +``` + +#### `FeedXSLTOptions` {#FeedXSLTOptions} + +Permits to style the blog XML feeds so that browsers render them nicely with [XSLT](https://developer.mozilla.org/en-US/docs/Web/XSLT). + +- Use `true` to let the blog use its built-in `.xsl` and `.css` files to style the blog feed +- Use a falsy value (`undefined | null | false`) to disable the feature +- Use a `string` to provide a file path to a custom `.xsl` file relative to the blog content folder. By convention, you must provide a `.css` file with the exact same name. + +```ts +type FeedXSLTOptions = + | boolean + | undefined + | null + | { + rss?: string | boolean | null | undefined; + atom?: string | boolean | null | undefined; + }; +``` + +#### `CreateFeedItemsFn` {#CreateFeedItemsFn} + +```ts +type CreateFeedItemsFn = (params: { + blogPosts: BlogPost[]; + siteConfig: DocusaurusConfig; + outDir: string; + defaultCreateFeedItemsFn: CreateFeedItemsFn; +}) => Promise<BlogFeedItem[]>; +``` + +#### `ProcessBlogPostsFn` {#ProcessBlogPostsFn} + +```ts +type ProcessBlogPostsFn = (params: { + blogPosts: BlogPost[]; +}) => Promise<void | BlogPost[]>; +``` + +### Example configuration {#ex-config} + +You can configure this plugin through preset options or plugin options. + +:::tip + +Most Docusaurus users configure this plugin through the preset options. + +::: + +```js config-tabs +// Preset Options: blog +// Plugin Options: @docusaurus/plugin-content-blog + +const config = { + path: 'blog', + // Simple use-case: string editUrl + // editUrl: 'https://github.com/facebook/docusaurus/edit/main/website/', + // Advanced use-case: functional editUrl + editUrl: ({locale, blogDirPath, blogPath, permalink}) => + `https://github.com/facebook/docusaurus/edit/main/website/${blogDirPath}/${blogPath}`, + editLocalizedFiles: false, + blogTitle: 'Blog title', + blogDescription: 'Blog', + blogSidebarCount: 5, + blogSidebarTitle: 'All our posts', + routeBasePath: 'blog', + include: ['**/*.{md,mdx}'], + exclude: [ + '**/_*.{js,jsx,ts,tsx,md,mdx}', + '**/_*/**', + '**/*.test.{js,jsx,ts,tsx}', + '**/__tests__/**', + ], + postsPerPage: 10, + blogListComponent: '@theme/BlogListPage', + blogPostComponent: '@theme/BlogPostPage', + blogTagsListComponent: '@theme/BlogTagsListPage', + blogTagsPostsComponent: '@theme/BlogTagsPostsPage', + remarkPlugins: [require('./my-remark-plugin')], + rehypePlugins: [], + beforeDefaultRemarkPlugins: [], + beforeDefaultRehypePlugins: [], + truncateMarker: /<!--\s*(truncate)\s*-->/, + showReadingTime: true, + feedOptions: { + type: '', + title: '', + description: '', + copyright: '', + language: undefined, + 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, + }); + }, + }, +}; +``` + +## Markdown front matter {#markdown-front-matter} + +Markdown documents can use the following Markdown [front matter](../../guides/markdown-features/markdown-features-intro.mdx#front-matter) metadata fields, enclosed by a line `---` on either side. + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `authors` | `Authors` | `undefined` | List of blog post authors (or unique author). Read the [`authors` guide](../../blog.mdx#blog-post-authors) for more explanations. Prefer `authors` over the `author_*` front matter fields, even for single author blog posts. | +| `author` | `string` | `undefined` | ⚠️ Prefer using `authors`. The blog post author's name. | +| `author_url` | `string` | `undefined` | ⚠️ Prefer using `authors`. The URL that the author's name will be linked to. This could be a GitHub, X, Facebook profile URL, etc. | +| `author_image_url` | `string` | `undefined` | ⚠️ Prefer using `authors`. The URL to the author's thumbnail image. | +| `author_title` | `string` | `undefined` | ⚠️ Prefer using `authors`. A description of the author. | +| `title` | `string` | Markdown title | The blog post title. | +| `title_meta` | `string` | `frontMatter.title` | The blog post SEO metadata title, used in `<head>` for `<title>` and `og:title`. Permits to override `title` when the displayed title and SEO title should be different. | +| `sidebar_label` | `string` | `title` | A custom label for the blog sidebar, replacing the default one (`title`). | +| `date` | `string` | File name or file creation time | The blog post creation date. If not specified, this can be extracted from the file or folder name, e.g, `2021-04-15-blog-post.mdx`, `2021-04-15-blog-post/index.mdx`, `2021/04/15/blog-post.mdx`. Otherwise, it is the Markdown file creation time. | +| `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your post. Strings can be a reference to keys of a [tags file](#tags-file) (usually `tags.yml`) | +| `draft` | `boolean` | `false` | Draft blog posts will only be available during development. | +| `unlisted` | `boolean` | `false` | Unlisted blog posts will be available in both development and production. They will be "hidden" in production, not indexed, excluded from sitemaps, and can only be accessed by users having a direct link. | +| `hide_table_of_contents` | `boolean` | `false` | Whether to hide the table of contents to the right. | +| `toc_min_heading_level` | `number` | `2` | The minimum heading level shown in the table of contents. Must be between 2 and 6 and lower or equal to the max value. | +| `toc_max_heading_level` | `number` | `3` | The max heading level shown in the table of contents. Must be between 2 and 6. | +| `keywords` | `string[]` | `undefined` | Keywords meta tag, which will become the `<meta name="keywords" content="keyword1,keyword2,..."/>` in `<head>`, used by search engines. | +| `description` | `string` | The first line of Markdown content | The description of your document, which will become the `<meta name="description" content="..."/>` and `<meta property="og:description" content="..."/>` in `<head>`, used by search engines. | +| `image` | `string` | `undefined` | Cover or thumbnail image that will be used as the `<meta property="og:image" content="..."/>` in the `<head>`, enhancing link previews on social media and messaging platforms. | +| `slug` | `string` | File path | Allows to customize the blog post URL (`/<routeBasePath>/<slug>`). Support multiple patterns: `slug: my-blog-post`, `slug: /my/path/to/blog/post`, slug: `/`. | +| `last_update` | `FrontMatterLastUpdate` | `undefined` | Allows overriding the last update author/date. Date can be any [parsable date string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse). | + +```mdx-code-block +</APITable> +``` + +```ts +type FrontMatterLastUpdate = {date?: string; author?: string}; + +type Tag = string | {label: string; permalink: string}; + +// An author key references an author from the global plugin authors.yml file +type AuthorKey = string; + +// Social platform name -> Social platform link +// Example: {MyPlatform: 'https://myplatform.com/myusername'} +// Pre-defined platforms +// ("x", "github", "twitter", "linkedin", "stackoverflow", "instagram", "bluesky", "mastodon", "threads", "twitch", "youtube") accept handles: +// Example: {github: 'slorber'} +type AuthorSocials = Record<string, string>; + +type Author = { + key?: AuthorKey; + name: string; + title?: string; + url?: string; + image_url?: string; + socials?: AuthorSocials; +}; + +// The front matter authors field allows various possible shapes +type Authors = AuthorKey | Author | (AuthorKey | Author)[]; +``` + +Example: + +```md +--- +title: Welcome Docusaurus +authors: + - slorber + - yangshun + - name: Joel Marcey + title: Co-creator of Docusaurus 1 + url: https://github.com/JoelMarcey + image_url: https://github.com/JoelMarcey.png + socials: + x: joelmarcey + github: JoelMarcey +tags: [docusaurus] +description: This is my first post on Docusaurus. +image: https://i.imgur.com/mErPwqL.png +hide_table_of_contents: false +--- + +A Markdown blog post +``` + +import TagsFileApiRefSection from './_partial-tags-file-api-ref-section.mdx'; + +<TagsFileApiRefSection /> + +## Authors File {#authors-file} + +Use the [`authors` plugin option](#authors) to configure the path of a YAML authors file. + +By convention, the plugin will look for a `authors.yml` file at the root of your blog content folder(s). + +This file can contain a list of predefined [global blog authors](../../blog.mdx#global-authors). You can reference these authors by their keys in Markdown files thanks to the [`authors` front matter](#markdown-front-matter). + +### Types {#authors-file-types} + +The YAML content of the provided authors file should respect the following shape: + +```tsx +type AuthorsMapInput = { + [authorKey: string]: AuthorInput; +}; + +type AuthorInput = { + name?: string; + title?: string; + description?: string; + imageURL?: string; + url?: string; + email?: string; + page?: boolean | {permalink: string}; + socials?: Record<string, string>; + [customAuthorAttribute: string]: unknown; +}; +``` + +### Example {#authors-file-example} + +```yml title="tags.yml" +slorber: + name: Sébastien Lorber + title: Docusaurus maintainer + url: https://sebastienlorber.com + image_url: https://github.com/slorber.png + page: true + socials: + x: sebastienlorber + github: slorber + +jmarcey: + name: Joel Marcey + title: Co-creator of Docusaurus 1 + url: https://github.com/JoelMarcey + image_url: https://github.com/JoelMarcey.png + email: jimarcey@gmail.com + page: + permalink: '/joel-marcey' + socials: + x: joelmarcey + github: JoelMarcey +``` + +```md title="blog/my-blog-post.md" +--- +authors: [slorber, jmarcey] +--- + +# My Blog Post + +Content +``` + +## i18n {#i18n} + +Read the [i18n introduction](../../i18n/i18n-introduction.mdx) first. + +### Translation files location {#translation-files-location} + +- **Base path**: `website/i18n/[locale]/docusaurus-plugin-content-blog` +- **Multi-instance path**: `website/i18n/[locale]/docusaurus-plugin-content-blog-[pluginId]` +- **JSON files**: extracted with [`docusaurus write-translations`](../../cli.mdx#docusaurus-write-translations-sitedir) +- **Markdown files**: `website/i18n/[locale]/docusaurus-plugin-content-blog` + +### Example file-system structure {#example-file-system-structure} + +```bash +website/i18n/[locale]/docusaurus-plugin-content-blog +│ +│ # translations for website/blog +├── authors.yml +├── first-blog-post.md +├── second-blog-post.md +│ +│ # translations for the plugin options that will be rendered +└── options.json +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugins/plugin-content-docs.mdx b/website/versioned_docs/version-3.7.0/api/plugins/plugin-content-docs.mdx new file mode 100644 index 0000000000..fa9ddbf53e --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/plugin-content-docs.mdx @@ -0,0 +1,376 @@ +--- +sidebar_position: 1 +slug: /api/plugins/@docusaurus/plugin-content-docs +--- + +# 📦 plugin-content-docs + +import APITable from '@site/src/components/APITable'; + +Provides the [Docs](../../guides/docs/docs-introduction.mdx) functionality and is the default docs plugin for Docusaurus. + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-content-docs +``` + +:::tip + +If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. + +You can configure this plugin through the [preset options](../../using-plugins.mdx#docusauruspreset-classic). + +::: + +## Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `path` | `string` | `'docs'` | Path to the docs content directory on the file system, relative to site directory. | +| `editUrl` | <code>string \| [EditUrlFunction](#EditUrlFunction)</code> | `undefined` | Base URL to edit your site. The final URL is computed by `editUrl + relativeDocPath`. Using a function allows more nuanced control for each file. Omitting this variable entirely will disable edit links. | +| `editLocalizedFiles` | `boolean` | `false` | The edit URL will target the localized file, instead of the original unlocalized file. Ignored when `editUrl` is a function. | +| `editCurrentVersion` | `boolean` | `false` | The edit URL will always target the current version doc instead of older versions. Ignored when `editUrl` is a function. | +| `routeBasePath` | `string` | `'docs'` | URL route for the docs section of your site. **DO NOT** include a trailing slash. Use `/` for shipping docs without base path. | +| `tagsBasePath` | `string` | `'tags'` | URL route for the tags list page of your site. It is prepended to the `routeBasePath`. | +| `include` | `string[]` | `['**/*.{md,mdx}']` | Array of glob patterns matching Markdown files to be built, relative to the content path. | +| `exclude` | `string[]` | _See example configuration_ | Array of glob patterns matching Markdown files to be excluded. Serves as refinement based on the `include` option. | +| `sidebarPath` | <code>false \| string</code> | `undefined` | Path to a sidebars configuration file, loaded in a Node.js context. Use `false` to disable sidebars, or `undefined` to create a fully autogenerated sidebar. | +| `sidebarCollapsible` | `boolean` | `true` | Whether sidebar categories are collapsible by default. See also [Collapsible categories](/docs/sidebar/items#collapsible-categories) | +| `sidebarCollapsed` | `boolean` | `true` | Whether sidebar categories are collapsed by default. See also [Expanded categories by default](/docs/sidebar/items#expanded-categories-by-default) | +| `sidebarItemsGenerator` | <code>[SidebarGenerator](#SidebarGenerator)</code> | _Omitted_ | Function used to replace the sidebar items of type `'autogenerated'` with real sidebar items (docs, categories, links...). See also [Customize the sidebar items generator](/docs/sidebar/autogenerated#customize-the-sidebar-items-generator) | +| `numberPrefixParser` | <code>boolean \| [PrefixParser](#PrefixParser)</code> | _Omitted_ | Custom parsing logic to extract number prefixes from file names. Use `false` to disable this behavior and leave the docs untouched, and `true` to use the default parser. See also [Using number prefixes](/docs/sidebar/autogenerated#using-number-prefixes) | +| `docsRootComponent` | `string` | `'@theme/DocsRoot'` | Parent component of all the docs plugin pages (including all versions). Stays mounted when navigation between docs pages and versions. | +| `docVersionRootComponent` | `string` | `'@theme/DocVersionLayout'` | Parent component of all docs pages of an individual version (doc pages with sidebars, tags pages). Stays mounted when navigation between pages of that specific version. | +| `docRootComponent` | `string` | `'@theme/DocRoot'` | Parent component of all doc pages with sidebars (regular docs pages, category generated index pages). Stays mounted when navigation between such pages. | +| `docItemComponent` | `string` | `'@theme/DocItem'` | Main doc container, with TOC, pagination, etc. | +| `docTagsListComponent` | `string` | `'@theme/DocTagsListPage'` | Root component of the tags list page | +| `docTagDocListComponent` | `string` | `'@theme/DocTagDocListPage'` | Root component of the "docs containing tag X" page. | +| `docCategoryGeneratedIndexComponent` | `string` | `'@theme/DocCategoryGeneratedIndexPage'` | Root component of the generated category index page. | +| `remarkPlugins` | `any[]` | `[]` | Remark plugins passed to MDX. | +| `rehypePlugins` | `any[]` | `[]` | Rehype plugins passed to MDX. | +| `rehypePlugins` | `any[]` | `[]` | Recma plugins passed to MDX. | +| `beforeDefaultRemarkPlugins` | `any[]` | `[]` | Custom Remark plugins passed to MDX before the default Docusaurus Remark plugins. | +| `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. | +| `showLastUpdateAuthor` | `boolean` | `false` | Whether to display the author who last updated the doc. | +| `showLastUpdateTime` | `boolean` | `false` | Whether to display the last date the doc was updated. This requires access to git history during the build, so will not work correctly with shallow clones (a common default for CI systems). With GitHub `actions/checkout`, use`fetch-depth: 0`. | +| `breadcrumbs` | `boolean` | `true` | Enable or disable the breadcrumbs on doc pages. | +| `disableVersioning` | `boolean` | `false` | Explicitly disable versioning even when multiple versions exist. This will make the site only include the current version. Will error if `includeCurrentVersion: false` and `disableVersioning: true`. | +| `includeCurrentVersion` | `boolean` | `true` | Include the current version of your docs. | +| `lastVersion` | `string` | First version in `versions.json` | The version navigated to in priority and displayed by default for docs navbar items. | +| `onlyIncludeVersions` | `string[]` | All versions available | Only include a subset of all available versions. | +| `versions` | <code>[VersionsConfig](#VersionsConfig)</code> | `{}` | Independent customization of each version's properties. | +| `tags` | `string \| false \| null \| undefined` | `tags.yml` | Path to a YAML file listing pre-defined tags. Relative to the docs version content directories. | +| `onInlineTags` | `'ignore' \| 'log' \| 'warn' \| 'throw'` | `warn` | The plugin behavior when docs contain inline tags (not appearing in the list of pre-defined tags, usually `docs/tags.yml`). | + +```mdx-code-block +</APITable> +``` + +### Types {#types} + +#### `EditUrlFunction` {#EditUrlFunction} + +```ts +type EditUrlFunction = (params: { + version: string; + versionDocsDirPath: string; + docPath: string; + permalink: string; + locale: string; +}) => string | undefined; +``` + +#### `PrefixParser` {#PrefixParser} + +```ts +type PrefixParser = (filename: string) => { + filename: string; + numberPrefix?: number; +}; +``` + +#### `SidebarGenerator` {#SidebarGenerator} + +```ts +type SidebarGenerator = (generatorArgs: { + /** The sidebar item with type "autogenerated" to be transformed. */ + item: {type: 'autogenerated'; dirName: string}; + /** Useful metadata for the version this sidebar belongs to. */ + version: {contentPath: string; versionName: string}; + /** All the docs of that version (unfiltered). */ + docs: { + id: string; + title: string; + frontMatter: DocFrontMatter & Record<string, unknown>; + source: string; + sourceDirName: string; + sidebarPosition?: number | undefined; + }[]; + /** Number prefix parser configured for this plugin. */ + numberPrefixParser: PrefixParser; + /** The default category index matcher which you can override. */ + isCategoryIndex: CategoryIndexMatcher; + /** + * key is the path relative to the doc content directory, value is the + * category metadata file's content. + */ + categoriesMetadata: {[filePath: string]: CategoryMetadata}; + /** + * Useful to re-use/enhance the default sidebar generation logic from + * Docusaurus. + */ + defaultSidebarItemsGenerator: SidebarGenerator; + // Returns an array of sidebar items — same as what you can declare in + // sidebars.js, except for shorthands. See https://docusaurus.io/docs/sidebar/items +}) => Promise<SidebarItem[]>; + +type CategoryIndexMatcher = (param: { + /** The file name, without extension */ + fileName: string; + /** + * The list of directories, from lowest level to highest. + * If there's no dir name, directories is ['.'] + */ + directories: string[]; + /** The extension, with a leading dot */ + extension: string; +}) => boolean; +``` + +#### `VersionsConfig` {#VersionsConfig} + +```ts +type VersionConfig = { + /** + * The base path of the version, will be appended to `baseUrl` + + * `routeBasePath`. + */ + path?: string; + /** The label of the version to be used in badges, dropdowns, etc. */ + label?: string; + /** The banner to show at the top of a doc of that version. */ + banner?: 'none' | 'unreleased' | 'unmaintained'; + /** Show a badge with the version label at the top of each doc. */ + badge?: boolean; + /** Prevents search engines from indexing this version */ + noIndex?: boolean; + /** Add a custom class name to the <html> element of each doc */ + className?: string; +}; + +type VersionsConfig = {[versionName: string]: VersionConfig}; +``` + +### Example configuration {#ex-config} + +You can configure this plugin through preset options or plugin options. + +:::tip + +Most Docusaurus users configure this plugin through the preset options. + +::: + +```js config-tabs +// Preset Options: docs +// Plugin Options: @docusaurus/plugin-content-docs + +const config = { + path: 'docs', + breadcrumbs: true, + // Simple use-case: string editUrl + // editUrl: 'https://github.com/facebook/docusaurus/edit/main/website/', + // Advanced use-case: functional editUrl + editUrl: ({versionDocsDirPath, docPath}) => + `https://github.com/facebook/docusaurus/edit/main/website/${versionDocsDirPath}/${docPath}`, + editLocalizedFiles: false, + editCurrentVersion: false, + routeBasePath: 'docs', + include: ['**/*.md', '**/*.mdx'], + exclude: [ + '**/_*.{js,jsx,ts,tsx,md,mdx}', + '**/_*/**', + '**/*.test.{js,jsx,ts,tsx}', + '**/__tests__/**', + ], + sidebarPath: 'sidebars.js', + async sidebarItemsGenerator({ + defaultSidebarItemsGenerator, + numberPrefixParser, + item, + version, + docs, + isCategoryIndex, + }) { + // Use the provided data to generate a custom sidebar slice + return [ + {type: 'doc', id: 'intro'}, + { + type: 'category', + label: 'Tutorials', + items: [ + {type: 'doc', id: 'tutorial1'}, + {type: 'doc', id: 'tutorial2'}, + ], + }, + ]; + }, + numberPrefixParser(filename) { + // Implement your own logic to extract a potential number prefix + const numberPrefix = findNumberPrefix(filename); + // Prefix found: return it with the cleaned filename + if (numberPrefix) { + return { + numberPrefix, + filename: filename.replace(prefix, ''), + }; + } + // No number prefix found + return {numberPrefix: undefined, filename}; + }, + docsRootComponent: '@theme/DocsRoot', + docVersionRootComponent: '@theme/DocVersionRoot', + docRootComponent: '@theme/DocRoot', + docItemComponent: '@theme/DocItem', + remarkPlugins: [require('./my-remark-plugin')], + rehypePlugins: [], + beforeDefaultRemarkPlugins: [], + beforeDefaultRehypePlugins: [], + showLastUpdateAuthor: false, + showLastUpdateTime: false, + disableVersioning: false, + includeCurrentVersion: true, + lastVersion: undefined, + versions: { + current: { + label: 'Android SDK v2.0.0 (WIP)', + path: 'android-2.0.0', + banner: 'none', + }, + '1.0.0': { + label: 'Android SDK v1.0.0', + path: 'android-1.0.0', + banner: 'unmaintained', + }, + }, + onlyIncludeVersions: ['current', '1.0.0', '2.0.0'], +}; +``` + +## Markdown front matter {#markdown-front-matter} + +Markdown documents can use the following Markdown [front matter](../../guides/markdown-features/markdown-features-intro.mdx#front-matter) metadata fields, enclosed by a line `---` on either side. + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `id` | `string` | file path (including folders, without the extension) | A unique document ID. | +| `title` | `string` | Markdown title or `id` | The text title of your document. Used for the page metadata and as a fallback value in multiple places (sidebar, next/previous buttons...). Automatically added at the top of your doc if it does not contain any Markdown title. | +| `pagination_label` | `string` | `sidebar_label` or `title` | The text used in the document next/previous buttons for this document. | +| `sidebar_label` | `string` | `title` | The text shown in the document sidebar for this document. | +| `sidebar_position` | `number` | Default ordering | Controls the position of a doc inside the generated sidebar slice when using `autogenerated` sidebar items. See also [Autogenerated sidebar metadata](/docs/sidebar/autogenerated#autogenerated-sidebar-metadata). | +| `sidebar_class_name` | `string` | `undefined` | Gives the corresponding sidebar label a special class name when using autogenerated sidebars. | +| `sidebar_custom_props` | `object` | `undefined` | Assign [custom props](../../guides/docs/sidebar/index.mdx#passing-custom-props) to the sidebar item referencing this doc | +| `displayed_sidebar` | `string` | `undefined` | Force the display of a given sidebar when browsing the current document. Read the [multiple sidebars guide](../../guides/docs/sidebar/multiple-sidebars.mdx) for details. | +| `hide_title` | `boolean` | `false` | Whether to hide the title at the top of the doc. It only hides a title declared through the front matter, and have no effect on a Markdown title at the top of your document. | +| `hide_table_of_contents` | `boolean` | `false` | Whether to hide the table of contents to the right. | +| `toc_min_heading_level` | `number` | `2` | The minimum heading level shown in the table of contents. Must be between 2 and 6 and lower or equal to the max value. | +| `toc_max_heading_level` | `number` | `3` | The max heading level shown in the table of contents. Must be between 2 and 6. | +| `pagination_next` | <code>string \| null</code> | Next doc in the sidebar | The ID of the documentation you want the "Next" pagination to link to. Use `null` to disable showing "Next" for this page. | +| `pagination_prev` | <code>string \| null</code> | Previous doc in the sidebar | The ID of the documentation you want the "Previous" pagination to link to. Use `null` to disable showing "Previous" for this page. | +| `parse_number_prefixes` | `boolean` | `numberPrefixParser` plugin option | Whether number prefix parsing is disabled on this doc. See also [Using number prefixes](/docs/sidebar/autogenerated#using-number-prefixes). | +| `custom_edit_url` | <code>string \| null</code> | Computed using the `editUrl` plugin option | The URL for editing this document. Use `null` to disable showing "Edit this page" for this page. | +| `keywords` | `string[]` | `undefined` | Keywords meta tag for the document page, for search engines. | +| `description` | `string` | The first line of Markdown content | The description of your document, which will become the `<meta name="description" content="..."/>` and `<meta property="og:description" content="..."/>` in `<head>`, used by search engines. | +| `image` | `string` | `undefined` | Cover or thumbnail image that will be used as the `<meta property="og:image" content="..."/>` in the `<head>`, enhancing link previews on social media and messaging platforms. | +| `slug` | `string` | File path | Allows to customize the document URL (`/<routeBasePath>/<slug>`). Support multiple patterns: `slug: my-doc`, `slug: /my/path/myDoc`, `slug: /`. | +| `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your docs. Strings can be a reference to keys of a [tags file](#tags-file) (usually `tags.yml`) | +| `draft` | `boolean` | `false` | Draft documents will only be available during development. | +| `unlisted` | `boolean` | `false` | Unlisted documents will be available in both development and production. They will be "hidden" in production, not indexed, excluded from sitemaps, and can only be accessed by users having a direct link. | +| `last_update` | `FrontMatterLastUpdate` | `undefined` | Allows overriding the last update author/date. Date can be any [parsable date string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse). | + +```mdx-code-block +</APITable> +``` + +```ts +type FrontMatterLastUpdate = {date?: string; author?: string}; + +type Tag = string | {label: string; permalink: string}; +``` + +Example: + +```md +--- +id: doc-markdown +title: Docs Markdown Features +hide_title: false +hide_table_of_contents: false +sidebar_label: Markdown +sidebar_position: 3 +pagination_label: Markdown features +custom_edit_url: https://github.com/facebook/docusaurus/edit/main/docs/api-doc-markdown.md +description: How do I find you when I cannot solve this problem +keywords: + - docs + - docusaurus +tags: [docusaurus] +image: https://i.imgur.com/mErPwqL.png +slug: /myDoc +last_update: + date: 1/1/2000 + author: custom author name +--- + +# Markdown Features + +My Document Markdown content +``` + +import TagsFileApiRefSection from './_partial-tags-file-api-ref-section.mdx'; + +<TagsFileApiRefSection /> + +## i18n {#i18n} + +Read the [i18n introduction](../../i18n/i18n-introduction.mdx) first. + +### Translation files location {#translation-files-location} + +- **Base path**: `website/i18n/[locale]/docusaurus-plugin-content-docs` +- **Multi-instance path**: `website/i18n/[locale]/docusaurus-plugin-content-docs-[pluginId]` +- **JSON files**: extracted with [`docusaurus write-translations`](../../cli.mdx#docusaurus-write-translations-sitedir) +- **Markdown files**: `website/i18n/[locale]/docusaurus-plugin-content-docs/[versionName]` + +### Example file-system structure {#example-file-system-structure} + +```bash +website/i18n/[locale]/docusaurus-plugin-content-docs +│ +│ # translations for website/docs +├── current +│ ├── api +│ │ └── config.md +│ └── getting-started.md +├── current.json +│ +│ # translations for website/versioned_docs/version-1.0.0 +├── version-1.0.0 +│ ├── api +│ │ └── config.md +│ └── getting-started.md +└── version-1.0.0.json +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugins/plugin-content-pages.mdx b/website/versioned_docs/version-3.7.0/api/plugins/plugin-content-pages.mdx new file mode 100644 index 0000000000..03db1f4f1b --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/plugin-content-pages.mdx @@ -0,0 +1,158 @@ +--- +sidebar_position: 3 +slug: /api/plugins/@docusaurus/plugin-content-pages +--- + +# 📦 plugin-content-pages + +import APITable from '@site/src/components/APITable'; + +The default pages plugin for Docusaurus. The classic template ships with this plugin with default configurations. This plugin provides [creating pages](guides/creating-pages.mdx) functionality. + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-content-pages +``` + +:::tip + +If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. + +You can configure this plugin through the [preset options](../../using-plugins.mdx#docusauruspreset-classic). + +::: + +## Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `path` | `string` | `'src/pages'` | Path to data on filesystem relative to site dir. Components in this directory will be automatically converted to pages. | +| `editUrl` | <code>string \| [EditUrlFn](#EditUrlFn)</code> | `undefined` | **Only for Markdown pages**. Base URL to edit your site. The final URL is computed by `editUrl + relativePostPath`. Using a function allows more nuanced control for each file. Omitting this variable entirely will disable edit links. | +| `editLocalizedFiles` | `boolean` | `false` | **Only for Markdown pages**. The edit URL will target the localized file, instead of the original unlocalized file. Ignored when `editUrl` is a function. | +| `routeBasePath` | `string` | `'/'` | URL route for the pages section of your site. **DO NOT** include a trailing slash. | +| `include` | `string[]` | `['**/*.{js,jsx,ts,tsx,md,mdx}']` | Matching files will be included and processed. | +| `exclude` | `string[]` | _See example configuration_ | No route will be created for matching files. | +| `mdxPageComponent` | `string` | `'@theme/MDXPage'` | Component used by each MDX page. | +| `remarkPlugins` | `[]` | `any[]` | Remark plugins passed to MDX. | +| `rehypePlugins` | `[]` | `any[]` | Rehype plugins passed to MDX. | +| `rehypePlugins` | `any[]` | `[]` | Recma plugins passed to MDX. | +| `beforeDefaultRemarkPlugins` | `any[]` | `[]` | Custom Remark plugins passed to MDX before the default Docusaurus Remark plugins. | +| `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. | +| `showLastUpdateAuthor` | `boolean` | `false` | **Only for Markdown pages**. Whether to display the author who last updated the page. | +| `showLastUpdateTime` | `boolean` | `false` | **Only for Markdown pages**. Whether to display the last date the page post was updated. This requires access to git history during the build, so will not work correctly with shallow clones (a common default for CI systems). With GitHub `actions/checkout`, use`fetch-depth: 0`. | + +```mdx-code-block +</APITable> +``` + +### Types {#types} + +#### `EditUrlFn` {#EditUrlFn} + +```ts +type EditUrlFunction = (params: { + blogDirPath: string; + blogPath: string; + permalink: string; + locale: string; +}) => string | undefined; +``` + +### Example configuration {#ex-config} + +You can configure this plugin through preset options or plugin options. + +:::tip + +Most Docusaurus users configure this plugin through the preset options. + +::: + +```js config-tabs +// Preset Options: pages +// Plugin Options: @docusaurus/plugin-content-pages + +const config = { + path: 'src/pages', + routeBasePath: '', + include: ['**/*.{js,jsx,ts,tsx,md,mdx}'], + exclude: [ + '**/_*.{js,jsx,ts,tsx,md,mdx}', + '**/_*/**', + '**/*.test.{js,jsx,ts,tsx}', + '**/__tests__/**', + ], + mdxPageComponent: '@theme/MDXPage', + remarkPlugins: [require('./my-remark-plugin')], + rehypePlugins: [], + beforeDefaultRemarkPlugins: [], + beforeDefaultRehypePlugins: [], +}; +``` + +## Markdown front matter {#markdown-front-matter} + +Markdown pages can use the following Markdown [front matter](../../guides/markdown-features/markdown-features-intro.mdx#front-matter) metadata fields, enclosed by a line `---` on either side. + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `title` | `string` | Markdown title | The blog post title. | +| `description` | `string` | The first line of Markdown content | The description of your page, which will become the `<meta name="description" content="..."/>` and `<meta property="og:description" content="..."/>` in `<head>`, used by search engines. | +| `keywords` | `string[]` | `undefined` | Keywords meta tag, which will become the `<meta name="keywords" content="keyword1,keyword2,..."/>` in `<head>`, used by search engines. | +| `image` | `string` | `undefined` | Cover or thumbnail image that will be used as the `<meta property="og:image" content="..."/>` in the `<head>`, enhancing link previews on social media and messaging platforms. | +| `wrapperClassName` | `string` | | Class name to be added to the wrapper element to allow targeting specific page content. | +| `hide_table_of_contents` | `boolean` | `false` | Whether to hide the table of contents to the right. | +| `draft` | `boolean` | `false` | Draft pages will only be available during development. | +| `unlisted` | `boolean` | `false` | Unlisted pages will be available in both development and production. They will be "hidden" in production, not indexed, excluded from sitemaps, and can only be accessed by users having a direct link. | + +```mdx-code-block +</APITable> +``` + +Example: + +```md +--- +title: Markdown Page +description: Markdown page SEO description +wrapperClassName: markdown-page +hide_table_of_contents: false +draft: true +--- + +Markdown page content +``` + +## i18n {#i18n} + +Read the [i18n introduction](../../i18n/i18n-introduction.mdx) first. + +### Translation files location {#translation-files-location} + +- **Base path**: `website/i18n/[locale]/docusaurus-plugin-content-pages` +- **Multi-instance path**: `website/i18n/[locale]/docusaurus-plugin-content-pages-[pluginId]` +- **JSON files**: extracted with [`docusaurus write-translations`](../../cli.mdx#docusaurus-write-translations-sitedir) +- **Markdown files**: `website/i18n/[locale]/docusaurus-plugin-content-pages` + +### Example file-system structure {#example-file-system-structure} + +```bash +website/i18n/[locale]/docusaurus-plugin-content-pages +│ +│ # translations for website/src/pages +├── first-markdown-page.md +└── second-markdown-page.md +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugins/plugin-debug.mdx b/website/versioned_docs/version-3.7.0/api/plugins/plugin-debug.mdx new file mode 100644 index 0000000000..e580466ce5 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/plugin-debug.mdx @@ -0,0 +1,108 @@ +--- +sidebar_position: 5 +slug: /api/plugins/@docusaurus/plugin-debug +--- + +# 📦 plugin-debug + +```mdx-code-block +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +``` + +The debug plugin will display useful debug information at [`http://localhost:3000/__docusaurus/debug`](http://localhost:3000/__docusaurus/debug). + +It is mostly useful for plugin authors, that will be able to inspect more easily the content of the `.docusaurus` folder (like the creates routes), but also be able to inspect data structures that are never written to disk, like the plugin data loaded through the `contentLoaded` lifecycle. + +:::info + +If you use the plugin via the classic preset, the preset will **enable the plugin in development and disable it in production** by default (`debug: undefined`) to avoid exposing potentially sensitive information. You can use `debug: true` to always enable it or `debug: false` to always disable it. + +If you use a standalone plugin, you may need to achieve the same effect by checking the environment: + +```js title="docusaurus.config.js" +export default { + plugins: [ + // highlight-next-line + process.env.NODE_ENV === 'production' && '@docusaurus/plugin-debug', + ].filter(Boolean), +}; +``` + +::: + +:::note + +If you report a bug, we will probably ask you to have this plugin turned on in the production, so that we can inspect your deployment config more easily. + +If you don't have any sensitive information, you can keep it on in production [like we do](/__docusaurus/debug). + +::: + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-debug +``` + +:::tip + +If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. + +You can configure this plugin through the [preset options](../../using-plugins.mdx#docusauruspreset-classic). + +::: + +## Configuration {#configuration} + +This plugin currently has no options. + +### Example configuration {#ex-config} + +You can configure this plugin through preset options or plugin options. + +:::tip + +Most Docusaurus users configure this plugin through the preset options. + +::: + +```mdx-code-block +<Tabs groupId="api-config-ex"> +<TabItem value="preset" label="Preset options"> +``` + +If you use a preset, configure this plugin through the [preset options](../../using-plugins.mdx#docusauruspreset-classic): + +```js title="docusaurus.config.js" +export default { + presets: [ + [ + '@docusaurus/preset-classic', + { + // highlight-next-line + debug: true, // This will enable the plugin in production + }, + ], + ], +}; +``` + +```mdx-code-block +</TabItem> +<TabItem value="plugin" label="Plugin Options"> +``` + +If you are using a standalone plugin, provide options directly to the plugin: + +```js title="docusaurus.config.js" +export default { + // highlight-next-line + plugins: ['@docusaurus/plugin-debug'], +}; +``` + +```mdx-code-block +</TabItem> +</Tabs> +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugins/plugin-google-analytics.mdx b/website/versioned_docs/version-3.7.0/api/plugins/plugin-google-analytics.mdx new file mode 100644 index 0000000000..a914d122be --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/plugin-google-analytics.mdx @@ -0,0 +1,77 @@ +--- +sidebar_position: 6 +slug: /api/plugins/@docusaurus/plugin-google-analytics +--- + +# 📦 plugin-google-analytics + +import APITable from '@site/src/components/APITable'; + +The default [Google Analytics](https://developers.google.com/analytics/devguides/collection/analyticsjs/) plugin. It is a JavaScript library for measuring how users interact with your website **in the production build**. If you are using Google Analytics 4 you might need to consider using [plugin-google-gtag](./plugin-google-gtag.mdx) instead. + +:::danger Deprecated + +This plugin is **deprecated** and became useless on July 1, 2023. + +Google is [moving away from Universal Analytics](https://blog.google/products/marketingplatform/analytics/prepare-for-future-with-google-analytics-4/). + +If you are still using this plugin with a `UA-*` tracking id, you should create a Google Analytics 4 account as soon as possible, and use [`@docusaurus/plugin-google-gtag`](./plugin-google-gtag.mdx) instead of this plugin. More details [here](https://github.com/facebook/docusaurus/issues/7221). + +::: + +:::warning production only + +This plugin is always inactive in development and **only active in production** to avoid polluting the analytics statistics. + +::: + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-google-analytics +``` + +:::tip + +If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. + +You can configure this plugin through the [preset options](../../using-plugins.mdx#docusauruspreset-classic). + +::: + +## Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `trackingID` | `string` | **Required** | The tracking ID of your analytics service. | +| `anonymizeIP` | `boolean` | `false` | Whether the IP should be anonymized when sending requests. | + +```mdx-code-block +</APITable> +``` + +### Example configuration {#ex-config} + +You can configure this plugin through preset options or plugin options. + +:::tip + +Most Docusaurus users configure this plugin through the preset options. + +::: + +```js config-tabs +// Preset Options: googleAnalytics +// Plugin Options: @docusaurus/plugin-google-analytics + +const config = { + trackingID: 'UA-141789564-1', + anonymizeIP: true, +}; +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugins/plugin-google-gtag.mdx b/website/versioned_docs/version-3.7.0/api/plugins/plugin-google-gtag.mdx new file mode 100644 index 0000000000..ee30a0f3b8 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/plugin-google-gtag.mdx @@ -0,0 +1,73 @@ +--- +sidebar_position: 7 +slug: /api/plugins/@docusaurus/plugin-google-gtag +--- + +# 📦 plugin-google-gtag + +import APITable from '@site/src/components/APITable'; + +The default [Global Site Tag (gtag.js)](https://developers.google.com/tag-platform/gtagjs) plugin. It is a JavaScript tagging framework and API that allows you to send event data to Google Analytics, Google Ads, and Google Marketing Platform. This section describes how to configure a Docusaurus site to enable global site tag for Google Analytics. + +:::tip + +You can use [Google's Tag Assistant](https://tagassistant.google.com/) tool to check if your gtag is set up correctly! + +::: + +:::warning production only + +This plugin is always inactive in development and **only active in production** to avoid polluting the analytics statistics. + +::: + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-google-gtag +``` + +:::tip + +If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. + +You can configure this plugin through the [preset options](../../using-plugins.mdx#docusauruspreset-classic). + +::: + +## Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `trackingID` | <code>string \| string[]</code> | **Required** | The tracking ID of your gtag service. It is possible to provide multiple ids. | +| `anonymizeIP` | `boolean` | `false` | Whether the IP should be anonymized when sending requests. | + +```mdx-code-block +</APITable> +``` + +### Example configuration {#ex-config} + +You can configure this plugin through preset options or plugin options. + +:::tip + +Most Docusaurus users configure this plugin through the preset options. + +::: + +```js config-tabs +// Preset Options: gtag +// Plugin Options: @docusaurus/plugin-google-gtag + +const config = { + trackingID: 'G-999X9XX9XX', + anonymizeIP: true, +}; +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugins/plugin-google-tag-manager.mdx b/website/versioned_docs/version-3.7.0/api/plugins/plugin-google-tag-manager.mdx new file mode 100644 index 0000000000..e444a53877 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/plugin-google-tag-manager.mdx @@ -0,0 +1,71 @@ +--- +sidebar_position: 8 +slug: /api/plugins/@docusaurus/plugin-google-tag-manager +--- + +# 📦 plugin-google-tag-manager + +import APITable from '@site/src/components/APITable'; + +A plugin for adding [Google Tag Manager (gtm.js)](https://developers.google.com/tag-platform/tag-manager) to a Docusaurus site. Use this plugin in conjunction with the standard [gtag plugin](./plugin-google-gtag.mdx) for in-depth analysis of how users are using your site. + +:::tip + +You can use [Google's Tag Assistant](https://tagassistant.google.com/) tool to check if tag manager is set up correctly! + +::: + +:::warning production only + +This plugin is always inactive in development and **only active in production** to avoid polluting the analytics statistics. + +::: + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-google-tag-manager +``` + +:::tip + +If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. + +You can configure this plugin through the [preset options](../../using-plugins.mdx#docusauruspreset-classic). + +::: + +## Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `containerId` | `string` | **Required** | Your Tag Manager container Id (usually starts with `GTM-`). | + +```mdx-code-block +</APITable> +``` + +### Example configuration {#ex-config} + +You can configure this plugin through preset options or plugin options. + +:::tip + +Most Docusaurus users configure this plugin through the preset options. + +::: + +```js config-tabs +// Preset Options: googleTagManager +// Plugin Options: @docusaurus/plugin-google-tag-manager + +const config = { + containerId: 'GTM-12345', +}; +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugins/plugin-ideal-image.mdx b/website/versioned_docs/version-3.7.0/api/plugins/plugin-ideal-image.mdx new file mode 100644 index 0000000000..16f3a4d987 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/plugin-ideal-image.mdx @@ -0,0 +1,92 @@ +--- +sidebar_position: 8 +slug: /api/plugins/@docusaurus/plugin-ideal-image +--- + +# 📦 plugin-ideal-image + +import APITable from '@site/src/components/APITable'; + +Docusaurus Plugin to generate an almost ideal image (responsive, lazy-loading, and low quality placeholder). + +:::info + +By default, the plugin is **inactive in development** so you could always view full-scale images. If you want to debug the ideal image behavior, you could set the [`disableInDev`](#disableInDev) option to `false`. + +::: + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-ideal-image +``` + +## Usage {#usage} + +This plugin supports the PNG and JPG formats only. + +```jsx +import Image from '@theme/IdealImage'; +import thumbnail from './path/to/img.png'; + +// your React code +<Image img={thumbnail} /> + +// or +<Image img={require('./path/to/img.png')} /> +``` + +:::warning + +This plugin registers a [Webpack loader](https://webpack.js.org/loaders/) that changes the type of imported/require images: + +- Before: `string` +- After: `{preSrc: string, src: import("@theme/IdealImage").SrcImage}` + +::: + +## Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `name` | `string` | `ideal-img/[name].[hash:hex:7].[width].[ext]` | Filename template for output files. | +| `sizes` | `number[]` | _original size_ | Specify all widths you want to use. If a specified size exceeds the original image's width, the latter will be used (i.e. images won't be scaled up). | +| `size` | `number` | _original size_ | Specify one width you want to use; if the specified size exceeds the original image's width, the latter will be used (i.e. images won't be scaled up) | +| `min` | `number` | | As an alternative to manually specifying `sizes`, you can specify `min`, `max` and `steps`, and the sizes will be generated for you. | +| `max` | `number` | | See `min` above | +| `steps` | `number` | `4` | Configure the number of images generated between `min` and `max` (inclusive) | +| `quality` | `number` | `85` | JPEG compression quality | +| `disableInDev` | `boolean` | `true` | You can test ideal image behavior in dev mode by setting this to `false`. **Tip**: use [network throttling](https://www.browserstack.com/guide/how-to-perform-network-throttling-in-chrome) in your browser to simulate slow networks. | + +```mdx-code-block +</APITable> +``` + +### Example configuration {#ex-config} + +Here's an example configuration: + +```js title="docusaurus.config.js" +export default { + plugins: [ + [ + '@docusaurus/plugin-ideal-image', + // highlight-start + { + quality: 70, + max: 1030, // max resized image's size. + min: 640, // min resized image's size. if original is lower, use that size. + steps: 2, // the max number of images generated between min and max (inclusive) + disableInDev: false, + }, + // highlight-end + ], + ], +}; +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugins/plugin-pwa.mdx b/website/versioned_docs/version-3.7.0/api/plugins/plugin-pwa.mdx new file mode 100644 index 0000000000..df16a0c864 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/plugin-pwa.mdx @@ -0,0 +1,303 @@ +--- +sidebar_position: 9 +slug: /api/plugins/@docusaurus/plugin-pwa +--- + +# 📦 plugin-pwa + +Docusaurus Plugin to add PWA support using [Workbox](https://developers.google.com/web/tools/workbox). This plugin generates a [Service Worker](https://developers.google.com/web/fundamentals/primers/service-workers) in production build only, and allows you to create fully PWA-compliant documentation site with offline and installation support. + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-pwa +``` + +## Configuration {#configuration} + +Create a [PWA manifest](https://web.dev/add-manifest/) at `./static/manifest.json`. + +Modify `docusaurus.config.js` with a minimal PWA config, like: + +```js title="docusaurus.config.js" +export default { + plugins: [ + [ + '@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', // your PWA manifest + }, + { + tagName: 'meta', + name: 'theme-color', + content: 'rgb(37, 194, 160)', + }, + ], + }, + ], + ], +}; +``` + +## Progressive Web App {#progressive-web-app} + +Having a service worker installed is not enough to make your application a PWA. You'll need to at least include a [Web App Manifest](https://developer.mozilla.org/en-US/docs/Web/Manifest) and have the correct tags in `<head>` ([Options > pwaHead](#pwahead)). + +After deployment, you can use [Lighthouse](https://developers.google.com/web/tools/lighthouse) to run an audit on your site. + +For a more exhaustive list of what it takes for your site to be a PWA, refer to the [PWA Checklist](https://developers.google.com/web/progressive-web-apps/checklist) + +## App installation support {#app-installation-support} + +If your browser supports it, you should be able to install a Docusaurus site as an app. + +![A screen recording of the installation process. A button appears in the address bar of the browser, which displays a dialog asking "install this application?" when clicked. After clicking the "Install" button, a new application is opened in the operating system, opening to the Docusaurus homepage.](/img/pwa_install.gif) + +:::note + +App installation requires the HTTPS protocol and a valid manifest. + +::: + +## Offline mode (precaching) {#offline-mode-precaching} + +We enable users to browse a Docusaurus site offline, by using service-worker precaching. + +The [workbox-precaching](https://developers.google.com/web/tools/workbox/modules/workbox-precaching) page explains the idea: + +> One feature of service workers is the ability to save a set of files to the cache when the service worker is installing. This is often referred to as "precaching", since you are caching content ahead of the service worker being used. +> +> The main reason for doing this is that it gives developers control over the cache, meaning they can determine when and how long a file is cached as well as serve it to the browser without going to the network, meaning it can be used to create web apps that work offline. +> +> Workbox takes a lot of the heavy lifting out of precaching by simplifying the API and ensuring assets are downloaded efficiently. + +By default, offline mode is enabled when the site is installed as an app. See the `offlineModeActivationStrategies` option for details. + +After the site has been precached, the service worker will serve cached responses for later visits. When a new build is deployed along with a new service worker, the new one will begin installing and eventually move to a waiting state. During this waiting state, a reload popup will show and ask the user to reload the page for new content. Until the user either clears the application cache or clicks the `reload` button on the popup, the service worker will continue serving the old content. + +:::warning + +Offline mode / precaching requires downloading all the static assets of the site ahead of time, and can consume unnecessary bandwidth. It may not be a good idea to activate it for all kind of sites. + +::: + +## Options {#options} + +### `debug` {#debug} + +- Type: `boolean` +- Default: `false` + +Turn debug mode on: + +- Workbox logs +- Additional Docusaurus logs +- Unoptimized SW file output +- Source maps + +### `offlineModeActivationStrategies` {#offlinemodeactivationstrategies} + +- Type: `('appInstalled' | 'mobile' | 'saveData'| 'queryString' | 'always')[]` +- Default: `['appInstalled', 'queryString', 'standalone']` + +Strategies used to turn the offline mode on: + +- `appInstalled`: activates for users having installed the site as an app (not 100% reliable) +- `standalone`: activates for users running the app as standalone (often the case once a PWA is installed) +- `queryString`: activates if queryString contains `offlineMode=true` (convenient for PWA debugging) +- `mobile`: activates for mobile users (`width <= 996px`) +- `saveData`: activates for users with `navigator.connection.saveData === true` +- `always`: activates for all users + +:::warning + +Use this carefully: some users may not like to be forced to use the offline mode. + +::: + +:::danger + +It is not possible to detect if a page is rendered as a PWA in a reliable manner. + +The `appinstalled` event has been [removed from the specification](https://github.com/w3c/manifest/pull/836), and the [`navigator.getInstalledRelatedApps()`](https://web.dev/get-installed-related-apps/) API is only supported in recent Chrome versions and require `related_applications` declared in the manifest. + +The [`standalone` strategy](https://petelepage.com/blog/2019/07/is-my-pwa-installed/) is a nice fallback to activate the offline mode (at least when running the installed app). + +::: + +### `injectManifestConfig` {#injectmanifestconfig} + +[Workbox options](https://developer.chrome.com/docs/workbox/reference/workbox-build/#type-InjectManifestOptions) to pass to `workbox.injectManifest()`. This gives you control over which assets will be precached, and be available offline. + +- Type: `InjectManifestOptions` +- Default: `{}` + +```js title="docusaurus.config.js" +export default { + plugins: [ + [ + '@docusaurus/plugin-pwa', + { + injectManifestConfig: { + manifestTransforms: [ + //... + ], + modifyURLPrefix: { + //... + }, + // We already add regular static assets (HTML, images...) to be available offline + // You can add more files according to your needs + globPatterns: ['**/*.{pdf,docx,xlsx}'], + // ... + }, + }, + ], + ], +}; +``` + +### `pwaHead` {#pwahead} + +- Type: `({ tagName: string; [attributeName: string]: string })[]` +- Default: `[]` + +Array of objects containing `tagName` and key-value pairs for attributes to inject into the `<head>` tag. Technically you can inject any head tag through this, but it's ideally used for tags to make your site PWA compliant. Here's a list of tag to make your app fully compliant: + +```js +export default { + plugins: [ + [ + '@docusaurus/plugin-pwa', + { + 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', + }, + { + tagName: 'meta', + name: 'apple-mobile-web-app-status-bar-style', + content: '#000', + }, + { + tagName: 'link', + rel: 'apple-touch-icon', + href: '/img/docusaurus.png', + }, + { + tagName: 'link', + rel: 'mask-icon', + href: '/img/docusaurus.svg', + color: 'rgb(37, 194, 160)', + }, + { + tagName: 'meta', + name: 'msapplication-TileImage', + content: '/img/docusaurus.png', + }, + { + tagName: 'meta', + name: 'msapplication-TileColor', + content: '#000', + }, + ], + }, + ], + ], +}; +``` + +### `swCustom` {#swcustom} + +- Type: `string | undefined` +- Default: `undefined` + +Useful for additional Workbox rules. You can do whatever a service worker can do here, and use the full power of workbox libraries. The code is transpiled, so you can use modern ES6+ syntax here. + +For example, to cache files from external routes: + +```js +import {registerRoute} from 'workbox-routing'; +import {StaleWhileRevalidate} from 'workbox-strategies'; + +// default fn export receiving some useful params +export default function swCustom(params) { + const { + debug, // :boolean + offlineMode, // :boolean + } = params; + + // Cache responses from external resources + registerRoute((context) => { + return [ + /graph\.facebook\.com\/.*\/picture/, + /netlify\.com\/img/, + /avatars1\.githubusercontent/, + ].some((regex) => context.url.href.match(regex)); + }, new StaleWhileRevalidate()); +} +``` + +The module should have a `default` function export, and receives some params. + +### `swRegister` {#swregister} + +- Type: `string | false` +- Default: `'docusaurus-plugin-pwa/src/registerSW.js'` + +Adds an entry before the Docusaurus app so that registration can happen before the app runs. The default `registerSW.js` file is enough for simple registration. + +Passing `false` will disable registration entirely. + +## Manifest example {#manifest-example} + +The Docusaurus site manifest can serve as an inspiration: + +```mdx-code-block +import CodeBlock from '@theme/CodeBlock'; + +<CodeBlock className="language-json"> + {JSON.stringify(require('@site/static/manifest.json'),null,2)} +</CodeBlock> +``` + +## Customizing reload popup {#customizing-reload-popup} + +The `@theme/PwaReloadPopup` component is rendered when a new service worker is waiting to be installed, and we suggest a reload to the user. You can [swizzle](../../swizzling.mdx) this component and implement your own UI. It will receive an `onReload` callback as props, which should be called when the `reload` button is clicked. This will tell the service worker to install the waiting service worker and reload the page. + +The default theme includes an implementation for the reload popup and uses [Infima Alerts](https://infima.dev/docs/components/alert). + +![A screen recording of the reload process. An alert box shows in the bottom right of the window, saying "New content available". After clicking the "Refresh" button, the page's main heading changes from "Introduction" to "PWA :))".](/img/pwa_reload.gif) + +Your component can render `null`, but this is not recommended: users won't have a way to get up-to-date content. diff --git a/website/versioned_docs/version-3.7.0/api/plugins/plugin-rsdoctor.mdx b/website/versioned_docs/version-3.7.0/api/plugins/plugin-rsdoctor.mdx new file mode 100644 index 0000000000..100d714893 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/plugin-rsdoctor.mdx @@ -0,0 +1,57 @@ +--- +sidebar_position: 7 +slug: /api/plugins/@docusaurus/plugin-rsdoctor +--- + +# 📦 plugin-rsdoctor + +import APITable from '@site/src/components/APITable'; + +A [Rsdoctor](https://rsdoctor.dev/) plugin can help you troubleshoot the bundling phase of your Docusaurus site, supporting both Webpack and Rspack. + +:::tip + +Use it to figure out which plugin or loader is slowing down the bundler, and focus your efforts on optimizing the bottleneck. + +::: + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-rsdoctor +``` + +## Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `rsdoctorOptions` | `object` | `{}` | The [Rsdoctor bundler plugin options](https://rsdoctor.dev/config/options/options), forwarded as is | + +```mdx-code-block +</APITable> +``` + +### Example configuration {#ex-config} + +You can configure this plugin through plugin options. + +```js title="docusaurus.config.js" +export default { + plugins: [ + [ + 'rsdoctor', + { + rsdoctorOptions: { + mode: 'lite', + }, + }, + ], + ], +}; +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugins/plugin-sitemap.mdx b/website/versioned_docs/version-3.7.0/api/plugins/plugin-sitemap.mdx new file mode 100644 index 0000000000..75ca74ef8b --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/plugin-sitemap.mdx @@ -0,0 +1,110 @@ +--- +sidebar_position: 10 +slug: /api/plugins/@docusaurus/plugin-sitemap +--- + +# 📦 plugin-sitemap + +import APITable from '@site/src/components/APITable'; + +This plugin creates sitemaps for your site so that search engine crawlers can crawl your site more accurately. + +:::warning production only + +This plugin is always inactive in development and **only active in production** because it works on the build output. + +::: + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-sitemap +``` + +:::tip + +If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. + +You can configure this plugin through the [preset options](../../using-plugins.mdx#docusauruspreset-classic). + +::: + +## Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `lastmod` | `'date' \| 'datetime' \| null` | `null` | `date` is YYYY-MM-DD. `datetime` is a ISO 8601 datetime. `null` is disabled. See [sitemap docs](https://www.sitemaps.org/protocol.html#xmlTagDefinitions). | +| `changefreq` | `string \| null` | `'weekly'` | See [sitemap docs](https://www.sitemaps.org/protocol.html#xmlTagDefinitions) | +| `priority` | `number \| null` | `0.5` | See [sitemap docs](https://www.sitemaps.org/protocol.html#xmlTagDefinitions) | +| `ignorePatterns` | `string[]` | `[]` | A list of glob patterns; matching route paths will be filtered from the sitemap. Note that you may need to include the base URL in here. | +| `filename` | `string` | `sitemap.xml` | The path to the created sitemap file, relative to the output directory. Useful if you have two plugin instances outputting two files. | +| `createSitemapItems` | <code>[CreateSitemapItemsFn](#CreateSitemapItemsFn) \| undefined</code> | `undefined` | An optional function which can be used to transform and / or filter the items in the sitemap. | + +```mdx-code-block +</APITable> +``` + +### Types {#types} + +#### `CreateSitemapItemsFn` {#CreateSitemapItemsFn} + +```ts +type CreateSitemapItemsFn = (params: { + siteConfig: DocusaurusConfig; + routes: RouteConfig[]; + defaultCreateSitemapItems: CreateSitemapItemsFn; +}) => Promise<SitemapItem[]>; +``` + +:::info + +This plugin also respects some site config: + +- [`noIndex`](../docusaurus.config.js.mdx#noIndex): results in no sitemap generated +- [`trailingSlash`](../docusaurus.config.js.mdx#trailingSlash): determines if the URLs in the sitemap have trailing slashes + +::: + +:::note About `lastmod` + +The `lastmod` option will only output a sitemap `<lastmod>` tag if plugins provide [route metadata](../plugin-methods/lifecycle-apis.mdx#addRoute) attributes `sourceFilePath` and/or `lastUpdatedAt`. + +All the official content plugins provide the metadata for routes backed by a content file (Markdown, MDX or React page components), but it is possible third-party plugin authors do not provide this information, and the plugin will not be able to output a `<lastmod>` tag for their routes. + +::: + +### Example configuration {#ex-config} + +You can configure this plugin through preset options or plugin options. + +:::tip + +Most Docusaurus users configure this plugin through the preset options. + +::: + +```js config-tabs +// Preset Options: sitemap +// Plugin Options: @docusaurus/plugin-sitemap + +const config = { + lastmod: 'date', + changefreq: 'weekly', + priority: 0.5, + ignorePatterns: ['/tags/**'], + filename: 'sitemap.xml', + createSitemapItems: async (params) => { + const {defaultCreateSitemapItems, ...rest} = params; + const items = await defaultCreateSitemapItems(rest); + return items.filter((item) => !item.url.includes('/page/')); + }, +}; +``` + +You can find your sitemap at `/sitemap.xml`. diff --git a/website/versioned_docs/version-3.7.0/api/plugins/plugin-svgr.mdx b/website/versioned_docs/version-3.7.0/api/plugins/plugin-svgr.mdx new file mode 100644 index 0000000000..bd5bef1eab --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/plugin-svgr.mdx @@ -0,0 +1,55 @@ +--- +sidebar_position: 7 +slug: /api/plugins/@docusaurus/plugin-svgr +--- + +# 📦 plugin-svgr + +import APITable from '@site/src/components/APITable'; + +An [SVGR](https://react-svgr.com/) plugin to transform SVG files into React components automatically at build time. + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-svgr +``` + +:::tip + +If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. + +You can configure this plugin through the [preset options](../../using-plugins.mdx#docusauruspreset-classic). + +::: + +## Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `svgrConfig` | `object` | `{}` | The [SVGR config options](https://react-svgr.com/docs/options/), forwarded as is | + +```mdx-code-block +</APITable> +``` + +### Example configuration {#ex-config} + +You can configure this plugin through plugin options. + +```js config-tabs +// Preset Options: svgr +// Plugin Options: @docusaurus/plugin-svgr + +const config = { + svgrConfig: { + /* SVGR config */ + }, +}; +``` diff --git a/website/versioned_docs/version-3.7.0/api/plugins/plugin-vercel-analytics.mdx b/website/versioned_docs/version-3.7.0/api/plugins/plugin-vercel-analytics.mdx new file mode 100644 index 0000000000..4c1e966843 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/plugins/plugin-vercel-analytics.mdx @@ -0,0 +1,57 @@ +--- +sidebar_position: 11 +slug: /api/plugins/@docusaurus/plugin-vercel-analytics +--- + +# 📦 plugin-vercel-analytics + +import APITable from '@site/src/components/APITable'; + +[Vercel Analytics](https://vercel.com/docs/analytics) provides comprehensive insights into your website's visitors, tracking top pages, referrers, and demographics like location, operating systems, and browser info. + +:::warning production only + +This plugin is always inactive in development and **only active in production** (`docusaurus build`) to avoid polluting the analytics statistics. + +::: + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-vercel-analytics +``` + +## Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `mode` | `string` | `'auto'` | Override the automatic environment detection. Read the [official docs](https://vercel.com/docs/analytics/package#mode) for details. | +| `debug` | `boolean` | `undefined` | Enable browser console logging of analytics events. Read the [official docs](https://vercel.com/docs/analytics/package#debug) for details. | + +```mdx-code-block +</APITable> +``` + +### Example configuration {#ex-config} + +You can configure this plugin through plugin options. + +```js title="docusaurus.config.js" +export default { + plugins: [ + [ + 'vercel-analytics', + { + debug: true, + mode: 'auto', + }, + ], + ], +}; +``` diff --git a/website/versioned_docs/version-3.7.0/api/themes/_category_.yml b/website/versioned_docs/version-3.7.0/api/themes/_category_.yml new file mode 100644 index 0000000000..a0ceda5d59 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/themes/_category_.yml @@ -0,0 +1,5 @@ +label: Themes +position: 3 +link: + type: doc + id: themes-overview # Dogfood using a "local id" diff --git a/website/versioned_docs/version-3.7.0/api/themes/overview.mdx b/website/versioned_docs/version-3.7.0/api/themes/overview.mdx new file mode 100644 index 0000000000..98084d7418 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/themes/overview.mdx @@ -0,0 +1,34 @@ +--- +sidebar_position: 0 +id: themes-overview +sidebar_label: Themes overview +slug: /api/themes +--- + +# Docusaurus themes + +We provide official Docusaurus themes. + +## Main themes {#main-themes} + +The main themes implement the user interface for the [docs](../plugins/plugin-content-docs.mdx), [blog](../plugins/plugin-content-blog.mdx) and [pages](../plugins/plugin-content-pages.mdx) plugins. + +- [@docusaurus/theme-classic](./theme-classic.mdx) +- 🚧 other themes are planned + +:::warning + +The goal is to have all themes share the exact same features, user-experience and configuration. + +Only the UI design and underlying styling framework should change, and you should be able to change theme easily. + +We are not there yet: only the classic theme is production ready. + +::: + +## Enhancement themes {#enhancement-themes} + +These themes will enhance the existing main themes with additional user-interface related features. + +- [@docusaurus/theme-live-codeblock](./theme-live-codeblock.mdx) +- [@docusaurus/theme-search-algolia](./theme-search-algolia.mdx) diff --git a/website/versioned_docs/version-3.7.0/api/themes/theme-classic.mdx b/website/versioned_docs/version-3.7.0/api/themes/theme-classic.mdx new file mode 100644 index 0000000000..5073013923 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/themes/theme-classic.mdx @@ -0,0 +1,63 @@ +--- +sidebar_position: 2 +slug: /api/themes/@docusaurus/theme-classic +--- + +# 📦 theme-classic + +import APITable from '@site/src/components/APITable'; + +The classic theme for Docusaurus. + +You can refer to the [theme configuration page](theme-configuration.mdx) for more details on the configuration. + +```bash npm2yarn +npm install --save @docusaurus/theme-classic +``` + +:::tip + +If you have installed `@docusaurus/preset-classic`, you don't need to install it as a dependency. + +::: + +## Configuration {#configuration} + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `customCss` | <code>string[] \| string</code> | `[]` | Stylesheets to be imported globally as [client modules](../../advanced/client.mdx#client-modules). Relative paths are resolved against the site directory. | + +```mdx-code-block +</APITable> +``` + +:::note + +Most configuration for the theme is done in `themeConfig`, which can be found in [theme configuration](./theme-configuration.mdx). + +::: + +### Example configuration {#ex-config} + +You can configure this theme through preset options or plugin options. + +:::tip + +Most Docusaurus users configure this plugin through the preset options. + +::: + +```js config-tabs +// Preset Options: theme +// Plugin Options: @docusaurus/theme-classic + +const config = { + customCss: './src/css/custom.css', +}; +``` diff --git a/website/versioned_docs/version-3.7.0/api/themes/theme-configuration.mdx b/website/versioned_docs/version-3.7.0/api/themes/theme-configuration.mdx new file mode 100644 index 0000000000..7be1ba2b64 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/themes/theme-configuration.mdx @@ -0,0 +1,1157 @@ +--- +sidebar_position: 1 +sidebar_label: Configuration +slug: /api/themes/configuration +toc_max_heading_level: 4 +--- + +# Theme configuration + +import APITable from '@site/src/components/APITable'; + +This configuration applies to all [main themes](./overview.mdx). + +## Common {#common} + +### Color mode {#color-mode---dark-mode} + +The classic theme provides by default light and dark mode support, with a navbar switch for the user. + +It is possible to customize the color mode support within the `colorMode` object. + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `defaultMode` | <code>'light' \| 'dark'</code> | `'light'` | The color mode when user first visits the site. | +| `disableSwitch` | `boolean` | `false` | Hides the switch in the navbar. Useful if you want to support a single color mode. | +| `respectPrefersColorScheme` | `boolean` | `false` | Whether to use the `prefers-color-scheme` media-query, using user system preferences, instead of the hardcoded `defaultMode`. | + +```mdx-code-block +</APITable> +``` + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + // highlight-start + colorMode: { + defaultMode: 'light', + disableSwitch: false, + respectPrefersColorScheme: false, + }, + // highlight-end + }, +}; +``` + +:::warning + +With `respectPrefersColorScheme: true`, the `defaultMode` is overridden by user system preferences. + +If you only want to support one color mode, you likely want to ignore user system preferences. + +::: + +### Meta image {#meta-image} + +You can configure a default image that will be used for your meta tag, in particular `og:image` and `twitter:image`. + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `image` | `string` | `undefined` | The meta image URL for the site. Relative to your site's "static" directory. Cannot be SVGs. Can be external URLs too. | + +```mdx-code-block +</APITable> +``` + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + // highlight-next-line + image: 'img/docusaurus.png', + }, +}; +``` + +### Metadata {#metadata} + +You can configure additional HTML metadata (and override existing ones). + +Accepted fields: + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `metadata` | `Metadata[]` | `[]` | Any field will be directly passed to the `<meta />` tag. Possible fields include `id`, `name`, `property`, `content`, `itemprop`, etc. | + +```mdx-code-block +</APITable> +``` + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + // highlight-next-line + metadata: [{name: 'twitter:card', content: 'summary'}], + }, +}; +``` + +### Announcement bar {#announcement-bar} + +Sometimes you want to announce something in your website. Just for such a case, you can add an announcement bar. This is a non-fixed and optionally dismissible panel above the navbar. All configuration are in the `announcementBar` object. + +Accepted fields: + +```mdx-code-block +<APITable name="announcement-bar"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `id` | `string` | `'announcement-bar'` | Any value that will identify this message. | +| `content` | `string` | `''` | The text content of the announcement. HTML will be interpolated. | +| `backgroundColor` | `string` | `'#fff'` | Background color of the entire bar. | +| `textColor` | `string` | `'#000'` | Announcement text color. | +| `isCloseable` | `boolean` | `true` | Whether this announcement can be dismissed with a '×' button. | + +```mdx-code-block +</APITable> +``` + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + // highlight-start + 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, + }, + // highlight-end + }, +}; +``` + +## Plugins + +Our [main themes](./overview.mdx) offer additional theme configuration options for Docusaurus core content plugins. + +### Docs + +```mdx-code-block +<APITable name="navbar-overview"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `versionPersistence` | `'localStorage' \| 'none'` | `undefined` | Defines the browser persistence of the preferred docs version. | +| `sidebar.hideable` | `boolean` | `false` | Show a hide button at the bottom of the sidebar. | +| `sidebar.autoCollapseCategories` | `boolean` | `false` | Automatically collapse all sibling categories of the one you navigate to. | + +```mdx-code-block +</APITable> +``` + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + docs: { + // highlight-start + versionPersistence: 'localStorage', + sidebar: { + hideable: false, + autoCollapseCategories: false, + }, + // highlight-end + }, + }, +}; +``` + +### Blog + +```mdx-code-block +<APITable name="navbar-overview"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `sidebar.groupByYear` | `boolean` | `true` | Group sidebar blog posts by years. | + +```mdx-code-block +</APITable> +``` + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + blog: { + // highlight-start + sidebar: { + groupByYear: true, + }, + // highlight-end + }, + }, +}; +``` + +## Navbar {#navbar} + +Accepted fields: + +```mdx-code-block +<APITable name="navbar-overview"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `title` | `string` | `undefined` | Title for the navbar. | +| `logo` | _See below_ | `undefined` | Customization of the logo object. | +| `items` | `NavbarItem[]` | `[]` | A list of navbar items. See specification below. | +| `hideOnScroll` | `boolean` | `false` | Whether the navbar is hidden when the user scrolls down. | +| `style` | <code>'primary' \| 'dark'</code> | Same as theme | Sets the navbar style, ignoring the dark/light theme. | + +```mdx-code-block +</APITable> +``` + +### Navbar logo {#navbar-logo} + +The logo can be placed in [static folder](static-assets.mdx). Logo URL is set to base URL of your site by default. Although you can specify your own URL for the logo, if it is an external link, it will open in a new tab. In addition, you can override a value for the target attribute of logo link, it can come in handy if you are hosting docs website in a subdirectory of your main website, and in which case you probably do not need a link in the logo to the main website will open in a new tab. + +To improve dark mode support, you can also set a different logo for this mode. + +Accepted fields: + +```mdx-code-block +<APITable name="navbar-logo"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `alt` | `string` | `undefined` | Alt tag for the logo image. | +| `src` | `string` | **Required** | URL to the logo image. Base URL is appended by default. | +| `srcDark` | `string` | `logo.src` | An alternative image URL to use in dark mode. | +| `href` | `string` | `siteConfig.baseUrl` | Link to navigate to when the logo is clicked. | +| `width` | <code>string \| number</code> | `undefined` | Specifies the `width` attribute. | +| `height` | <code>string \| number</code> | `undefined` | Specifies the `height` attribute. | +| `target` | `string` | Calculated based on `href` (external links will open in a new tab, all others in the current one). | The `target` attribute of the link; controls whether the link is opened in a new tab, the current one, or otherwise. | +| `className` | `string` | `undefined` | CSS class applied to the image. | +| `style` | `object` | `undefined` | CSS inline style object. React/JSX flavor, using camelCase properties. | + +```mdx-code-block +</APITable> +``` + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + title: 'Site Title', + // highlight-start + logo: { + alt: 'Site Logo', + src: 'img/logo.svg', + srcDark: 'img/logo_dark.svg', + href: 'https://docusaurus.io/', + target: '_self', + width: 32, + height: 32, + className: 'custom-navbar-logo-class', + style: {border: 'solid red'}, + }, + // highlight-end + }, + }, +}; +``` + +### Navbar items {#navbar-items} + +You can add items to the navbar via `themeConfig.navbar.items`. + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + // highlight-start + items: [ + { + type: 'doc', + position: 'left', + docId: 'introduction', + label: 'Docs', + }, + {to: 'blog', label: 'Blog', position: 'left'}, + { + type: 'docsVersionDropdown', + position: 'right', + }, + { + type: 'localeDropdown', + position: 'right', + }, + { + href: 'https://github.com/facebook/docusaurus', + position: 'right', + className: 'header-github-link', + 'aria-label': 'GitHub repository', + }, + ], + // highlight-end + }, + }, +}; +``` + +The items can have different behaviors based on the `type` field. The sections below will introduce you to all the types of navbar items available. + +#### Navbar link {#navbar-link} + +By default, Navbar items are regular links (internal or external). + +React Router should automatically apply active link styling to links, but you can use `activeBasePath` in edge cases. For cases in which a link should be active on several different paths (such as when you have multiple doc folders under the same sidebar), you can use `activeBaseRegex`. `activeBaseRegex` is a more flexible alternative to `activeBasePath` and takes precedence over it -- Docusaurus parses it into a regular expression that is tested against the current URL. + +Outbound (external) links automatically get `target="_blank" rel="noopener noreferrer"` attributes. + +Accepted fields: + +```mdx-code-block +<APITable name="navbar-link"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `type` | `'default'` | Optional | Sets the type of this item to a link. | +| `label` | `string` | **Required** | The name to be shown for this item. | +| `html` | `string` | Optional | Same as `label`, but renders pure HTML instead of text content. | +| `to` | `string` | **Required** | Client-side routing, used for navigating within the website. The baseUrl will be automatically prepended to this value. | +| `href` | `string` | **Required** | A full-page navigation, used for navigating outside of the website. **Only one of `to` or `href` should be used.** | +| `prependBaseUrlToHref` | `boolean` | `false` | Prepends the baseUrl to `href` values. | +| `position` | <code>'left' \| 'right'</code> | `'left'` | The side of the navbar this item should appear on. | +| `activeBasePath` | `string` | `to` / `href` | To apply the active class styling on all routes starting with this path. This usually isn't necessary. | +| `activeBaseRegex` | `string` | `undefined` | Alternative to `activeBasePath` if required. | +| `className` | `string` | `''` | Custom CSS class (for styling any item). | + +```mdx-code-block +</APITable> +``` + +:::note + +In addition to the fields above, you can specify other arbitrary attributes that can be applied to a HTML link. + +::: + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + items: [ + // highlight-start + { + to: 'docs/introduction', + // Only one of "to" or "href" should be used + // href: 'https://www.facebook.com', + label: 'Introduction', + // Only one of "label" or "html" should be used + // html: '<b>Introduction</b>' + position: 'left', + activeBaseRegex: 'docs/(next|v8)', + target: '_blank', + }, + // highlight-end + ], + }, + }, +}; +``` + +#### Navbar dropdown {#navbar-dropdown} + +Navbar items of the type `dropdown` has the additional `items` field, an inner array of navbar items. + +Navbar dropdown items only accept the following **"link-like" item types**: + +- [Navbar link](#navbar-link) +- [Navbar doc link](#navbar-doc-link) +- [Navbar docs version](#navbar-docs-version) +- [Navbar doc sidebar](#navbar-doc-sidebar) +- [Navbar with custom HTML](#navbar-with-custom-html) + +Note that the dropdown base item is a clickable link as well, so this item can receive any of the props of a [plain navbar link](#navbar-link). + +Accepted fields: + +```mdx-code-block +<APITable name="navbar-dropdown"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `type` | `'dropdown'` | Optional | Sets the type of this item to a dropdown. | +| `label` | `string` | **Required** | The name to be shown for this item. | +| `items` | <code>[LinkLikeItem](#navbar-dropdown)[]</code> | **Required** | The items to be contained in the dropdown. | +| `position` | <code>'left' \| 'right'</code> | `'left'` | The side of the navbar this item should appear on. | + +```mdx-code-block +</APITable> +``` + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + items: [ + // highlight-start + { + type: 'dropdown', + label: 'Community', + position: 'left', + items: [ + { + label: 'Facebook', + href: 'https://www.facebook.com', + }, + { + type: 'doc', + label: 'Social', + docId: 'social', + }, + // ... more items + ], + }, + // highlight-end + ], + }, + }, +}; +``` + +#### Navbar doc link {#navbar-doc-link} + +If you want to link to a specific doc, this special navbar item type will render the link to the doc of the provided `docId`. It will get the class `navbar__link--active` as long as you browse a doc of the same sidebar. + +Accepted fields: + +```mdx-code-block +<APITable name="navbar-doc-link"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `type` | `'doc'` | **Required** | Sets the type of this item to a doc link. | +| `docId` | `string` | **Required** | The ID of the doc that this item links to. | +| `label` | `string` | `docId` | The name to be shown for this item. | +| `position` | <code>'left' \| 'right'</code> | `'left'` | The side of the navbar this item should appear on. | +| `docsPluginId` | `string` | `'default'` | The ID of the docs plugin that the doc belongs to. | + +```mdx-code-block +</APITable> +``` + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + items: [ + // highlight-start + { + type: 'doc', + position: 'left', + docId: 'introduction', + label: 'Docs', + }, + // highlight-end + ], + }, + }, +}; +``` + +#### Navbar linked to a sidebar {#navbar-doc-sidebar} + +You can link a navbar item to the first document link (which can be a doc link or a generated category index) of a given sidebar without having to hardcode a doc ID. + +Accepted fields: + +```mdx-code-block +<APITable name="navbar-doc-sidebar"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `type` | `'docSidebar'` | **Required** | Sets the type of this navbar item to a sidebar's first document. | +| `sidebarId` | `string` | **Required** | The ID of the sidebar that this item is linked to. | +| `label` | `string` | First document link's sidebar label | The name to be shown for this item. | +| `position` | <code>'left' \| 'right'</code> | `'left'` | The side of the navbar this item should appear on. | +| `docsPluginId` | `string` | `'default'` | The ID of the docs plugin that the sidebar belongs to. | + +```mdx-code-block +</APITable> +``` + +:::tip + +Use this navbar item type if your sidebar is updated often and the order is not stable. + +::: + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + items: [ + // highlight-start + { + type: 'docSidebar', + position: 'left', + sidebarId: 'api', + label: 'API', + }, + // highlight-end + ], + }, + }, +}; +``` + +```js title="sidebars.js" +export default { + tutorial: [ + { + type: 'autogenerated', + dirName: 'guides', + }, + ], + api: [ + // highlight-next-line + 'cli', // The navbar item will be linking to this doc + 'docusaurus-core', + { + type: 'autogenerated', + dirName: 'api', + }, + ], +}; +``` + +#### Navbar docs version dropdown {#navbar-docs-version-dropdown} + +If you use docs with versioning, this special navbar item type that will render a dropdown with all your site's available versions. + +The user will be able to switch from one version to another, while staying on the same doc (as long as the doc ID is constant across versions). + +Accepted fields: + +```mdx-code-block +<APITable name="navbar-docs-version-dropdown"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `type` | `'docsVersionDropdown'` | **Required** | Sets the type of this item to a docs version dropdown. | +| `position` | <code>'left' \| 'right'</code> | `'left'` | The side of the navbar this item should appear on. | +| `dropdownItemsBefore` | <code>[LinkLikeItem](#navbar-dropdown)[]</code> | `[]` | Add additional dropdown items at the beginning of the dropdown. | +| `dropdownItemsAfter` | <code>[LinkLikeItem](#navbar-dropdown)[]</code> | `[]` | Add additional dropdown items at the end of the dropdown. | +| `docsPluginId` | `string` | `'default'` | The ID of the docs plugin that the doc versioning belongs to. | +| `dropdownActiveClassDisabled` | `boolean` | `false` | Do not add the link active class when browsing docs. | + +```mdx-code-block +</APITable> +``` + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + items: [ + // highlight-start + { + type: 'docsVersionDropdown', + position: 'left', + dropdownItemsAfter: [{to: '/versions', label: 'All versions'}], + dropdownActiveClassDisabled: true, + }, + // highlight-end + ], + }, + }, +}; +``` + +#### Navbar docs version {#navbar-docs-version} + +If you use docs with versioning, this special navbar item type will link to the active/browsed version of your doc (depends on the current URL), and fallback to the latest version. + +Accepted fields: + +```mdx-code-block +<APITable name="navbar-docs-version"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `type` | `'docsVersion'` | **Required** | Sets the type of this item to a doc version link. | +| `label` | `string` | The active/latest version label. | The name to be shown for this item. | +| `to` | `string` | The active/latest version. | The internal link that this item points to. | +| `position` | <code>'left' \| 'right'</code> | `'left'` | The side of the navbar this item should appear on. | +| `docsPluginId` | `string` | `'default'` | The ID of the docs plugin that the doc versioning belongs to. | + +```mdx-code-block +</APITable> +``` + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + items: [ + // highlight-start + { + type: 'docsVersion', + position: 'left', + to: '/path', + label: 'label', + }, + // highlight-end + ], + }, + }, +}; +``` + +#### Navbar locale dropdown {#navbar-locale-dropdown} + +If you use the [i18n feature](../../i18n/i18n-introduction.mdx), this special navbar item type will render a dropdown with all your site's available locales. + +The user will be able to switch from one locale to another, while staying on the same page. + +Accepted fields: + +```mdx-code-block +<APITable name="navbar-locale-dropdown"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `type` | `'localeDropdown'` | **Required** | Sets the type of this item to a locale dropdown. | +| `position` | <code>'left' \| 'right'</code> | `'left'` | The side of the navbar this item should appear on. | +| `dropdownItemsBefore` | <code>[LinkLikeItem](#navbar-dropdown)[]</code> | `[]` | Add additional dropdown items at the beginning of the dropdown. | +| `dropdownItemsAfter` | <code>[LinkLikeItem](#navbar-dropdown)[]</code> | `[]` | Add additional dropdown items at the end of the dropdown. | +| `queryString` | `string` | `undefined` | The query string to be appended to the URL. | + +```mdx-code-block +</APITable> +``` + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + items: [ + // highlight-start + { + type: 'localeDropdown', + position: 'left', + dropdownItemsAfter: [ + { + to: 'https://my-site.com/help-us-translate', + label: 'Help us translate', + }, + ], + }, + // highlight-end + ], + }, + }, +}; +``` + +#### Navbar search {#navbar-search} + +If you use the [search](../../search.mdx), the search bar will be the rightmost element in the navbar. + +However, with this special navbar item type, you can change the default location. + +```mdx-code-block +<APITable name="navbar-search"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `type` | `'search'` | **Required** | Sets the type of this item to a search bar. | +| `position` | <code>'left' \| 'right'</code> | `'left'` | The side of the navbar this item should appear on. | +| `className` | `string` | / | Custom CSS class for this navbar item. | + +```mdx-code-block +</APITable> +``` + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + items: [ + // highlight-start + { + type: 'search', + position: 'right', + }, + // highlight-end + ], + }, + }, +}; +``` + +#### Navbar with custom HTML {#navbar-with-custom-html} + +You can also render your own HTML markup inside a navbar item using this navbar item type. + +```mdx-code-block +<APITable name="navbar-html"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `type` | `'html'` | **Required** | Sets the type of this item to a HTML element. | +| `position` | <code>'left' \| 'right'</code> | `'left'` | The side of the navbar this item should appear on. | +| `className` | `string` | `''` | Custom CSS class for this navbar item. | +| `value` | `string` | `''` | Custom HTML to be rendered inside this navbar item. | + +```mdx-code-block +</APITable> +``` + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + items: [ + // highlight-start + { + type: 'html', + position: 'right', + value: '<button>Give feedback</button>', + }, + // highlight-end + ], + }, + }, +}; +``` + +### Auto-hide sticky navbar {#auto-hide-sticky-navbar} + +You can enable this cool UI feature that automatically hides the navbar when a user starts scrolling down the page, and show it again when the user scrolls up. + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + // highlight-next-line + hideOnScroll: true, + }, + }, +}; +``` + +### Navbar style {#navbar-style} + +You can set the static Navbar style without disabling the theme switching ability. The selected style will always apply no matter which theme user have selected. + +Currently, there are two possible style options: `dark` and `primary` (based on the `--ifm-color-primary` color). You can see the styles preview in the [Infima documentation](https://infima.dev/docs/components/navbar/). + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + // highlight-next-line + style: 'primary', + }, + }, +}; +``` + +## CodeBlock {#codeblock} + +Docusaurus uses [Prism React Renderer](https://github.com/FormidableLabs/prism-react-renderer) to highlight code blocks. All configuration are in the `prism` object. + +Accepted fields: + +```mdx-code-block +<APITable name="codeblock"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `theme` | `PrismTheme` | `palenight` | The Prism theme to use for light-theme code blocks. | +| `darkTheme` | `PrismTheme` | `palenight` | The Prism theme to use for dark-theme code blocks. | +| `defaultLanguage` | `string` | `undefined` | The default language to use for code blocks not declaring any explicit language. | +| `magicComments` | `MagicCommentConfig[]` | _see below_ | The list of [magic comments](../../guides/markdown-features/markdown-features-code-blocks.mdx#custom-magic-comments). | + +```mdx-code-block +</APITable> +``` + +```ts +type MagicCommentConfig = { + className: string; + line?: string; + block?: {start: string; end: string}; +}; +``` + +```js +const defaultMagicComments = [ + { + className: 'theme-code-block-highlighted-line', + line: 'highlight-next-line', + block: {start: 'highlight-start', end: 'highlight-end'}, + }, +]; +``` + +### Theme {#theme} + +By default, we use [Palenight](https://github.com/FormidableLabs/prism-react-renderer/blob/master/packages/prism-react-renderer/src/themes/palenight.ts) as syntax highlighting theme. You can specify a custom theme from the [list of available themes](https://github.com/FormidableLabs/prism-react-renderer/tree/master/packages/prism-react-renderer/src/themes). You may also use a different syntax highlighting theme when the site is in dark mode. + +Example configuration: + +```js title="docusaurus.config.js" +import {themes as prismThemes} from 'prism-react-renderer'; + +export default { + themeConfig: { + prism: { + // highlight-start + theme: prismThemes.github, + darkTheme: prismThemes.dracula, + // highlight-end + }, + }, +}; +``` + +:::note + +If you use the line highlighting Markdown syntax, you might need to specify a different highlight background color for the dark mode syntax highlighting theme. Refer to the [docs for guidance](../../guides/markdown-features/markdown-features-code-blocks.mdx#line-highlighting). + +::: + +### Default language {#default-language} + +You can set a default language for code blocks if no language is added after the opening triple backticks (i.e. ```). Note that a valid [language name](https://prismjs.com/#supported-languages) must be passed. + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + prism: { + // highlight-next-line + defaultLanguage: 'javascript', + }, + }, +}; +``` + +## Footer {#footer-1} + +You can add logo and a copyright to the footer via `themeConfig.footer`. Logo can be placed in [static folder](static-assets.mdx). Logo URL works in the same way of the navbar logo. + +Accepted fields: + +```mdx-code-block +<APITable name="footer"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `logo` | `Logo` | `undefined` | Customization of the logo object. See [Navbar logo](#navbar-logo) for details. | +| `copyright` | `string` | `undefined` | The copyright message to be displayed at the bottom, also supports custom HTML. | +| `style` | <code>'dark' \| 'light'</code> | `'light'` | The color theme of the footer component. | +| `links` | <code>(Column \| FooterLink)[]</code> | `[]` | The link groups to be present. | + +```mdx-code-block +</APITable> +``` + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + // highlight-start + footer: { + logo: { + alt: 'Meta Open Source Logo', + src: 'img/meta_oss_logo.png', + href: 'https://opensource.fb.com', + width: 160, + height: 51, + }, + copyright: `Copyright © ${new Date().getFullYear()} My Project, Inc. Built with Docusaurus.`, + }, + // highlight-end + }, +}; +``` + +### Footer Links {#footer-links} + +You can add links to the footer via `themeConfig.footer.links`. There are two types of footer configurations: **multi-column footers** and **simple footers**. + +Multi-column footer links have a `title` and a list of `FooterItem`s for each column. + +```mdx-code-block +<APITable name="footer-links"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `title` | `string` | `undefined` | Label of the section of these links. | +| `items` | `FooterItem[]` | `[]` | Links in this section. | + +```mdx-code-block +</APITable> +``` + +Accepted fields of each `FooterItem`: + +```mdx-code-block +<APITable name="footer-items"> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `label` | `string` | **Required** | Text to be displayed for this link. | +| `to` | `string` | **Required** | Client-side routing, used for navigating within the website. The baseUrl will be automatically prepended to this value. | +| `href` | `string` | **Required** | A full-page navigation, used for navigating outside of the website. **Only one of `to` or `href` should be used.** | +| `html` | `string` | `undefined` | Renders the HTML pass-through instead of a simple link. In case `html` is used, no other options should be provided. | + +```mdx-code-block +</APITable> +``` + +Example multi-column configuration: + +```js title="docusaurus.config.js" +export default { + footer: { + // highlight-start + links: [ + { + title: 'Docs', + items: [ + { + label: 'Style Guide', + to: 'docs/', + }, + { + label: 'Second Doc', + to: 'docs/doc2/', + }, + ], + }, + { + title: 'Community', + items: [ + { + label: 'Stack Overflow', + href: 'https://stackoverflow.com/questions/tagged/docusaurus', + }, + { + label: 'Discord', + href: 'https://discordapp.com/invite/docusaurus', + }, + { + label: 'X', + href: 'https://x.com/docusaurus', + }, + { + html: ` + <a href="https://www.netlify.com" target="_blank" rel="noreferrer noopener" aria-label="Deploys by Netlify"> + <img src="https://www.netlify.com/img/global/badges/netlify-color-accent.svg" alt="Deploys by Netlify" width="114" height="51" /> + </a> + `, + }, + ], + }, + ], + // highlight-end + }, +}; +``` + +A simple footer just has a list of `FooterItem`s displayed in a row. + +Example simple configuration: + +```js title="docusaurus.config.js" +export default { + footer: { + // highlight-start + links: [ + { + label: 'Stack Overflow', + href: 'https://stackoverflow.com/questions/tagged/docusaurus', + }, + { + label: 'Discord', + href: 'https://discordapp.com/invite/docusaurus', + }, + { + label: 'X', + href: 'https://x.com/docusaurus', + }, + { + html: ` + <a href="https://www.netlify.com" target="_blank" rel="noreferrer noopener" aria-label="Deploys by Netlify"> + <img src="https://www.netlify.com/img/global/badges/netlify-color-accent.svg" alt="Deploys by Netlify" width="114" height="51" /> + </a> + `, + }, + ], + // highlight-end + }, +}; +``` + +## Table of Contents {#table-of-contents} + +You can adjust the default table of contents via `themeConfig.tableOfContents`. + +```mdx-code-block +<APITable> +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `minHeadingLevel` | `number` | `2` | The minimum heading level shown in the table of contents. Must be between 2 and 6 and lower or equal to the max value. | +| `maxHeadingLevel` | `number` | `3` | Max heading level displayed in the TOC. Should be an integer between 2 and 6. | + +```mdx-code-block +</APITable> +``` + +Example configuration: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + // highlight-start + tableOfContents: { + minHeadingLevel: 2, + maxHeadingLevel: 5, + }, + // highlight-end + }, +}; +``` + +## Hooks {#hooks} + +### `useColorMode` {#use-color-mode} + +A React hook to access the color context. This context contains functions for setting light and dark mode and exposes boolean variable, indicating which mode is currently in use. + +Usage example: + +```jsx +import React from 'react'; +// highlight-next-line +import {useColorMode} from '@docusaurus/theme-common'; + +const Example = () => { + // highlight-next-line + const {colorMode, setColorMode} = useColorMode(); + + return <h1>Dark mode is now {colorMode === 'dark' ? 'on' : 'off'}</h1>; +}; +``` + +:::note + +The component calling `useColorMode` must be a child of the `Layout` component. + +```jsx +function ExamplePage() { + return ( + <Layout> + <Example /> + </Layout> + ); +} +``` + +::: + +## i18n {#i18n} + +Read the [i18n introduction](../../i18n/i18n-introduction.mdx) first. + +### Translation files location {#translation-files-location} + +- **Base path**: `website/i18n/[locale]/docusaurus-theme-[themeName]` +- **Multi-instance path**: N/A +- **JSON files**: extracted with [`docusaurus write-translations`](../../cli.mdx#docusaurus-write-translations-sitedir) +- **Markdown files**: N/A + +### Example file-system structure {#example-file-system-structure} + +```bash +website/i18n/[locale]/docusaurus-theme-classic +│ +│ # translations for the theme +├── navbar.json +└── footer.json +``` diff --git a/website/versioned_docs/version-3.7.0/api/themes/theme-live-codeblock.mdx b/website/versioned_docs/version-3.7.0/api/themes/theme-live-codeblock.mdx new file mode 100644 index 0000000000..212c910b3e --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/themes/theme-live-codeblock.mdx @@ -0,0 +1,29 @@ +--- +sidebar_position: 3 +slug: /api/themes/@docusaurus/theme-live-codeblock +--- + +# 📦 theme-live-codeblock + +This theme provides a `@theme/CodeBlock` component that is powered by [react-live](https://commerce.nearform.com/open-source/react-live/). You can read more on [interactive code editor](../../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor) documentation. + +```bash npm2yarn +npm install --save @docusaurus/theme-live-codeblock +``` + +### Configuration {#configuration} + +```js title="docusaurus.config.js" +export default { + plugins: ['@docusaurus/theme-live-codeblock'], + themeConfig: { + liveCodeBlock: { + /** + * The position of the live playground, above or under the editor + * Possible values: "top" | "bottom" + */ + playgroundPosition: 'bottom', + }, + }, +}; +``` diff --git a/website/versioned_docs/version-3.7.0/api/themes/theme-mermaid.mdx b/website/versioned_docs/version-3.7.0/api/themes/theme-mermaid.mdx new file mode 100644 index 0000000000..d9a2059535 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/themes/theme-mermaid.mdx @@ -0,0 +1,25 @@ +--- +sidebar_position: 5 +slug: /api/themes/@docusaurus/theme-mermaid +--- + +# 📦 theme-mermaid + +This theme provides a `@theme/Mermaid` component that is powered by [mermaid](https://mermaid-js.github.io/). You can read more on [diagrams](../../guides/markdown-features/markdown-features-diagrams.mdx) documentation. + +```bash npm2yarn +npm install --save @docusaurus/theme-mermaid +``` + +## Configuration {#configuration} + +```js title="docusaurus.config.js" +export default { + themes: ['@docusaurus/theme-mermaid'], + // In order for Mermaid code blocks in Markdown to work, + // you also need to enable the Remark plugin with this option + markdown: { + mermaid: true, + }, +}; +``` diff --git a/website/versioned_docs/version-3.7.0/api/themes/theme-search-algolia.mdx b/website/versioned_docs/version-3.7.0/api/themes/theme-search-algolia.mdx new file mode 100644 index 0000000000..f8aa09a99c --- /dev/null +++ b/website/versioned_docs/version-3.7.0/api/themes/theme-search-algolia.mdx @@ -0,0 +1,20 @@ +--- +sidebar_position: 4 +slug: /api/themes/@docusaurus/theme-search-algolia +--- + +# 📦 theme-search-algolia + +This theme provides a `@theme/SearchBar` component that integrates with Algolia DocSearch easily. Combined with `@docusaurus/theme-classic`, it provides a very easy search integration. You can read more on [search](../../search.mdx) documentation. + +```bash npm2yarn +npm install --save @docusaurus/theme-search-algolia +``` + +This theme also adds search page available at `/search` (as swizzlable `SearchPage` component) path with OpenSearch support. You can change this default path via `themeConfig.algolia.searchPagePath`. Use `false` to disable search page. + +:::tip + +If you have installed `@docusaurus/preset-classic`, you don't need to install it as a dependency. + +::: diff --git a/website/versioned_docs/version-3.7.0/assets/docusaurus-asset-example-banner.png b/website/versioned_docs/version-3.7.0/assets/docusaurus-asset-example-banner.png new file mode 100644 index 0000000000..ebe95f5ec8 Binary files /dev/null and b/website/versioned_docs/version-3.7.0/assets/docusaurus-asset-example-banner.png differ diff --git a/website/versioned_docs/version-3.7.0/assets/docusaurus-asset-example.docx b/website/versioned_docs/version-3.7.0/assets/docusaurus-asset-example.docx new file mode 100644 index 0000000000..3c51aea4e7 Binary files /dev/null and b/website/versioned_docs/version-3.7.0/assets/docusaurus-asset-example.docx differ diff --git a/website/versioned_docs/version-3.7.0/assets/docusaurus-asset-example.xyz b/website/versioned_docs/version-3.7.0/assets/docusaurus-asset-example.xyz new file mode 100644 index 0000000000..188262276a Binary files /dev/null and b/website/versioned_docs/version-3.7.0/assets/docusaurus-asset-example.xyz differ diff --git a/website/versioned_docs/version-3.7.0/blog.mdx b/website/versioned_docs/version-3.7.0/blog.mdx new file mode 100644 index 0000000000..468e42f3b9 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/blog.mdx @@ -0,0 +1,766 @@ +--- +description: Deploy a full-featured blog in no time with Docusaurus. +--- + +# Blog + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +The blog feature enables you to deploy a full-featured blog in no time. + +:::info + +Check the [Blog Plugin API Reference documentation](./api/plugins/plugin-content-blog.mdx) for an exhaustive list of options. + +::: + +## Initial setup {#initial-setup} + +To set up your site's blog, start by creating a `blog` directory. + +Then, add an item link to your blog within `docusaurus.config.js`: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + // ... + navbar: { + items: [ + // ... + // highlight-next-line + {to: 'blog', label: 'Blog', position: 'left'}, // or position: 'right' + ], + }, + }, +}; +``` + +## Adding posts {#adding-posts} + +To publish in the blog, create a Markdown file within the blog directory. + +For example, create a file at `website/blog/2019-09-05-hello-docusaurus.md`: + +```md title="website/blog/2019-09-05-hello-docusaurus.md" +--- +title: Welcome Docusaurus +description: This is my first post on Docusaurus. +slug: welcome-docusaurus-v2 +authors: + - name: Joel Marcey + title: Co-creator of Docusaurus 1 + url: https://github.com/JoelMarcey + image_url: https://github.com/JoelMarcey.png + socials: + x: joelmarcey + github: JoelMarcey + - name: Sébastien Lorber + title: Docusaurus maintainer + url: https://sebastienlorber.com + image_url: https://github.com/slorber.png + socials: + x: sebastienlorber + github: slorber +tags: [hello, docusaurus-v2] +image: https://i.imgur.com/mErPwqL.png +hide_table_of_contents: false +--- + +Welcome to this blog. This blog is created with [**Docusaurus 2**](https://docusaurus.io/). + +<!-- truncate --> + +This is my first post on Docusaurus 2. + +A whole bunch of exploration to follow. +``` + +The [front matter](./guides/markdown-features/markdown-features-intro.mdx#front-matter) is useful to add more metadata to your blog post, for example, author information, but Docusaurus will be able to infer all necessary metadata without the front matter. For all possible fields, see [the API documentation](api/plugins/plugin-content-blog.mdx#markdown-front-matter). + +## Blog list {#blog-list} + +The blog's index page (by default, it is at `/blog`) is the _blog list page_, where all blog posts are collectively displayed. + +Use the `<!--truncate-->` marker in your blog post to represent what will be shown as the summary when viewing all published blog posts. Anything above `<!--truncate-->` will be part of the summary. Note that the portion above the truncate marker must be standalone renderable Markdown. For example: + +```md title="website/blog/my-post.md" {7} +--- +title: Markdown blog truncation example +--- + +All these will be part of the blog post summary. + +<!-- truncate --> + +But anything from here on down will not be. +``` + +For files using the `.mdx` extension, use a [MDX](https://mdxjs.com/) comment `{/* truncate */}` instead: + +{/* prettier-ignore */} +```md title="website/blog/my-post.mdx" {7} +--- +title: MDX blog truncation Example +--- + +All these will be part of the blog post summary. + +{/* truncate */} + +But anything from here on down will not be. +``` + +By default, 10 posts are shown on each blog list page, but you can control pagination with the `postsPerPage` option in the plugin configuration. If you set `postsPerPage: 'ALL'`, pagination will be disabled and all posts will be displayed on the first page. You can also add a meta description to the blog list page for better SEO: + +```js title="docusaurus.config.js" +export default { + // ... + presets: [ + [ + '@docusaurus/preset-classic', + { + blog: { + // highlight-start + blogTitle: 'Docusaurus blog!', + blogDescription: 'A Docusaurus powered blog!', + postsPerPage: 'ALL', + // highlight-end + }, + }, + ], + ], +}; +``` + +## Blog sidebar {#blog-sidebar} + +The blog sidebar displays recent blog posts. The default number of items shown is 5, but you can customize with the `blogSidebarCount` option in the plugin configuration. By setting `blogSidebarCount: 0`, the sidebar will be completely disabled, with the container removed as well. This will increase the width of the main container. Specially, if you have set `blogSidebarCount: 'ALL'`, _all_ posts will be displayed. + +You can also alter the sidebar heading text with the `blogSidebarTitle` option. For example, if you have set `blogSidebarCount: 'ALL'`, instead of the default "Recent posts", you may rather make it say "All posts": + +```js title="docusaurus.config.js" +export default { + presets: [ + [ + '@docusaurus/preset-classic', + { + blog: { + // highlight-start + blogSidebarTitle: 'All posts', + blogSidebarCount: 'ALL', + // highlight-end + }, + }, + ], + ], +}; +``` + +## Blog post date {#blog-post-date} + +Docusaurus will extract a `YYYY-MM-DD` date from many patterns such as `YYYY-MM-DD-my-blog-post-title.md` or `YYYY/MM/DD/my-blog-post-title.md`. This enables you to easily group blog posts by year, by month, or to use a flat structure. + +<details> +<summary>Supported date extraction patterns</summary> + +| Pattern | Example | +| --- | --- | +| Single file | `2021-05-28-my-blog-post-title.md` | +| MDX file | `2021-05-28-my-blog-post-title.mdx` | +| Single folder + `index.md` | `2021-05-28-my-blog-post-title/index.md` | +| Folder named by date | `2021-05-28/my-blog-post-title.md` | +| Nested folders by date | `2021/05/28/my-blog-post-title.md` | +| Partially nested folders by date | `2021/05-28-my-blog-post-title.md` | +| Nested folders + `index.md` | `2021/05/28/my-blog-post-title/index.md` | +| Date in the middle of path | `category/2021/05-28-my-blog-post-title.md` | + +Docusaurus can extract the date from the posts using any of the naming patterns above. It is advisable to choose one pattern and apply it to all posts to avoid confusion. + +</details> + +:::tip + +Using a folder can be convenient to co-locate blog post images alongside the Markdown file. + +::: + +This naming convention is optional, and you can also provide the date as front matter. Since the front matter follows YAML syntax where the datetime notation is supported, you can use front matter if you need more fine-grained publish dates. For example, if you have multiple posts published on the same day, you can order them according to the time of the day: + +```md title="earlier-post.md" +--- +date: 2021-09-13T10:00 +--- +``` + +```md title="later-post.md" +--- +date: 2021-09-13T18:00 +--- +``` + +## Blog post authors {#blog-post-authors} + +Use the `authors` front matter field to declare blog post authors. An author should have at least a `name` or an `image_url`. Docusaurus uses information like `url`, `email`, and `title`, but any other information is allowed. + +### Inline authors {#inline-authors} + +Blog post authors can be declared directly inside the front matter: + +```mdx-code-block +<Tabs groupId="author-front-matter"> +<TabItem value="single" label="Single author"> +``` + +```md title="my-blog-post.md" +--- +authors: + name: Joel Marcey + title: Co-creator of Docusaurus 1 + url: https://github.com/JoelMarcey + image_url: https://github.com/JoelMarcey.png + email: jimarcey@gmail.com + socials: + x: joelmarcey + github: JoelMarcey +--- +``` + +```mdx-code-block +</TabItem> +<TabItem value="multiple" label="Multiple authors"> +``` + +```md title="my-blog-post.md" +--- +authors: + - name: Joel Marcey + title: Co-creator of Docusaurus 1 + url: https://github.com/JoelMarcey + image_url: https://github.com/JoelMarcey.png + email: jimarcey@gmail.com + socials: + x: joelmarcey + github: JoelMarcey + - name: Sébastien Lorber + title: Docusaurus maintainer + url: https://sebastienlorber.com + image_url: https://github.com/slorber.png + socials: + x: sebastienlorber + github: slorber +--- +``` + +```mdx-code-block +</TabItem> +</Tabs> +``` + +:::tip + +This option works best to get started, or for casual, irregular authors. + +::: + +:::info + +Prefer using the `authors` front matter, but the legacy `author_*` front matter remains supported: + +```md title="my-blog-post.md" +--- +author: Joel Marcey +author_title: Co-creator of Docusaurus 1 +author_url: https://github.com/JoelMarcey +author_image_url: https://github.com/JoelMarcey.png +--- +``` + +::: + +### Global authors {#global-authors} + +For regular blog post authors, it can be tedious to maintain authors' information inlined in each blog post. + +It is possible to declare those authors globally in a configuration file: + +```yml title="website/blog/authors.yml" +jmarcey: + name: Joel Marcey + title: Co-creator of Docusaurus 1 + url: https://github.com/JoelMarcey + image_url: https://github.com/JoelMarcey.png + email: jimarcey@gmail.com + socials: + x: joelmarcey + github: JoelMarcey + +slorber: + name: Sébastien Lorber + title: Docusaurus maintainer + url: https://sebastienlorber.com + image_url: https://github.com/slorber.png + socials: + x: sebastienlorber + github: slorber +``` + +:::tip + +Use the `authorsMapPath` plugin option to configure the path. JSON is also supported. + +::: + +In blog posts front matter, you can reference the authors declared in the global configuration file: + +```mdx-code-block +<Tabs groupId="author-front-matter"> +<TabItem value="single" label="Single author"> +``` + +```md title="my-blog-post.md" +--- +authors: jmarcey +--- +``` + +```mdx-code-block +</TabItem> +<TabItem value="multiple" label="Multiple authors"> +``` + +```md title="my-blog-post.md" +--- +authors: [jmarcey, slorber] +--- +``` + +```mdx-code-block +</TabItem> +</Tabs> +``` + +:::info + +The `authors` system is very flexible and can suit more advanced use-case: + +<details> + <summary>Mix inline authors and global authors</summary> + +You can use global authors most of the time, and still use inline authors: + +```md title="my-blog-post.md" +--- +authors: + - jmarcey + - slorber + - name: Inline Author name + title: Inline Author Title + url: https://github.com/inlineAuthor + image_url: https://github.com/inlineAuthor +--- +``` + +</details> + +<details> + <summary>Local override of global authors</summary> + +You can customize the global author's data on per-blog-post basis: + +```md title="my-blog-post.md" +--- +authors: + - key: jmarcey + title: Joel Marcey's new title + - key: slorber + name: Sébastien Lorber's new name +--- +``` + +</details> + +<details> + <summary>Localize the author's configuration file</summary> + +The configuration file can be localized, just create a localized copy of it at: + +```bash +website/i18n/[locale]/docusaurus-plugin-content-blog/authors.yml +``` + +</details> + +::: + +An author, either declared through front matter or through the authors map, needs to have a name or an avatar, or both. If all authors of a post don't have names, Docusaurus will display their avatars compactly. See [this test post](/tests/blog/2022/01/20/image-only-authors) for the effect. + +:::warning Feed generation + +[RSS feeds](#feed) require the author's email to be set for the author to appear in the feed. + +::: + +### Authors pages {#authors-pages} + +The authors pages feature is optional, and mainly useful for multi-author blogs. + +You can activate it independently for each author by adding a `page: true` attribute to the [global author configuration](#global-authors): + +```yml title="website/blog/authors.yml" +slorber: + name: Sébastien Lorber + // highlight-start + page: true # Turns the feature on - route will be /authors/slorber + // highlight-end + +jmarcey: + name: Joel Marcey + // highlight-start + page: + # Turns the feature on - route will be /authors/custom-author-url + permalink: '/custom-author-url' + // highlight-end +``` + +The blog plugin will now generate: + +- a dedicated author page for each author ([example](/blog/authors/slorber)) listing all the blog posts they contributed to +- an authors index page ([example](/blog/authors)) listing all these authors, in the order they appear in `authors.yml` + +:::warning About inline authors + +Only [global authors](#global-authors) can activate this feature. [Inline authors](#inline-authors) are not supported. + +::: + +## Blog post tags {#blog-post-tags} + +Tags are declared in the front matter and introduce another dimension of categorization. + +It is possible to define tags inline, or to reference predefined tags declared in a [`tags file`](api/plugins/plugin-content-blog.mdx#tags-file) (optional, usually `blog/tags.yml`). + +In the following example: + +- `docusaurus` references a predefined tag key declared in `blog/tags.yml` +- `Releases` is an inline tag, because it does not exist in `blog/tags.yml` + +```md title="blog/my-post.md" +--- +title: 'My blog post' +tags: + - Releases + - docusaurus +--- + +Content +``` + +```yml title="blog/tags.yml" +docusaurus: + label: 'Docusaurus' + permalink: '/docusaurus' + description: 'Blog posts related to the Docusaurus framework' +``` + +## Reading time {#reading-time} + +Docusaurus generates a reading time estimation for each blog post based on word count. We provide an option to customize this. + +```js title="docusaurus.config.js" +export default { + presets: [ + [ + '@docusaurus/preset-classic', + { + blog: { + // highlight-start + showReadingTime: true, // When set to false, the "x min read" won't be shown + readingTime: ({content, frontMatter, defaultReadingTime}) => + defaultReadingTime({content, options: {wordsPerMinute: 300}}), + // highlight-end + }, + }, + ], + ], +}; +``` + +The `readingTime` callback receives three parameters: the blog content text as a string, front matter as a record of string keys and their values, and the default reading time function. It returns a number (reading time in minutes) or `undefined` (disable reading time for this page). + +The default reading time is able to accept additional options: `wordsPerMinute` as a number (default: 300), and `wordBound` as a function from string to boolean. If the string passed to `wordBound` should be a word bound (spaces, tabs, and line breaks by default), the function should return `true`. + +:::tip + +Use the callback for all your customization needs: + +```mdx-code-block +<Tabs> +<TabItem value="disable-per-post" label="Per-post disabling"> +``` + +**Disable reading time on one page:** + +```js title="docusaurus.config.js" +export default { + presets: [ + [ + '@docusaurus/preset-classic', + { + blog: { + showReadingTime: true, + // highlight-start + readingTime: ({content, frontMatter, defaultReadingTime}) => + frontMatter.hide_reading_time + ? undefined + : defaultReadingTime({content}), + // highlight-end + }, + }, + ], + ], +}; +``` + +Usage: + +```md "my-blog-post.md" +--- +hide_reading_time: true +--- + +This page will no longer display the reading time stats! +``` + +```mdx-code-block +</TabItem> +<TabItem value="passing-options" label="Passing options"> +``` + +**Pass options to the default reading time function:** + +```js title="docusaurus.config.js" +export default { + presets: [ + [ + '@docusaurus/preset-classic', + { + blog: { + // highlight-start + readingTime: ({content, defaultReadingTime}) => + defaultReadingTime({content, options: {wordsPerMinute: 100}}), + // highlight-end + }, + }, + ], + ], +}; +``` + +```mdx-code-block +</TabItem> +<TabItem value="using-custom-algo" label="Using custom algorithms"> +``` + +**Use a custom implementation of reading time:** + +```js title="docusaurus.config.js" +import myReadingTime from './myReadingTime'; + +export default { + presets: [ + [ + '@docusaurus/preset-classic', + { + blog: { + // highlight-next-line + readingTime: ({content}) => myReadingTime(content), + }, + }, + ], + ], +}; +``` + +```mdx-code-block +</TabItem> +</Tabs> +``` + +::: + +## Feed {#feed} + +You can generate RSS / Atom / JSON feed by passing `feedOptions`. By default, RSS and Atom feeds are generated. To disable feed generation, set `feedOptions.type` to `null`. + +```ts +type FeedType = 'rss' | 'atom' | 'json'; + +type BlogOptions = { + feedOptions?: { + type?: FeedType | 'all' | FeedType[] | null; + title?: string; + description?: string; + copyright: string; + + language?: string; // possible values: http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes + limit?: number | false | null; // defaults to 20 + // XSLT permits browsers to style and render nicely the feed XML files + xslt?: + | boolean + | { + // + rss?: string | boolean; + atom?: string | boolean; + }; + // Allow control over the construction of BlogFeedItems + createFeedItems?: (params: { + blogPosts: BlogPost[]; + siteConfig: DocusaurusConfig; + outDir: string; + defaultCreateFeedItems: (params: { + blogPosts: BlogPost[]; + siteConfig: DocusaurusConfig; + outDir: string; + }) => Promise<BlogFeedItem[]>; + }) => Promise<BlogFeedItem[]>; + }; +}; +``` + +Example usage: + +```js title="docusaurus.config.js" +export default { + // ... + presets: [ + [ + '@docusaurus/preset-classic', + { + blog: { + // highlight-start + feedOptions: { + type: 'all', + copyright: `Copyright © ${new Date().getFullYear()} Facebook, Inc.`, + 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, + }); + }, + }, + // highlight-end + }, + }, + ], + ], +}; +``` + +The feeds can be found at: + +<Tabs> +<TabItem value="RSS"> + +```text +https://example.com/blog/rss.xml +``` + +</TabItem> +<TabItem value="Atom"> + +```text +https://example.com/blog/atom.xml +``` + +</TabItem> +<TabItem value="JSON"> + +```text +https://example.com/blog/feed.json +``` + +</TabItem> +</Tabs> + +## Advanced topics {#advanced-topics} + +### Blog-only mode {#blog-only-mode} + +You can run your Docusaurus site without a dedicated landing page and instead have your blog's post list page as the index page. Set the `routeBasePath` to be `'/'` to serve the blog through the root route `example.com/` instead of the subroute `example.com/blog/`. + +```js title="docusaurus.config.js" +export default { + // ... + presets: [ + [ + '@docusaurus/preset-classic', + { + // highlight-next-line + docs: false, // Optional: disable the docs plugin + blog: { + // highlight-next-line + routeBasePath: '/', // Serve the blog at the site's root + /* other blog options */ + }, + }, + ], + ], +}; +``` + +:::warning + +Don't forget to delete the existing homepage at `./src/pages/index.js` or else there will be two files mapping to the same route! + +::: + +:::warning + +If you disable the docs plugin, don't forget to delete references to the docs plugin elsewhere in your configuration file. Notably, make sure to remove the docs-related navbar items. + +::: + +:::tip + +There's also a "Docs-only mode" for those who only want to use the docs. Read [Docs-only mode](./guides/docs/docs-introduction.mdx) for detailed instructions or a more elaborate explanation of `routeBasePath`. + +::: + +### Multiple blogs {#multiple-blogs} + +By default, the classic theme assumes only one blog per website and hence includes only one instance of the blog plugin. If you would like to have multiple blogs on a single website, it's possible too! You can add another blog by specifying another blog plugin in the `plugins` option for `docusaurus.config.js`. + +Set the `routeBasePath` to the URL route that you want your second blog to be accessed on. Note that the `routeBasePath` here has to be different from the first blog or else there could be a collision of paths! Also, set `path` to the path to the directory containing your second blog's entries. + +As documented for [multi-instance plugins](./using-plugins.mdx#multi-instance-plugins-and-plugin-ids), you need to assign a unique ID to the plugins. + +```js title="docusaurus.config.js" +export default { + // ... + plugins: [ + [ + '@docusaurus/plugin-content-blog', + { + /** + * Required for any multi-instance plugin + */ + id: 'second-blog', + /** + * URL route for the blog section of your site. + * *DO NOT* include a trailing slash. + */ + routeBasePath: 'my-second-blog', + /** + * Path to data on filesystem relative to site dir. + */ + path: './my-second-blog', + }, + ], + ], +}; +``` + +As an example, we host a second blog [here](/tests/blog). diff --git a/website/versioned_docs/version-3.7.0/browser-support.mdx b/website/versioned_docs/version-3.7.0/browser-support.mdx new file mode 100644 index 0000000000..79c01861d7 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/browser-support.mdx @@ -0,0 +1,106 @@ +--- +description: How to keep a reasonable bundle size while ensuring sufficient browser support. +--- + +# Browser support + +Docusaurus allows sites to define the list of supported browsers through a [browserslist configuration](https://github.com/browserslist/browserslist). + +## Purpose {#purpose} + +Websites need to balance between backward compatibility and bundle size. As old browsers do not support modern APIs or syntax, more code is needed to implement the same functionality. + +For example, you may use the [optional chaining syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining): + +```js +const value = obj?.prop?.val; +``` + +...which unfortunately is only recognized by browser versions released after 2020. To be compatible with earlier browser versions, when building your site for production, our JS loader will transpile your code to a more verbose syntax: + +```js +var _obj, _obj$prop; + +const value = + (_obj = obj) === null || _obj === void 0 + ? void 0 + : (_obj$prop = _obj.prop) === null || _obj$prop === void 0 + ? void 0 + : _obj$prop.val; +``` + +However, this penalizes all other users with increased site load time because the 29-character line now becomes 168 characters—a 6-fold increase! (In practice, it will be better because the names used will be shorter.) As a tradeoff, the JS loader only transpiles the syntax to the degree that's supported by all browser versions defined in the browser list. + +The browser list by default is provided through the `package.json` file as a root `browserslist` field. + +:::warning + +On old browsers, the compiled output will use unsupported (too recent) JS syntax, causing React to fail to initialize and end up with a static website with only HTML/CSS and no JS. + +::: + +## Default values {#default-values} + +Websites initialized with the default classic template has the following in `package.json`: + +```json title="package.json" +{ + "name": "docusaurus", + // ... + // highlight-start + "browserslist": { + "production": [">0.5%", "not dead", "not op_mini all"], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } + // highlight-end + // ... +} +``` + +Explained in natural language, the browsers supported in production are those: + +- With more than 0.5% of market share; _and_ +- Has official support or updates in the past 24 months (the opposite of "dead"); _and_ +- Is not Opera Mini. + +And browsers used in development are: + +- The latest version of Chrome _or_ Firefox _or_ Safari. + +You can "evaluate" any config with the `browserslist` CLI to obtain the actual list: + +```bash +npx browserslist --env="production" +``` + +The output is all browsers supported in production. Below is the output in January 2022: + +```text +and_chr 96 +and_uc 12.12 +chrome 96 +chrome 95 +chrome 94 +edge 96 +firefox 95 +firefox 94 +ie 11 +ios_saf 15.2 +ios_saf 15.0-15.1 +ios_saf 14.5-14.8 +ios_saf 14.0-14.4 +ios_saf 12.2-12.5 +opera 82 +opera 81 +safari 15.1 +safari 14.1 +safari 13.1 +``` + +## Read more {#read-more} + +You may wish to visit the [browserslist documentation](https://github.com/browserslist/browserslist/blob/main/README.md) for more specifications, especially the accepted [query values](https://github.com/browserslist/browserslist/blob/main/README.md#queries) and [best practices](https://github.com/browserslist/browserslist/blob/main/README.md#best-practices). diff --git a/website/versioned_docs/version-3.7.0/cli.mdx b/website/versioned_docs/version-3.7.0/cli.mdx new file mode 100644 index 0000000000..1ec8120b49 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/cli.mdx @@ -0,0 +1,190 @@ +--- +description: Docusaurus provides a set of scripts to help you generate, serve, and deploy your website. +--- + +# CLI + +Docusaurus provides a set of scripts to help you generate, serve, and deploy your website. + +Once your website is bootstrapped, the website source will contain the Docusaurus scripts that you can invoke with your package manager: + +```json title="package.json" +{ + // ... + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids" + } +} +``` + +## Docusaurus CLI commands {#docusaurus-cli-commands} + +Below is a list of Docusaurus CLI commands and their usages: + +### `docusaurus start [siteDir]` {#docusaurus-start-sitedir} + +Builds and serves a preview of your site locally with [Webpack Dev Server](https://webpack.js.org/configuration/dev-server). + +#### Options {#options} + +| Name | Default | Description | +| --- | --- | --- | +| `--port` | `3000` | Specifies the port of the dev server. | +| `--host` | `localhost` | Specify a host to use. For example, if you want your server to be accessible externally, you can use `--host 0.0.0.0`. | +| `--locale` | | Specify site locale to be used. | +| `--hot-only` | `false` | Enables Hot Module Replacement without page refresh as a fallback in case of build failures. More information [here](https://webpack.js.org/configuration/dev-server/#devserverhotonly). | +| `--no-open` | `false` | Do not open the page automatically in the browser. | +| `--config` | `undefined` | Path to Docusaurus config file, default to `[siteDir]/docusaurus.config.js` | +| `--poll [optionalIntervalMs]` | `false` | Use polling of files rather than watching for live reload as a fallback in environments where watching doesn't work. More information [here](https://webpack.js.org/configuration/watch/#watchoptionspoll). | +| `--no-minify` | `false` | Build website without minimizing JS/CSS bundles. | + +:::info + +Please note that some functionality (for example, anchor links) will not work in development. The functionality will work as expected in production. + +::: + +:::info Development over network + +When forwarding port 3000 from a remote server or VM (e.g. GitHub Codespaces), you can run the dev server on `0.0.0.0` to make it listen on the local IP. + +```bash npm2yarn +npm run start -- --host 0.0.0.0 +``` + +::: + +#### Enabling HTTPS {#enabling-https} + +There are multiple ways to obtain a certificate. We will use [mkcert](https://github.com/FiloSottile/mkcert) as an example. + +1. Run `mkcert localhost` to generate `localhost.pem` + `localhost-key.pem` + +2. Run `mkcert -install` to install the cert in your trust store, and restart your browser + +3. Start the app with Docusaurus HTTPS env variables: + +```bash +HTTPS=true SSL_CRT_FILE=localhost.pem SSL_KEY_FILE=localhost-key.pem yarn start +``` + +4. Open `https://localhost:3000/` + +### `docusaurus build [siteDir]` {#docusaurus-build-sitedir} + +Compiles your site for production. + +#### Options {#options-1} + +| Name | Default | Description | +| --- | --- | --- | +| `--dev` | | Builds the website in dev mode, including full React error messages. | +| `--bundle-analyzer` | `false` | Analyze your bundle with the [webpack bundle analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer). | +| `--out-dir` | `build` | The full path for the new output directory, relative to the current workspace. | +| `--config` | `undefined` | Path to Docusaurus config file, default to `[siteDir]/docusaurus.config.js` | +| `--locale` | | Build the site in the specified locale(s). If not specified, all known locales are built. | +| `--no-minify` | `false` | Build website without minimizing JS/CSS bundles. | + +:::info + +For advanced minification of CSS bundle, we use the [advanced cssnano preset](https://github.com/cssnano/cssnano/tree/master/packages/cssnano-preset-advanced) (along with additional several PostCSS plugins) and [level 2 optimization of clean-css](https://github.com/jakubpawlowicz/clean-css#level-2-optimizations). If as a result of this advanced CSS minification you find broken CSS, build your website with the environment variable `USE_SIMPLE_CSS_MINIFIER=true` to minify CSS with the [default cssnano preset](https://github.com/cssnano/cssnano/tree/master/packages/cssnano-preset-default). **Please [fill out an issue](https://github.com/facebook/docusaurus/issues/new?labels=bug%2C+needs+triage&template=bug.md) if you experience CSS minification bugs.** + +You can skip the HTML minification with the environment variable `SKIP_HTML_MINIFICATION=true`. + +::: + +### `docusaurus swizzle [themeName] [componentName] [siteDir]` {#docusaurus-swizzle} + +[Swizzle](./swizzling.mdx) a theme component to customize it. + +```bash npm2yarn +npm run swizzle [themeName] [componentName] [siteDir] + +# Example (leaving out the siteDir to indicate this directory) +npm run swizzle @docusaurus/theme-classic Footer -- --eject +``` + +The swizzle CLI is interactive and will guide you through the whole [swizzle process](./swizzling.mdx). + +#### Options {#options-swizzle} + +| Name | Description | +| --- | --- | +| `themeName` | The name of the theme to swizzle from. | +| `componentName` | The name of the theme component to swizzle. | +| `--list` | Display components available for swizzling | +| `--eject` | [Eject](./swizzling.mdx#ejecting) the theme component | +| `--wrap` | [Wrap](./swizzling.mdx#wrapping) the theme component | +| `--danger` | Allow immediate swizzling of unsafe components | +| `--typescript` | Swizzle the TypeScript variant component | +| `--config` | Path to docusaurus config file, default to `[siteDir]/docusaurus.config.js` | + +:::warning + +Unsafe components have a higher risk of breaking changes due to internal refactorings. + +::: + +### `docusaurus deploy [siteDir]` {#docusaurus-deploy-sitedir} + +Deploys your site with [GitHub Pages](https://pages.github.com/). Check out the docs on [deployment](deployment.mdx#deploying-to-github-pages) for more details. + +#### Options {#options-3} + +| Name | Default | Description | +| --- | --- | --- | +| `--locale` | | Deploy the site in the specified locale(s). If not specified, all known locales are deployed. | +| `--out-dir` | `build` | The full path for the new output directory, relative to the current workspace. | +| `--skip-build` | `false` | Deploy website without building it. This may be useful when using a custom deploy script. | +| `--target-dir` | `.` | Path to the target directory to deploy to. | +| `--config` | `undefined` | Path to Docusaurus config file, default to `[siteDir]/docusaurus.config.js` | + +### `docusaurus serve [siteDir]` {#docusaurus-serve-sitedir} + +Serve your built website locally. + +| Name | Default | Description | +| --- | --- | --- | +| `--port` | `3000` | Use specified port | +| `--dir` | `build` | The full path for the output directory, relative to the current workspace | +| `--build` | `false` | Build website before serving | +| `--config` | `undefined` | Path to Docusaurus config file, default to `[siteDir]/docusaurus.config.js` | +| `--host` | `localhost` | Specify a host to use. For example, if you want your server to be accessible externally, you can use `--host 0.0.0.0`. | +| `--no-open` | `false` locally, `true` in CI | Do not open a browser window to the server location. | + +### `docusaurus clear [siteDir]` {#docusaurus-clear-sitedir} + +Clear a Docusaurus site's generated assets, caches, build artifacts. + +We recommend running this command before reporting bugs, after upgrading versions, or anytime you have issues with your Docusaurus site. + +### `docusaurus write-translations [siteDir]` {#docusaurus-write-translations-sitedir} + +Write the JSON translation files that you will have to translate. + +By default, the files are written in `website/i18n/<defaultLocale>/...`. + +| Name | Default | Description | +| --- | --- | --- | +| `--locale` | `<defaultLocale>` | Define which locale folder you want to write translations the JSON files in | +| `--override` | `false` | Override existing translation messages | +| `--config` | `undefined` | Path to Docusaurus config file, default to `[siteDir]/docusaurus.config.js` | +| `--messagePrefix` | `''` | Allows adding a prefix to each translation message, to help you highlight untranslated strings | + +### `docusaurus write-heading-ids [siteDir] [files]` {#docusaurus-write-heading-ids-sitedir} + +Add [explicit heading IDs](./guides/markdown-features/markdown-features-toc.mdx#heading-ids) to the Markdown documents of your site. + +| Name | Default | Description | +| --- | --- | --- | +| `files` | All MD files used by plugins | The files that you want heading IDs to be written to. | +| `--maintain-case` | `false` | Keep the headings' casing, otherwise make all lowercase. | +| `--overwrite` | `false` | Overwrite existing heading IDs. | diff --git a/website/versioned_docs/version-3.7.0/configuration.mdx b/website/versioned_docs/version-3.7.0/configuration.mdx new file mode 100644 index 0000000000..40e435afef --- /dev/null +++ b/website/versioned_docs/version-3.7.0/configuration.mdx @@ -0,0 +1,294 @@ +--- +description: Configuring your site's behavior through docusaurus.config.js and more. +--- + +# Configuration + +import TOCInline from '@theme/TOCInline'; + +:::info + +Check the [**`docusaurus.config.js` API reference**](api/docusaurus.config.js.mdx) for an exhaustive list of options. + +::: + +Docusaurus has a unique take on configurations. We encourage you to congregate information about your site into one place. We guard the fields of this file and facilitate making this data object accessible across your site. + +Keeping a well-maintained `docusaurus.config.js` helps you, your collaborators, and your open source contributors to be able to focus on documentation while still being able to customize the site. + +## Syntax to declare `docusaurus.config.js` {#syntax-to-declare-docusaurus-config} + +The `docusaurus.config.js` file is run in Node.js and should export either: + +- a **config object** +- a **function** that creates the config object + +:::info + +The `docusaurus.config.js` file supports: + +- [**ES Modules**](https://flaviocopes.com/es-modules/) +- [**CommonJS**](https://flaviocopes.com/commonjs/) +- [**TypeScript**](./typescript-support.mdx#typing-config) + +Constraints: + +- **Required:** use `export default /* your config*/` (or `module.exports`) to export your Docusaurus config +- **Optional:** use `import Lib from 'lib'` (or `require('lib')`) to import Node.js packages + +::: + +Docusaurus gives us the ability to declare its configuration in various **equivalent ways**, and all the following config examples lead to the exact same result: + +```js title="docusaurus.config.js" +export default { + title: 'Docusaurus', + url: 'https://docusaurus.io', + // your site config ... +}; +``` + +```js title="docusaurus.config.js" +module.exports = { + title: 'Docusaurus', + url: 'https://docusaurus.io', + // your site config ... +}; +``` + +```ts title="docusaurus.config.ts" +import type {Config} from '@docusaurus/types'; + +export default { + title: 'Docusaurus', + url: 'https://docusaurus.io', + // your site config ... +} satisfies Config; +``` + +```js title="docusaurus.config.js" +const config = { + title: 'Docusaurus', + url: 'https://docusaurus.io', + // your site config ... +}; + +export default config; +``` + +```js title="docusaurus.config.js" +export default function configCreator() { + return { + title: 'Docusaurus', + url: 'https://docusaurus.io', + // your site config ... + }; +} +``` + +```js title="docusaurus.config.js" +export default async function createConfigAsync() { + return { + title: 'Docusaurus', + url: 'https://docusaurus.io', + // your site config ... + }; +} +``` + +:::tip Using ESM-only packages + +Using an async config creator can be useful to import ESM-only modules (notably most Remark plugins). It is possible to import such modules thanks to dynamic imports: + +```js title="docusaurus.config.js" +export default async function createConfigAsync() { + // Use a dynamic import instead of require('esm-lib') + // highlight-next-line + const lib = await import('lib'); + + return { + title: 'Docusaurus', + url: 'https://docusaurus.io', + // rest of your site config... + }; +} +``` + +::: + +## What goes into a `docusaurus.config.js`? {#what-goes-into-a-docusaurusconfigjs} + +You should not have to write your `docusaurus.config.js` from scratch even if you are developing your site. All templates come with a `docusaurus.config.js` that includes defaults for the common options. + +However, it can be helpful if you have a high-level understanding of how the configurations are designed and implemented. + +The high-level overview of Docusaurus configuration can be categorized into: + +<TOCInline toc={toc} minHeadingLevel={3} maxHeadingLevel={3} /> + +### Site metadata {#site-metadata} + +Site metadata contains the essential global metadata such as `title`, `url`, `baseUrl`, and `favicon`. + +They are used in several places such as your site's title and headings, browser tab icon, social sharing (Facebook, X) information or even to generate the correct path to serve your static files. + +### Deployment configurations {#deployment-configurations} + +Deployment configurations such as `projectName`, `organizationName`, and optionally `deploymentBranch` are used when you deploy your site with the `deploy` command. + +It is recommended to check the [deployment docs](deployment.mdx) for more information. + +### Theme, plugin, and preset configurations {#theme-plugin-and-preset-configurations} + +List the [themes](./using-plugins.mdx#using-themes), [plugins](./using-plugins.mdx), and [presets](./using-plugins.mdx#using-presets) for your site in the `themes`, `plugins`, and `presets` fields, respectively. These are typically npm packages: + +```js title="docusaurus.config.js" +export default { + // ... + plugins: [ + '@docusaurus/plugin-content-blog', + '@docusaurus/plugin-content-pages', + ], + themes: ['@docusaurus/theme-classic'], +}; +``` + +:::tip + +Docusaurus supports [**module shorthands**](./using-plugins.mdx#module-shorthands), allowing you to simplify the above configuration as: + +```js title="docusaurus.config.js" +export default { + // ... + plugins: ['content-blog', 'content-pages'], + themes: ['classic'], +}; +``` + +::: + +They can also be loaded from local directories: + +```js title="docusaurus.config.js" +import path from 'path'; + +export default { + // ... + themes: [path.resolve(__dirname, '/path/to/docusaurus-local-theme')], +}; +``` + +To specify options for a plugin or theme, replace the name of the plugin or theme in the config file with an array containing the name and an options object: + +```js title="docusaurus.config.js" +export default { + // ... + plugins: [ + [ + 'content-blog', + { + path: 'blog', + routeBasePath: 'blog', + include: ['*.md', '*.mdx'], + // ... + }, + ], + 'content-pages', + ], +}; +``` + +To specify options for a plugin or theme that is bundled in a preset, pass the options through the `presets` field. In this example, `docs` refers to `@docusaurus/plugin-content-docs` and `theme` refers to `@docusaurus/theme-classic`. + +```js title="docusaurus.config.js" +export default { + // ... + presets: [ + [ + '@docusaurus/preset-classic', + { + docs: { + sidebarPath: './sidebars.js', + }, + theme: { + customCss: ['./src/css/custom.css'], + }, + }, + ], + ], +}; +``` + +:::tip + +The `presets: [['classic', {...}]]` shorthand works as well. + +::: + +For further help configuring themes, plugins, and presets, see [Using Plugins](./using-plugins.mdx). + +### Custom configurations {#custom-configurations} + +Docusaurus guards `docusaurus.config.js` from unknown fields. To add custom fields, define them in `customFields`. + +Example: + +```js title="docusaurus.config.js" +export default { + // ... + // highlight-start + customFields: { + image: '', + keywords: [], + }, + // highlight-end + // ... +}; +``` + +## Accessing configuration from components {#accessing-configuration-from-components} + +Your configuration object will be made available to all the components of your site. And you may access them via React context as `siteConfig`. + +Basic example: + +```jsx +import React from 'react'; +// highlight-next-line +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; + +const Hello = () => { + // highlight-start + const {siteConfig} = useDocusaurusContext(); + // highlight-end + const {title, tagline} = siteConfig; + + return <div>{`${title} · ${tagline}`}</div>; +}; +``` + +:::tip + +If you just want to use those fields on the client side, you could create your own JS files and import them as ES6 modules, there is no need to put them in `docusaurus.config.js`. + +::: + +## Customizing Babel Configuration {#customizing-babel-configuration} + +Docusaurus transpiles your site's source code using Babel by default. If you want to customize the Babel configuration, you can do so by creating a `babel.config.js` file in your project root. + +To use the built-in preset as a base configuration, install the following package and use it + +```bash npm2yarn +npm install --save @docusaurus/babel +``` + +Then use the preset in your `babel.config.js` file: + +```js title="babel.config.js" +export default { + presets: ['@docusaurus/babel/preset'], +}; +``` + +Most of the time, the default preset configuration will work just fine. If you want to customize your Babel configuration (e.g. to add support for Flow), you can directly edit this file. For your changes to take effect, you need to restart the Docusaurus dev server. diff --git a/website/versioned_docs/version-3.7.0/deployment.mdx b/website/versioned_docs/version-3.7.0/deployment.mdx new file mode 100644 index 0000000000..d80af32c4b --- /dev/null +++ b/website/versioned_docs/version-3.7.0/deployment.mdx @@ -0,0 +1,853 @@ +--- +description: Deploy your Docusaurus app for production on a range of static site hosting services. +--- + +# Deployment + +To build the static files of your website for production, run: + +```bash npm2yarn +npm run build +``` + +Once it finishes, the static files will be generated within the `build` directory. + +:::note + +The only responsibility of Docusaurus is to build your site and emit static files in `build`. + +It is now up to you to choose how to host those static files. + +::: + +You can deploy your site to static site hosting services such as [Vercel](https://vercel.com/), [GitHub Pages](https://pages.github.com/), [Netlify](https://www.netlify.com/), [Render](https://render.com/docs/static-sites), and [Surge](https://surge.sh/help/getting-started-with-surge). + +A Docusaurus site is statically rendered, and it can generally work without JavaScript! + +## Configuration {#configuration} + +The following parameters are required in `docusaurus.config.js` to optimize routing and serve files from the correct location: + +| Name | Description | +| --- | --- | +| `url` | URL for your site. For a site deployed at `https://my-org.com/my-project/`, `url` is `https://my-org.com/`. | +| `baseUrl` | Base URL for your project, with a trailing slash. For a site deployed at `https://my-org.com/my-project/`, `baseUrl` is `/my-project/`. | + +## Testing your Build Locally {#testing-build-locally} + +It is important to test your build locally before deploying it for production. Docusaurus provides a [`docusaurus serve`](cli.mdx#docusaurus-serve-sitedir) command for that: + +```bash npm2yarn +npm run serve +``` + +By default, this will load your site at [`http://localhost:3000/`](http://localhost:3000/). + +## Trailing slash configuration {#trailing-slashes} + +Docusaurus has a [`trailingSlash` config](./api/docusaurus.config.js.mdx#trailingSlash) to allow customizing URLs/links and emitted filename patterns. + +The default value generally works fine. Unfortunately, each static hosting provider has a **different behavior**, and deploying the exact same site to various hosts can lead to distinct results. Depending on your host, it can be useful to change this config. + +:::tip + +Use [slorber/trailing-slash-guide](https://github.com/slorber/trailing-slash-guide) to understand better the behavior of your host and configure `trailingSlash` appropriately. + +::: + +## Using environment variables {#using-environment-variables} + +Putting potentially sensitive information in the environment is common practice. However, in a typical Docusaurus website, the `docusaurus.config.js` file is the only interface to the Node.js environment (see [our architecture overview](advanced/architecture.mdx)), while everything else (MDX pages, React components, etc.) are client side and do not have direct access to the `process` global variable. In this case, you can consider using [`customFields`](api/docusaurus.config.js.mdx#customFields) to pass environment variables to the client side. + +```js title="docusaurus.config.js" +// If you are using dotenv (https://www.npmjs.com/package/dotenv) +import 'dotenv/config'; + +export default { + title: '...', + url: process.env.URL, // You can use environment variables to control site specifics as well + // highlight-start + customFields: { + // Put your custom environment here + teamEmail: process.env.EMAIL, + }, + // highlight-end +}; +``` + +```jsx title="home.jsx" +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; + +export default function Home() { + const { + siteConfig: {customFields}, + } = useDocusaurusContext(); + return <div>Contact us through {customFields.teamEmail}!</div>; +} +``` + +## Choosing a hosting provider {#choosing-a-hosting-provider} + +There are a few common hosting options: + +- [Self hosting](#self-hosting) with an HTTP server like Apache2 or Nginx. +- Jamstack providers (e.g. [Netlify](#deploying-to-netlify) and [Vercel](#deploying-to-vercel)). We will use them as references, but the same reasoning can apply to other providers. +- [GitHub Pages](#deploying-to-github-pages) (by definition, it is also Jamstack, but we compare it separately). + +If you are unsure of which one to choose, ask the following questions: + +<details> + +<summary> + How many resources (money, person-hours, etc.) am I willing to invest in this? +</summary> + +- 🔴 Self-hosting requires experience in networking as well as Linux and web server administration. It's the most difficult option, and would require the most time to manage successfully. Expense-wise, cloud services are almost never free, and purchasing/deploying an onsite server can be even more costly. +- 🟢 Jamstack providers can help you set up a working website in almost no time and offer features like server-side redirects that are easily configurable. Many providers offer generous build-time quotas even for free plans that you would almost never exceed. However, free plans have limits, and you would need to pay once you hit those limits. Check the pricing page of your provider for details. +- 🟡 The GitHub Pages deployment workflow can be tedious to set up. (Evidence: see the length of [Deploying to GitHub Pages](#deploying-to-github-pages)!) However, this service (including build and deployment) is always free for public repositories, and we have detailed instructions to help you make it work. + +</details> + +<details> + +<summary>How much server-side customization do I need?</summary> + +- 🟢 With self-hosting, you have access to the entire server's configuration. You can configure the virtual host to serve different content based on the request URL, you can do complicated server-side redirects, you can implement authentication, and so on. If you need a lot of server-side features, self-host your website. +- 🟡 Jamstack usually offers some server-side configuration (e.g. URL formatting (trailing slashes), server-side redirects, etc.). +- 🔴 GitHub Pages doesn't expose server-side configuration besides enforcing HTTPS and setting CNAME records. + +</details> + +<details> + +<summary>Do I need collaboration-friendly deployment workflows?</summary> + +- 🟡 Self-hosted services can leverage continuous deployment functionality like Netlify, but more heavy-lifting is involved. Usually, you would designate a specific person to manage the deployment, and the workflow wouldn't be very git-based as opposed to the other two options. +- 🟢 Netlify and Vercel have deploy previews for every pull request, which is useful for a team to review work before merging to production. You can also manage a team with different member access to the deployment. +- 🟡 GitHub Pages cannot do deploy previews in a non-convoluted way. One repo can only be associated with one site deployment. On the other hand, you can control who has write access to the site's deployment. + +</details> + +There isn't a silver bullet. You need to weigh your needs and resources before making a choice. + +## Self-Hosting {#self-hosting} + +Docusaurus can be self-hosted using [`docusaurus serve`](cli.mdx#docusaurus-serve-sitedir). Change port using `--port` and `--host` to change host. + +```bash npm2yarn +npm run serve -- --build --port 80 --host 0.0.0.0 +``` + +:::warning + +It is not the best option, compared to a static hosting provider / CDN. + +::: + +:::warning + +In the following sections, we will introduce a few common hosting providers and how they should be configured to deploy Docusaurus sites most efficiently. Docusaurus is not affiliated with any of these services, and this information is provided for convenience only. Some of the write-ups are provided by third-parties, and recent API changes may not be reflected on our side. If you see outdated content, PRs are welcome. + +Because we can only provide this content on a best-effort basis only, we have stopped accepting PRs adding new hosting options. You can, however, publish your writeup on a separate site (e.g. your blog, or the provider's official website), and ask us to include a link to your writeup. + +::: + +## Deploying to Netlify {#deploying-to-netlify} + +To deploy your Docusaurus sites to [Netlify](https://www.netlify.com/), first make sure the following options are properly configured: + +```js title="docusaurus.config.js" +export default { + // highlight-start + url: 'https://docusaurus-2.netlify.app', // Url to your site with no trailing slash + baseUrl: '/', // Base directory of your site relative to your repo + // highlight-end + // ... +}; +``` + +Then, [create your site with Netlify](https://app.netlify.com/start). + +While you set up the site, specify the build commands and directories as follows: + +- build command: `npm run build` +- publish directory: `build` + +If you did not configure these build options, you may still go to "Site settings" -> "Build & deploy" after your site is created. + +Once properly configured with the above options, your site should deploy and automatically redeploy upon merging to your deploy branch, which defaults to `main`. + +:::warning + +Some Docusaurus sites put the `docs` folder outside of `website` (most likely former Docusaurus v1 sites): + +```bash +repo # git root +├── docs # MD files +└── website # Docusaurus root +``` + +If you decide to use the `website` folder as Netlify's base directory, Netlify will not trigger builds when you update the `docs` folder, and you need to configure a [custom `ignore` command](https://docs.netlify.com/configure-builds/common-configurations/ignore-builds/): + +```toml title="website/netlify.toml" +[build] + ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF . ../docs/" +``` + +::: + +:::warning + +By default, Netlify adds trailing slashes to Docusaurus URLs. + +It is recommended to disable the Netlify setting `Post Processing > Asset Optimization > Pretty Urls` to prevent lowercase URLs, unnecessary redirects, and 404 errors. + +**Be very careful**: the `Disable asset optimization` global checkbox is broken and does not really disable the `Pretty URLs` setting in practice. Please make sure to **uncheck it independently**. + +If you want to keep the `Pretty Urls` Netlify setting on, adjust the `trailingSlash` Docusaurus config appropriately. + +Refer to [slorber/trailing-slash-guide](https://github.com/slorber/trailing-slash-guide) for more information. + +::: + +## Deploying to Vercel {#deploying-to-vercel} + +Deploying your Docusaurus project to [Vercel](https://vercel.com/) will provide you with [various benefits](https://vercel.com/) in the areas of performance and ease of use. + +To deploy your Docusaurus project with a [Vercel for Git Integration](https://vercel.com/docs/concepts/git), make sure it has been pushed to a Git repository. + +Import the project into Vercel using the [Import Flow](https://vercel.com/import/git). During the import, you will find all relevant options preconfigured for you; however, you can choose to change any of these [options](https://vercel.com/docs/build-step#build-&-development-settings). + +After your project has been imported, all subsequent pushes to branches will generate [Preview Deployments](https://vercel.com/docs/platform/deployments#preview), and all changes made to the [Production Branch](https://vercel.com/docs/git-integrations#production-branch) (usually "main" or "master") will result in a [Production Deployment](https://vercel.com/docs/platform/deployments#production). + +## Deploying to GitHub Pages {#deploying-to-github-pages} + +Docusaurus provides an easy way to publish to [GitHub Pages](https://pages.github.com/), which comes free with every GitHub repository. + +### Overview {#github-pages-overview} + +Usually, there are two repositories (at least two branches) involved in a publishing process: the branch containing the source files, and the branch containing the build output to be served with GitHub Pages. In the following tutorial, they will be referred to as **"source"** and **"deployment"**, respectively. + +Each GitHub repository is associated with a GitHub Pages service. If the deployment repository is called `my-org/my-project` (where `my-org` is the organization name or username), the deployed site will appear at `https://my-org.github.io/my-project/`. If the deployment repository is called `my-org/my-org.github.io` (the _organization GitHub Pages repo_), the site will appear at `https://my-org.github.io/`. + +:::info + +In case you want to use your custom domain for GitHub Pages, create a `CNAME` file in the `static` directory. Anything within the `static` directory will be copied to the root of the `build` directory for deployment. When using a custom domain, you should be able to move back from `baseUrl: '/projectName/'` to `baseUrl: '/'`, and also set your `url` to your custom domain. + +You may refer to GitHub Pages' documentation [User, Organization, and Project Pages](https://help.github.com/en/articles/user-organization-and-project-pages) for more details. + +::: + +GitHub Pages picks up deploy-ready files (the output from `docusaurus build`) from the default branch (`master` / `main`, usually) or the `gh-pages` branch, and either from the root or the `/docs` folder. You can configure that through `Settings > Pages` in your repository. This branch will be called the "deployment branch". + +We provide a `docusaurus deploy` command that helps you deploy your site from the source branch to the deployment branch in one command: clone, build, and commit. + +### `docusaurus.config.js` settings {#docusaurusconfigjs-settings} + +First, modify your `docusaurus.config.js` and add the following params: + +| Name | Description | +| --- | --- | +| `organizationName` | The GitHub user or organization that owns the deployment repository. | +| `projectName` | The name of the deployment repository. | +| `deploymentBranch` | The name of the deployment branch. It defaults to `'gh-pages'` for non-organization GitHub Pages repos (`projectName` not ending in `.github.io`). Otherwise, it needs to be explicit as a config field or environment variable. | + +These fields also have their environment variable counterparts which have a higher priority: `ORGANIZATION_NAME`, `PROJECT_NAME`, and `DEPLOYMENT_BRANCH`. + +:::warning + +GitHub Pages adds a trailing slash to Docusaurus URLs by default. It is recommended to set a `trailingSlash` config (`true` or `false`, not `undefined`). + +::: + +Example: + +```js title="docusaurus.config.js" +export default { + // ... + url: 'https://endiliey.github.io', // Your website URL + baseUrl: '/', + // highlight-start + projectName: 'endiliey.github.io', + organizationName: 'endiliey', + trailingSlash: false, + // highlight-end + // ... +}; +``` + +:::warning + +By default, GitHub Pages runs published files through [Jekyll](https://jekyllrb.com/). Since Jekyll will discard any files that begin with `_`, it is recommended that you disable Jekyll by adding an empty file named `.nojekyll` file to your `static` directory. + +::: + +### Environment settings {#environment-settings} + +| Name | Description | +| --- | --- | +| `USE_SSH` | Set to `true` to use SSH instead of the default HTTPS for the connection to the GitHub repo. If the source repo URL is an SSH URL (e.g. `git@github.com:facebook/docusaurus.git`), `USE_SSH` is inferred to be `true`. | +| `GIT_USER` | The username for a GitHub account that **has push access to the deployment repo**. For your own repositories, this will usually be your GitHub username. Required if not using SSH, and ignored otherwise. | +| `GIT_PASS` | Personal access token of the git user (specified by `GIT_USER`), to facilitate non-interactive deployment (e.g. continuous deployment) | +| `CURRENT_BRANCH` | The source branch. Usually, the branch will be `main` or `master`, but it could be any branch except for `gh-pages`. If nothing is set for this variable, then the current branch from which `docusaurus deploy` is invoked will be used. | +| `GIT_USER_NAME` | The `git config user.name` value to use when pushing to the deployment repo | +| `GIT_USER_EMAIL` | The `git config user.email` value to use when pushing to the deployment repo | + +GitHub enterprise installations should work in the same manner as github.com; you only need to set the organization's GitHub Enterprise host as an environment variable: + +| Name | Description | +| ------------- | ----------------------------------------------- | +| `GITHUB_HOST` | The domain name of your GitHub enterprise site. | +| `GITHUB_PORT` | The port of your GitHub enterprise site. | + +### Deploy {#deploy} + +Finally, to deploy your site to GitHub Pages, run: + +```mdx-code-block +<Tabs> +<TabItem value="bash" label="Bash"> +``` + +```bash +GIT_USER=<GITHUB_USERNAME> yarn deploy +``` + +```mdx-code-block +</TabItem> +<TabItem value="windows" label="Windows"> +``` + +```batch +cmd /C "set "GIT_USER=<GITHUB_USERNAME>" && yarn deploy" +``` + +```mdx-code-block +</TabItem> +<TabItem value="powershell" label="PowerShell"> +``` + +```powershell +cmd /C 'set "GIT_USER=<GITHUB_USERNAME>" && yarn deploy' +``` + +```mdx-code-block +</TabItem> +</Tabs> +``` + +:::warning + +Beginning in August 2021, GitHub requires every command-line sign-in to use the **personal access token** instead of the password. When GitHub prompts for your password, enter the PAT instead. See the [GitHub documentation](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) for more information. + +Alternatively, you can use SSH (`USE_SSH=true`) to log in. + +::: + +### Triggering deployment with GitHub Actions {#triggering-deployment-with-github-actions} + +[GitHub Actions](https://help.github.com/en/actions) allow you to automate, customize, and execute your software development workflows right in your repository. + +The workflow examples below assume your website source resides in the `main` branch of your repository (the _source branch_ is `main`), and your [publishing source](https://help.github.com/en/github/working-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site) is configured for [publishing with a custom GitHub Actions Workflow](https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#publishing-with-a-custom-github-actions-workflow). + +Our goal is that: + +1. When a new pull request is made to `main`, there's an action that ensures the site builds successfully, without actually deploying. This job will be called `test-deploy`. +2. When a pull request is merged to the `main` branch or someone pushes to the `main` branch directly, it will be built and deployed to GitHub Pages. This job will be called `deploy`. + +Here are two approaches to deploying your docs with GitHub Actions. Based on the location of your deployment repository, choose the relevant tab below: + +- Source repo and deployment repo are the **same** repository. +- The deployment repo is a **remote** repository, different from the source. Instructions for this scenario assume [publishing source](https://help.github.com/en/github/working-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site) is the `gh-pages` branch. + +```mdx-code-block +<Tabs> +<TabItem value="same" label="Same"> +``` + +While you can have both jobs defined in the same workflow file, the original `deploy` workflow will always be listed as skipped in the PR check suite status, which is not indicative of the actual status and provides no value to the review process. We therefore propose to manage them as separate workflows instead. + +<details> +<summary>GitHub action files</summary> + +Add these two workflow files: + +:::warning Tweak the parameters for your setup + +These files assume you are using Yarn. If you use npm, change `cache: yarn`, `yarn install --frozen-lockfile`, `yarn build` to `cache: npm`, `npm ci`, `npm run build` accordingly. + +If your Docusaurus project is not at the root of your repo, you may need to configure a [default working directory](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-set-the-default-shell-and-working-directory), and adjust the paths accordingly. + +::: + +```yml title=".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 + +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: yarn + + - name: Install dependencies + run: yarn install --frozen-lockfile + - name: Build website + run: yarn 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 +``` + +```yml title=".github/workflows/test-deploy.yml" +name: Test deployment + +on: + pull_request: + 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 + +jobs: + test-deploy: + name: Test deployment + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-node@v4 + with: + node-version: 18 + cache: yarn + + - name: Install dependencies + run: yarn install --frozen-lockfile + - name: Test build website + run: yarn build +``` + +</details> + +```mdx-code-block +</TabItem> +<TabItem value="remote" label="Remote"> +``` + +A cross-repo publish is more difficult to set up because you need to push to another repo with permission checks. We will be using SSH to do the authentication. + +1. Generate a new [SSH key](https://help.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent). Since this SSH key will be used in CI, make sure to not enter any passphrase. +2. By default, your public key should have been created in `~/.ssh/id_rsa.pub`; otherwise, use the name you've provided in the previous step to add your key to [GitHub deploy keys](https://developer.github.com/v3/guides/managing-deploy-keys/). +3. Copy the key to clipboard with `pbcopy < ~/.ssh/id_rsa.pub` and paste it as a [deploy key](https://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys) in the deployment repository. Copy the file content if the command line doesn't work for you. Check the box for `Allow write access` before saving your deployment key. +4. You'll need your private key as a [GitHub secret](https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets) to allow Docusaurus to run the deployment for you. +5. Copy your private key with `pbcopy < ~/.ssh/id_rsa` and paste a GitHub secret with the name `GH_PAGES_DEPLOY` on your source repository. Copy the file content if the command line doesn't work for you. Save your secret. +6. Create your [documentation workflow](https://docs.github.com/en/actions/use-cases-and-examples/creating-an-example-workflow) in the `.github/workflows/` directory. In this example it's the `deploy.yml` file. + +At this point, you should have: + +- the source repo with the GitHub workflow set with the private SSH key as the GitHub Secret, and +- your deployment repo set with the public SSH key in GitHub Deploy Keys. + +<details> + +<summary>GitHub action file</summary> + +:::warning + +Please make sure that you replace `actions@github.com` with your GitHub email and `gh-actions` with your name. + +This file assumes you are using Yarn. If you use npm, change `cache: yarn`, `yarn install --frozen-lockfile`, `yarn build` to `cache: npm`, `npm ci`, `npm run build` accordingly. + +::: + +```yml title=".github/workflows/deploy.yml" +name: Deploy to GitHub Pages + +on: + pull_request: + branches: [main] + push: + branches: [main] + +permissions: + contents: write + +jobs: + test-deploy: + if: github.event_name != 'push' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-node@v4 + with: + node-version: 18 + cache: yarn + - name: Install dependencies + run: yarn install --frozen-lockfile + - name: Test build website + run: yarn build + deploy: + if: github.event_name != 'pull_request' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-node@v4 + with: + node-version: 18 + cache: yarn + - uses: webfactory/ssh-agent@v0.5.0 + with: + ssh-private-key: ${{ secrets.GH_PAGES_DEPLOY }} + - name: Deploy to GitHub Pages + env: + USE_SSH: true + run: | + git config --global user.email "actions@github.com" + git config --global user.name "gh-actions" + yarn install --frozen-lockfile + yarn deploy +``` + +</details> + +```mdx-code-block +</TabItem> +</Tabs> +``` + +<details> + +<summary>Site not deployed properly?</summary> + +After pushing to main, if you don't see your site published at the desired location (for example, it says "There isn't a GitHub Pages site here", or it's showing your repo's README.md file), try the following: + +- Wait about three minutes and refresh. It may take a few minutes for GitHub pages to pick up the new files. +- Check your repo's landing page for a little green tick next to the last commit's title, indicating the CI has passed. If you see a cross, it means the build or deployment failed, and you should check the log for more debugging information. +- Click on the tick and make sure you see a "Deploy to GitHub Pages" workflow. Names like "pages build and deployment / deploy" are GitHub's default workflows, indicating your custom deployment workflow failed to be triggered at all. Make sure the YAML files are placed under the `.github/workflows` folder, and that the trigger condition is set correctly (e.g., if your default branch is "master" instead of "main", you need to change the `on.push` property). +- Under your repo's Settings > Pages, make sure the "Source" (which is the source for the _deployment_ files, not "source" as in our terminology) is set to "gh-pages" + "/ (root)", since we are using `gh-pages` as the deployment branch. + +If you are using a custom domain: + +- Verify that you have the correct DNS records set up if you're using a custom domain. See [GitHub pages documentation on configuring custom domains](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/about-custom-domains-and-github-pages). Also, please be aware that it may take up to 24 hours for DNS changes to propagate through the internet. + +</details> + +### Triggering deployment with Travis CI {#triggering-deployment-with-travis-ci} + +Continuous integration (CI) services are typically used to perform routine tasks whenever new commits are checked in to source control. These tasks can be any combination of running unit tests and integration tests, automating builds, publishing packages to npm, and deploying changes to your website. All you need to do to automate the deployment of your website is to invoke the `yarn deploy` script whenever your website is updated. The following section covers how to do just that using [Travis CI](https://travis-ci.com/), a popular continuous integration service provider. + +1. Go to https://github.com/settings/tokens and generate a new [personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/). When creating the token, grant it the `repo` scope so that it has the permissions it needs. +2. Using your GitHub account, [add the Travis CI app](https://github.com/marketplace/travis-ci) to the repository you want to activate. +3. Open your Travis CI dashboard. The URL looks like `https://travis-ci.com/USERNAME/REPO`, and navigate to the `More options > Setting > Environment Variables` section of your repository. +4. Create a new environment variable named `GH_TOKEN` with your newly generated token as its value, then `GH_EMAIL` (your email address) and `GH_NAME` (your GitHub username). +5. Create a `.travis.yml` on the root of your repository with the following: + +```yml title=".travis.yml" +language: node_js +node_js: + - 18 +branches: + only: + - main +cache: + yarn: true +script: + - git config --global user.name "${GH_NAME}" + - git config --global user.email "${GH_EMAIL}" + - echo "machine github.com login ${GH_NAME} password ${GH_TOKEN}" > ~/.netrc + - yarn install + - GIT_USER="${GH_NAME}" yarn deploy +``` + +Now, whenever a new commit lands in `main`, Travis CI will run your suite of tests and if everything passes, your website will be deployed via the `yarn deploy` script. + +### Triggering deployment with Buddy {#triggering-deployment-with-buddy} + +[Buddy](https://buddy.works/) is an easy-to-use CI/CD tool that allows you to automate the deployment of your portal to different environments, including GitHub Pages. + +Follow these steps to create a pipeline that automatically deploys a new version of your website whenever you push changes to the selected branch of your project: + +1. Go to https://github.com/settings/tokens and generate a new [personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/). When creating the token, grant it the `repo` scope so that it has the permissions it needs. +2. Sign in to your Buddy account and create a new project. +3. Choose GitHub as your git hosting provider and select the repository with the code of your website. +4. Using the left navigation panel, switch to the `Pipelines` view. +5. Create a new pipeline. Define its name, set the trigger mode to `On push`, and select the branch that triggers the pipeline execution. +6. Add a `Node.js` action. +7. Add these commands in the action's terminal: + +```bash +GIT_USER=<GH_PERSONAL_ACCESS_TOKEN> +git config --global user.email "<YOUR_GH_EMAIL>" +git config --global user.name "<YOUR_GH_USERNAME>" +yarn deploy +``` + +After creating this simple pipeline, each new commit pushed to the branch you selected deploys your website to GitHub Pages using `yarn deploy`. Read [this guide](https://buddy.works/guides/react-docusaurus) to learn more about setting up a CI/CD pipeline for Docusaurus. + +### Using Azure Pipelines {#using-azure-pipelines} + +1. Sign Up at [Azure Pipelines](https://azure.microsoft.com/en-us/services/devops/pipelines/) if you haven't already. +2. Create an organization. Within the organization, create a project and connect your repository from GitHub. +3. Go to https://github.com/settings/tokens and generate a new [personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/) with the `repo` scope. +4. In the project page (which looks like `https://dev.azure.com/ORG_NAME/REPO_NAME/_build`), create a new pipeline with the following text. Also, click on edit and add a new environment variable named `GH_TOKEN` with your newly generated token as its value, then `GH_EMAIL` (your email address) and `GH_NAME` (your GitHub username). Make sure to mark them as secret. Alternatively, you can also add a file named `azure-pipelines.yml` at your repository root. + +```yml title="azure-pipelines.yml" +trigger: + - main + +pool: + vmImage: ubuntu-latest + +steps: + - checkout: self + persistCredentials: true + + - task: NodeTool@0 + inputs: + versionSpec: '18' + displayName: Install Node.js + + - script: | + git config --global user.name "${GH_NAME}" + git config --global user.email "${GH_EMAIL}" + git checkout -b main + echo "machine github.com login ${GH_NAME} password ${GH_TOKEN}" > ~/.netrc + yarn install + GIT_USER="${GH_NAME}" yarn deploy + env: + GH_NAME: $(GH_NAME) + GH_EMAIL: $(GH_EMAIL) + GH_TOKEN: $(GH_TOKEN) + displayName: Install and build +``` + +### Using Drone {#using-drone} + +1. Create a new SSH key that will be the [deploy key](https://docs.github.com/en/free-pro-team@latest/developers/overview/managing-deploy-keys#deploy-keys) for your project. +2. Name your private and public keys to be specific and so that it does not overwrite your other [SSH keys](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent). +3. Go to `https://github.com/USERNAME/REPO/settings/keys` and add a new deploy key by pasting in the public key you just generated. +4. Open your Drone.io dashboard and log in. The URL looks like `https://cloud.drone.io/USERNAME/REPO`. +5. Click on the repository, click on activate repository, and add a secret called `git_deploy_private_key` with your private key value that you just generated. +6. Create a `.drone.yml` on the root of your repository with the below text. + +```yml title=".drone.yml" +kind: pipeline +type: docker +trigger: + event: + - tag +- name: Website + image: node + commands: + - mkdir -p $HOME/.ssh + - ssh-keyscan -t rsa github.com >> $HOME/.ssh/known_hosts + - echo "$GITHUB_PRIVATE_KEY" > "$HOME/.ssh/id_rsa" + - chmod 0600 $HOME/.ssh/id_rsa + - cd website + - yarn install + - yarn deploy + environment: + USE_SSH: true + GITHUB_PRIVATE_KEY: + from_secret: git_deploy_private_key +``` + +Now, whenever you push a new tag to GitHub, this trigger will start the drone CI job to publish your website. + +## Deploying to Flightcontrol {#deploying-to-flightcontrol} + +[Flightcontrol](https://www.flightcontrol.dev/?ref=docusaurus) is a service that automatically builds and deploys your web apps to AWS Fargate directly from your Git repository. It gives you full access to inspect and make infrastructure changes without the limitations of a traditional PaaS. + +Get started by following [Flightcontrol's step-by-step Docusaurus guide](https://www.flightcontrol.dev/docs/reference/examples/docusaurus/?ref=docusaurus). + +## Deploying to Koyeb {#deploying-to-koyeb} + +[Koyeb](https://www.koyeb.com) is a developer-friendly serverless platform to deploy apps globally. The platform lets you seamlessly run Docker containers, web apps, and APIs with git-based deployment, native autoscaling, a global edge network, and built-in service mesh and discovery. Check out the [Koyeb's Docusaurus deployment guide](https://www.koyeb.com/tutorials/deploy-docusaurus-on-koyeb) to get started. + +## Deploying to Render {#deploying-to-render} + +[Render](https://render.com) offers [free static site hosting](https://render.com/docs/static-sites) with fully managed SSL, custom domains, a global CDN, and continuous auto-deploy from your Git repo. Get started in just a few minutes by following [Render's guide to deploying Docusaurus](https://render.com/docs/deploy-docusaurus). + +## Deploying to Qovery {#deploying-to-qovery} + +[Qovery](https://www.qovery.com) is a fully-managed cloud platform that runs on your AWS, Digital Ocean, and Scaleway account where you can host static sites, backend APIs, databases, cron jobs, and all your other apps in one place. + +1. Create a Qovery account. Visit the [Qovery dashboard](https://console.qovery.com) to create an account if you don't already have one. +2. Create a project. + - Click on **Create project** and give a name to your project. + - Click on **Next**. +3. Create a new environment. + - Click on **Create environment** and give a name (e.g. staging, production). +4. Add an application. + - Click on **Create an application**, give a name and select your GitHub or GitLab repository where your Docusaurus app is located. + - Define the main branch name and the root application path. + - Click on **Create**. After the application is created: + - Navigate to your application **Settings** + - Select **Port** + - Add port used by your Docusaurus application +5. Deploy + - All you have to do now is to navigate to your application and click on **Deploy**. + +![Deploy the app](https://hub.qovery.com/img/heroku/heroku-1.png) + +That's it. Watch the status and wait till the app is deployed. To open the application in your browser, click on **Action** and **Open** in your application overview. + +## Deploying to Hostman {#deploying-to-hostman} + +[Hostman](https://hostman.com/) allows you to host static websites for free. Hostman automates everything, you just need to connect your repository and follow these easy steps: + +1. Create a service. + + - To deploy a Docusaurus static website, click **Create** in the top-left corner of your [Dashboard](https://dashboard.hostman.com/) and choose **Front-end app or static website**. + +2. Select the project to deploy. + + - If you are logged in to Hostman with your GitHub, GitLab, or Bitbucket account, you will see the repository with your projects, including the private ones. + + - Choose the project you want to deploy. It must contain the directory with the project's files (e.g. `website`). + + - To access a different repository, click **Connect another repository**. + + - If you didn't use your Git account credentials to log in, you'll be able to access the necessary account now, and then select the project. + +3. Configure the build settings. + + - Next, the **Website customization** window will appear. Choose the **Static website** option from the list of frameworks. + + - The **Directory with app** points at the directory that will contain the project's files after the build. If you selected the repository with the contents of the website (or `my_website`) directory during Step 2, you can leave it empty. + + - The standard build command for Docusaurus is: + + ```bash npm2yarn + npm run build + ``` + + - You can modify the build command if needed. You can enter multiple commands separated by `&&`. + +4. Deploy. + + - Click **Deploy** to start the build process. + + - Once it starts, you will enter the deployment log. If there are any issues with the code, you will get warning or error messages in the log specifying the cause of the problem. Usually, the log contains all the debugging data you'll need. + + - When the deployment is complete, you will receive an email notification and also see a log entry. All done! Your project is up and ready. + +## Deploying to Surge {#deploying-to-surge} + +Surge is a [static web hosting platform](https://surge.sh/help/getting-started-with-surge) that you can use to deploy your Docusaurus project from the command line in seconds. Deploying your project to Surge is easy and free (including custom domains and SSL certs). + +Deploy your app in a matter of seconds using Surge with the following steps: + +1. First, install Surge using npm by running the following command: + ```bash npm2yarn + npm install -g surge + ``` +2. To build the static files of your site for production in the root directory of your project, run: + ```bash npm2yarn + npm run build + ``` +3. Then, run this command inside the root directory of your project: + ```bash + surge build/ + ``` + +First-time users of Surge would be prompted to create an account from the command line (which happens only once). + +Confirm that the site you want to publish is in the `build` directory. A randomly generated subdomain `*.surge.sh subdomain` is always given (which can be edited). + +### Using your domain {#using-your-domain} + +If you have a domain name you can deploy your site using the command: + +```bash +surge build/ your-domain.com +``` + +Your site is now deployed for free at `subdomain.surge.sh` or `your-domain.com` depending on the method you chose. + +### Setting up CNAME file {#setting-up-cname-file} + +Store your domain in a CNAME file for future deployments with the following command: + +```bash +echo subdomain.surge.sh > CNAME +``` + +You can deploy any other changes in the future with the command `surge`. + +## Deploying to Stormkit {#deploying-to-stormkit} + +You can deploy your Docusaurus project to [Stormkit](https://www.stormkit.io), a deployment platform for static websites, single-page applications (SPAs), and serverless functions. For detailed instructions, refer to this [guide](https://www.stormkit.io/blog/how-to-deploy-docusarous). + +## Deploying to QuantCDN {#deploying-to-quantcdn} + +1. Install [Quant CLI](https://docs.quantcdn.io/docs/cli/get-started) +2. Create a QuantCDN account by [signing up](https://dashboard.quantcdn.io/register) +3. Initialize your project with `quant init` and fill in your credentials: + ```bash + quant init + ``` +4. Deploy your site. + ```bash + quant deploy + ``` + +See [docs](https://docs.quantcdn.io/docs/cli/continuous-integration) and [blog](https://www.quantcdn.io/blog) for more examples and use cases for deploying to QuantCDN. + +## Deploying to Layer0 {#deploying-to-layer0} + +[Layer0](https://www.layer0.co) is an all-in-one platform to develop, deploy, preview, experiment on, monitor, and run your headless frontend. It is focused on large, dynamic websites and best-in-class performance through EdgeJS (a JavaScript-based Content Delivery Network), predictive prefetching, and performance monitoring. Layer0 offers a free tier. Get started in just a few minutes by following [Layer0's guide to deploying Docusaurus](https://docs.layer0.co/guides/docusaurus). + +## Deploying to Cloudflare Pages {#deploying-to-cloudflare-pages} + +[Cloudflare Pages](https://pages.cloudflare.com/) is a Jamstack platform for frontend developers to collaborate and deploy websites. Get started within a few minutes by following [this article](https://dev.to/apidev234/deploying-docusaurus-to-cloudflare-pages-565g). + +## Deploying to Azure Static Web Apps {#deploying-to-azure-static-web-apps} + +[Azure Static Web Apps](https://docs.microsoft.com/en-us/azure/static-web-apps/overview) is a service that automatically builds and deploys full-stack web apps to Azure directly from the code repository, simplifying the developer experience for CI/CD. Static Web Apps separates the web application's static assets from its dynamic (API) endpoints. Static assets are served from globally-distributed content servers, making it faster for clients to retrieve files using servers nearby. Dynamic APIs are scaled with serverless architectures using an event-driven functions-based approach that is more cost-effective and scales on demand. Get started in a few minutes by following [this step-by-step guide](https://dev.to/azure/11-share-content-with-docusaurus-azure-static-web-apps-30hc). + +## Deploying to Kinsta {#deploying-to-kinsta} + +[Kinsta Static Site Hosting](https://kinsta.com/static-site-hosting) lets you deploy up to 100 static sites for free, custom domains with SSL, 100 GB monthly bandwidth, and 260+ Cloudflare CDN locations. + +Get started in just a few clicks by following our [Docusaurus on Kinsta](https://kinsta.com/docs/docusaurus-example/) article. diff --git a/website/versioned_docs/version-3.7.0/docusaurus-core.mdx b/website/versioned_docs/version-3.7.0/docusaurus-core.mdx new file mode 100644 index 0000000000..63f0f4ddd7 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/docusaurus-core.mdx @@ -0,0 +1,770 @@ +--- +sidebar_label: Client API +--- + +# Docusaurus Client API + +Docusaurus provides some APIs on the clients that can be helpful to you when building your site. + +## Components {#components} + +### `<ErrorBoundary />` {#errorboundary} + +This component creates a [React error boundary](https://reactjs.org/docs/error-boundaries.html). + +Use it to wrap components that might throw, and display a fallback when that happens instead of crashing the whole app. + +```jsx +import React from 'react'; +import ErrorBoundary from '@docusaurus/ErrorBoundary'; + +const SafeComponent = () => ( + <ErrorBoundary + fallback={({error, tryAgain}) => ( + <div> + <p>This component crashed because of error: {error.message}.</p> + <button onClick={tryAgain}>Try Again!</button> + </div> + )}> + <SomeDangerousComponentThatMayThrow /> + </ErrorBoundary> +); +``` + +```mdx-code-block +import ErrorBoundaryTestButton from '@site/src/components/ErrorBoundaryTestButton' +``` + +:::tip + +To see it in action, click here: <ErrorBoundaryTestButton/> + +::: + +:::info + +Docusaurus uses this component to catch errors within the theme's layout, and also within the entire app. + +::: + +:::note + +This component doesn't catch build-time errors and only protects against client-side render errors that can happen when using stateful React components. + +::: + +#### Props {#errorboundary-props} + +- `fallback`: an optional render callback returning a JSX element. It will receive an object with 2 attributes: `error`, the error that was caught, and `tryAgain`, a function (`() => void`) callback to reset the error in the component and try rendering it again. If not present, `@theme/Error` will be rendered instead. `@theme/Error` is used for the error boundaries wrapping the site, above the layout. + +:::warning + +The `fallback` prop is a callback, and **not a React functional component**. You can't use React hooks inside this callback. + +::: + +### `<Head/>` {#head} + +This reusable React component will manage all of your changes to the document head. It takes plain HTML tags and outputs plain HTML tags and is beginner-friendly. It is a wrapper around [React Helmet](https://github.com/nfl/react-helmet). + +Usage Example: + +```jsx +import React from 'react'; +// highlight-next-line +import Head from '@docusaurus/Head'; + +const MySEO = () => ( + // highlight-start + <Head> + <meta property="og:description" content="My custom description" /> + <meta charSet="utf-8" /> + <title>My Title + + + // highlight-end +); +``` + +Nested or latter components will override duplicate usages: + +```jsx + + {/* highlight-start */} + + My Title + + + {/* highlight-end */} + + {/* highlight-start */} + + Nested Title + + + {/* highlight-end */} + + +``` + +Outputs: + +```html + + Nested Title + + +``` + +### `` {#link} + +This component enables linking to internal pages as well as a powerful performance feature called preloading. Preloading is used to prefetch resources so that the resources are fetched by the time the user navigates with this component. We use an `IntersectionObserver` to fetch a low-priority request when the `` is in the viewport and then use an `onMouseOver` event to trigger a high-priority request when it is likely that a user will navigate to the requested resource. + +The component is a wrapper around react-router’s `` component that adds useful enhancements specific to Docusaurus. All props are passed through to react-router’s `` component. + +External links also work, and automatically have these props: `target="_blank" rel="noopener noreferrer"`. + +```jsx +import React from 'react'; +// highlight-next-line +import Link from '@docusaurus/Link'; + +const Page = () => ( +
+

+ {/* highlight-next-line */} + Check out my blog! +

+

+ {/* highlight-next-line */} + Follow me on X! +

+
+); +``` + +#### `to`: string {#to-string} + +The target location to navigate to. Example: `/docs/introduction`. + +```jsx + +``` + +:::tip + +Prefer this component to vanilla `
` tags because Docusaurus does a lot of optimizations (e.g. broken path detection, prefetching, applying base URL...) if you use ``. + +::: + +### `` {#redirect} + +Rendering a `` will navigate to a new location. The new location will override the current location in the history stack like server-side redirects (HTTP 3xx) do. You can refer to [React Router's Redirect documentation](https://reacttraining.com/react-router/web/api/Redirect) for more info on available props. + +Example usage: + +```jsx +import React from 'react'; +// highlight-next-line +import {Redirect} from '@docusaurus/router'; + +const Home = () => { + // highlight-next-line + return ; +}; +``` + +:::note + +`@docusaurus/router` implements [React Router](https://reacttraining.com/react-router/web/guides/quick-start) and supports its features. + +::: + +### `` {#browseronly} + +The `` component permits to render React components only in the browser after the React app has hydrated. + +:::tip + +Use it for integrating with code that can't run in Node.js, because the `window` or `document` objects are being accessed. + +::: + +#### Props {#browseronly-props} + +- `children`: render function prop returning browser-only JSX. Will not be executed in Node.js +- `fallback` (optional): JSX to render on the server (Node.js) and until React hydration completes. + +#### Example with code {#browseronly-example-code} + +```jsx +// highlight-start +import BrowserOnly from '@docusaurus/BrowserOnly'; +// highlight-end + +const MyComponent = () => { + return ( + // highlight-start + + {() => page url = {window.location.href}} + + // highlight-end + ); +}; +``` + +#### Example with a library {#browseronly-example-library} + +```jsx +// highlight-start +import BrowserOnly from '@docusaurus/BrowserOnly'; +// highlight-end + +const MyComponent = (props) => { + return ( + // highlight-start + Loading...
}> + {() => { + const LibComponent = require('some-lib').LibComponent; + return ; + }} + + // highlight-end + ); +}; +``` + +### `` {#interpolate} + +A simple interpolation component for text containing dynamic placeholders. + +The placeholders will be replaced with the provided dynamic values and JSX elements of your choice (strings, links, styled elements...). + +#### Props {#interpolate-props} + +- `children`: text containing interpolation placeholders like `{placeholderName}` +- `values`: object containing interpolation placeholder values + +```jsx +import React from 'react'; +import Link from '@docusaurus/Link'; +import Interpolate from '@docusaurus/Interpolate'; + +export default function VisitMyWebsiteMessage() { + return ( + // highlight-start + + website + + ), + }}> + {'Hello, {firstName}! How are you? Take a look at my {website}'} + + // highlight-end + ); +} +``` + +### `` {#translate} + +When [localizing your site](./i18n/i18n-introduction.mdx), the `` component will allow providing **translation support to React components**, such as your homepage. The `` component supports [interpolation](#interpolate). + +The translation strings will statically extracted from your code with the [`docusaurus write-translations`](./cli.mdx#docusaurus-write-translations-sitedir) CLI and a `code.json` translation file will be created in `website/i18n/[locale]`. + +:::note + +The `` props **must be hardcoded strings**. + +Apart from the `values` prop used for interpolation, it is **not possible to use variables**, or the static extraction wouldn't work. + +::: + +#### Props {#translate-props} + +- `children`: untranslated string in the default site locale (can contain [interpolation placeholders](#interpolate)) +- `id`: optional value to be used as the key in JSON translation files +- `description`: optional text to help the translator +- `values`: optional object containing interpolation placeholder values + +#### Example {#example} + +```jsx title="src/pages/index.js" +import React from 'react'; +import Layout from '@theme/Layout'; + +// highlight-start +import Translate from '@docusaurus/Translate'; +// highlight-end + +export default function Home() { + return ( + +

+ {/* highlight-start */} + + Welcome to my website + + {/* highlight-end */} +

+
+ {/* highlight-start */} + + {'Welcome, {firstName}! How are you?'} + + {/* highlight-end */} +
+
+ ); +} +``` + +:::note + +You can even omit the children prop and specify a translation string in your `code.json` file manually after running the `docusaurus write-translations` CLI command. + +```jsx + +``` + +::: + +:::info + +The `` component supports interpolation. You can also implement [string pluralization](https://github.com/facebook/docusaurus/pull/i18n/i18n-tutorial.mdx#pluralization) through some custom code and the [`translate` imperative API](#translate-imperative). + +::: + +## Hooks {#hooks} + +### `useDocusaurusContext` {#useDocusaurusContext} + +React hook to access Docusaurus Context. The context contains the `siteConfig` object from [docusaurus.config.js](api/docusaurus.config.js.mdx) and some additional site metadata. + +```ts +type PluginVersionInformation = + | {readonly type: 'package'; readonly version?: string} + | {readonly type: 'project'} + | {readonly type: 'local'} + | {readonly type: 'synthetic'}; + +type SiteMetadata = { + readonly docusaurusVersion: string; + readonly siteVersion?: string; + readonly pluginVersions: Record; +}; + +type I18nLocaleConfig = { + label: string; + direction: string; +}; + +type I18n = { + defaultLocale: string; + locales: [string, ...string[]]; + currentLocale: string; + localeConfigs: Record; +}; + +type DocusaurusContext = { + siteConfig: DocusaurusConfig; + siteMetadata: SiteMetadata; + globalData: Record; + i18n: I18n; + codeTranslations: Record; +}; +``` + +Usage example: + +```jsx +import React from 'react'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; + +const MyComponent = () => { + // highlight-next-line + const {siteConfig, siteMetadata} = useDocusaurusContext(); + return ( +
+ {/* highlight-start */} +

{siteConfig.title}

+
{siteMetadata.siteVersion}
+
{siteMetadata.docusaurusVersion}
+ {/* highlight-end */} +
+ ); +}; +``` + +:::note + +The `siteConfig` object only contains **serializable values** (values that are preserved after `JSON.stringify()`). Functions, regexes, etc. would be lost on the client side. + +::: + +### `useIsBrowser` {#useIsBrowser} + +Returns `true` when the React app has successfully hydrated in the browser. + +:::warning + +Use this hook instead of `typeof windows !== 'undefined'` in React rendering logic. + +The first client-side render output (in the browser) **must be exactly the same** as the server-side render output (Node.js). Not following this rule can lead to unexpected hydration behaviors, as described in [The Perils of Rehydration](https://www.joshwcomeau.com/react/the-perils-of-rehydration/). + +::: + +Usage example: + +```jsx +import React from 'react'; +import useIsBrowser from '@docusaurus/useIsBrowser'; + +const MyComponent = () => { + // highlight-start + const isBrowser = useIsBrowser(); + // highlight-end + return
{isBrowser ? 'Client' : 'Server'}
; +}; +``` + +### `useBaseUrl` {#useBaseUrl} + +React hook to prepend your site `baseUrl` to a string. + +:::warning + +**Don't use it for regular links!** + +The `/baseUrl/` prefix is automatically added to all **absolute paths** by default: + +- Markdown: `[link](/my/path)` will link to `/baseUrl/my/path` +- React: `link` will link to `/baseUrl/my/path` + +::: + +#### Options {#options} + +```ts +type BaseUrlOptions = { + forcePrependBaseUrl: boolean; + absolute: boolean; +}; +``` + +#### Example usage: {#example-usage} + +```jsx +import React from 'react'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +const SomeImage = () => { + // highlight-start + const imgSrc = useBaseUrl('/img/myImage.png'); + // highlight-end + return ; +}; +``` + +:::tip + +In most cases, you don't need `useBaseUrl`. + +Prefer a `require()` call for [assets](./guides/markdown-features/markdown-features-assets.mdx): + +```jsx + +``` + +::: + +### `useBaseUrlUtils` {#useBaseUrlUtils} + +Sometimes `useBaseUrl` is not good enough. This hook return additional utils related to your site's base URL. + +- `withBaseUrl`: useful if you need to add base URLs to multiple URLs at once. + +```jsx +import React from 'react'; +import {useBaseUrlUtils} from '@docusaurus/useBaseUrl'; + +const Component = () => { + const urls = ['/a', '/b']; + // highlight-start + const {withBaseUrl} = useBaseUrlUtils(); + const urlsWithBaseUrl = urls.map(withBaseUrl); + // highlight-end + return
{/* ... */}
; +}; +``` + +### `useGlobalData` {#useGlobalData} + +React hook to access Docusaurus global data created by all the plugins. + +Global data is namespaced by plugin name then by plugin ID. + +:::info + +Plugin ID is only useful when a plugin is used multiple times on the same site. Each plugin instance is able to create its own global data. + +::: + +```ts +type GlobalData = Record< + PluginName, + Record< + PluginId, // "default" by default + any // plugin-specific data + > +>; +``` + +Usage example: + +```jsx +import React from 'react'; +// highlight-next-line +import useGlobalData from '@docusaurus/useGlobalData'; + +const MyComponent = () => { + // highlight-start + const globalData = useGlobalData(); + const myPluginData = globalData['my-plugin']['default']; + return
{myPluginData.someAttribute}
; + // highlight-end +}; +``` + +:::tip + +Inspect your site's global data at `.docusaurus/globalData.json` + +::: + +### `usePluginData` {#usePluginData} + +Access global data created by a specific plugin instance. + +This is the most convenient hook to access plugin global data and should be used most of the time. + +`pluginId` is optional if you don't use multi-instance plugins. + +```ts +function usePluginData( + pluginName: string, + pluginId?: string, + options?: {failfast?: boolean}, +); +``` + +Usage example: + +```jsx +import React from 'react'; +// highlight-next-line +import {usePluginData} from '@docusaurus/useGlobalData'; + +const MyComponent = () => { + // highlight-start + const myPluginData = usePluginData('my-plugin'); + return
{myPluginData.someAttribute}
; + // highlight-end +}; +``` + +### `useAllPluginInstancesData` {#useAllPluginInstancesData} + +Access global data created by a specific plugin. Given a plugin name, it returns the data of all the plugins instances of that name, by plugin id. + +```ts +function useAllPluginInstancesData( + pluginName: string, + options?: {failfast?: boolean}, +); +``` + +Usage example: + +```jsx +import React from 'react'; +// highlight-next-line +import {useAllPluginInstancesData} from '@docusaurus/useGlobalData'; + +const MyComponent = () => { + // highlight-start + const allPluginInstancesData = useAllPluginInstancesData('my-plugin'); + const myPluginData = allPluginInstancesData['default']; + return
{myPluginData.someAttribute}
; + // highlight-end +}; +``` + +### `useBrokenLinks` {#useBrokenLinks} + +React hook to access the Docusaurus broken link checker APIs, exposing a way for a Docusaurus pages to report and collect their links and anchors. + +:::warning + +This is an **advanced** API that **most Docusaurus users don't need to use directly**. + +It is already **built-in** in existing high-level components: + +- the [``](#link) component will collect links for you +- the `@theme/Heading` (used for Markdown headings) will collect anchors + +Use `useBrokenLinks()` if you implement your own `` or `` component. + +::: + +Usage example: + +```js title="MyHeading.js" +import useBrokenLinks from '@docusaurus/useBrokenLinks'; + +export default function MyHeading(props) { + useBrokenLinks().collectAnchor(props.id); + return

; +} +``` + +```js title="MyLink.js" +import useBrokenLinks from '@docusaurus/useBrokenLinks'; + +export default function MyLink(props) { + useBrokenLinks().collectLink(props.href); + return ; +} +``` + +## Functions {#functions} + +### `interpolate` {#interpolate-1} + +The imperative counterpart of the [``](#interpolate) component. + +#### Signature {#signature} + +```ts +// Simple string interpolation +function interpolate(text: string, values: Record): string; + +// JSX interpolation +function interpolate( + text: string, + values: Record, +): ReactNode; +``` + +#### Example {#example-1} + +```js +// highlight-next-line +import {interpolate} from '@docusaurus/Interpolate'; + +const message = interpolate('Welcome {firstName}', {firstName: 'Sébastien'}); +``` + +### `translate` {#translate-imperative} + +The imperative counterpart of the [``](#translate) component. Also supporting [placeholders interpolation](#interpolate). + +:::tip + +Use the imperative API for the **rare cases** where a **component cannot be used**, such as: + +- the page `title` metadata +- the `placeholder` props of form inputs +- the `aria-label` props for accessibility + +::: + +#### Signature {#signature-1} + +```ts +function translate( + translation: {message: string; id?: string; description?: string}, + values: Record, +): string; +``` + +#### Example {#example-2} + +```jsx title="src/pages/index.js" +import React from 'react'; +import Layout from '@theme/Layout'; + +// highlight-next-line +import {translate} from '@docusaurus/Translate'; + +export default function Home() { + return ( + + + + ); +} +``` + +## Modules {#modules} + +### `ExecutionEnvironment` {#executionenvironment} + +A module that exposes a few boolean variables to check the current rendering environment. + +:::warning + +For React rendering logic, use [`useIsBrowser()`](#useIsBrowser) or [``](#browseronly) instead. + +::: + +Example: + +```js +import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; + +if (ExecutionEnvironment.canUseDOM) { + require('lib-that-only-works-client-side'); +} +``` + +| Field | Description | +| --- | --- | +| `ExecutionEnvironment.canUseDOM` | `true` if on client/browser, `false` on Node.js/prerendering. | +| `ExecutionEnvironment.canUseEventListeners` | `true` if on client and has `window.addEventListener`. | +| `ExecutionEnvironment.canUseIntersectionObserver` | `true` if on client and has `IntersectionObserver`. | +| `ExecutionEnvironment.canUseViewport` | `true` if on client and has `window.screen`. | + +### `constants` {#constants} + +A module exposing useful constants to client-side theme code. + +```js +import {DEFAULT_PLUGIN_ID} from '@docusaurus/constants'; +``` + +| Named export | Value | +| ------------------- | --------- | +| `DEFAULT_PLUGIN_ID` | `default` | diff --git a/website/versioned_docs/version-3.7.0/guides/creating-pages.mdx b/website/versioned_docs/version-3.7.0/guides/creating-pages.mdx new file mode 100644 index 0000000000..c256716078 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/guides/creating-pages.mdx @@ -0,0 +1,140 @@ +--- +slug: /creating-pages +sidebar_label: Pages +--- + +# Creating Pages + +In this section, we will learn about creating pages in Docusaurus. + +The `@docusaurus/plugin-content-pages` plugin empowers you to create **one-off standalone pages** like a showcase page, playground page, or support page. You can use React components, or Markdown. + +:::note + +Pages do not have sidebars, only [docs](./docs/docs-introduction.mdx) do. + +::: + +:::info + +Check the [Pages Plugin API Reference documentation](./../api/plugins/plugin-content-pages.mdx) for an exhaustive list of options. + +::: + +## Add a React page {#add-a-react-page} + +React is used as the UI library to create pages. Every page component should export a React component, and you can leverage the expressiveness of React to build rich and interactive content. + +Create a file `/src/pages/helloReact.js`: + +```jsx title="/src/pages/helloReact.js" +import React from 'react'; +import Layout from '@theme/Layout'; + +export default function Hello() { + return ( + +
+

+ Edit pages/helloReact.js and save to reload. +

+
+
+ ); +} +``` + +Once you save the file, the development server will automatically reload the changes. Now open [`http://localhost:3000/helloReact`](http://localhost:3000/helloReact) and you will see the new page you just created. + +Each page doesn't come with any styling. You will need to import the `Layout` component from `@theme/Layout` and wrap your contents within that component if you want the navbar and/or footer to appear. + +:::tip + +You can also create TypeScript pages with the `.tsx` extension (`helloReact.tsx`). + +::: + +## Add a Markdown page {#add-a-markdown-page} + +Create a file `/src/pages/helloMarkdown.md`: + +```md title="/src/pages/helloMarkdown.md" +--- +title: my hello page title +description: my hello page description +hide_table_of_contents: true +--- + +# Hello + +How are you? +``` + +In the same way, a page will be created at [`http://localhost:3000/helloMarkdown`](http://localhost:3000/helloMarkdown). + +Markdown pages are less flexible than React pages because it always uses the theme layout. + +Here's an [example Markdown page](/examples/markdownPageExample). + +:::tip + +You can use the full power of React in Markdown pages too, refer to the [MDX](https://mdxjs.com/) documentation. + +::: + +## Routing {#routing} + +If you are familiar with other static site generators like Jekyll and Next, this routing approach will feel familiar to you. Any JavaScript file you create under `/src/pages/` directory will be automatically converted to a website page, following the `/src/pages/` directory hierarchy. For example: + +- `/src/pages/index.js` → `[baseUrl]` +- `/src/pages/foo.js` → `[baseUrl]/foo` +- `/src/pages/foo/test.js` → `[baseUrl]/foo/test` +- `/src/pages/foo/index.js` → `[baseUrl]/foo/` + +In this component-based development era, it is encouraged to co-locate your styling, markup, and behavior together into components. Each page is a component, and if you need to customize your page design with your own styles, we recommend co-locating your styles with the page component in its own directory. For example, to create a "Support" page, you could do one of the following: + +- Add a `/src/pages/support.js` file +- Create a `/src/pages/support/` directory and a `/src/pages/support/index.js` file. + +The latter is preferred as it has the benefits of letting you put files related to the page within that directory. For example, a CSS module file (`styles.module.css`) with styles meant to only be used on the "Support" page. + +:::note + +This is merely a recommended directory structure, and you will still need to manually import the CSS module file within your component module (`support/index.js`). + +::: + +By default, any Markdown or JavaScript file starting with `_` will be ignored and no routes will be created for that file (see the `exclude` option). + +```bash +my-website +├── src +│ └── pages +│ ├── styles.module.css +│ ├── index.js +│ ├── _ignored.js +│ ├── _ignored-folder +│ │ ├── Component1.js +│ │ └── Component2.js +│ └── support +│ ├── index.js +│ └── styles.module.css +. +``` + +:::warning + +All JavaScript/TypeScript files within the `src/pages/` directory will have corresponding website paths generated for them. If you want to create reusable components into that directory, use the `exclude` option (by default, files prefixed with `_`, test files(`.test.js`), and files in `__tests__` directory are not turned into pages). + +::: + +### Duplicate Routes {#duplicate-routes} + +You may accidentally create multiple pages that are meant to be accessed on the same route. When this happens, Docusaurus will warn you about duplicate routes when you run `yarn start` or `yarn build` (behavior configurable through the [`onDuplicateRoutes`](../api/docusaurus.config.js.mdx#onDuplicateRoutes) config), but the site will still be built successfully. The page that was created last will be accessible, but it will override other conflicting pages. To resolve this issue, you should modify or remove any conflicting routes. diff --git a/website/versioned_docs/version-3.7.0/guides/docs/docs-create-doc.mdx b/website/versioned_docs/version-3.7.0/guides/docs/docs-create-doc.mdx new file mode 100644 index 0000000000..caf8e2ea77 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/guides/docs/docs-create-doc.mdx @@ -0,0 +1,192 @@ +--- +id: create-doc +description: Create a Markdown Document +slug: /create-doc +--- + +# Create a doc + +Create a Markdown file, `greeting.md`, and place it under the `docs` directory. + +```bash +website # root directory of your site +├── docs +│ └── greeting.md +├── src +│ └── pages +├── docusaurus.config.js +├── ... +``` + +```md +--- +description: Create a doc page with rich content. +--- + +# Hello from Docusaurus + +Are you ready to create the documentation site for your open source project? + +## Headers + +will show up on the table of contents on the upper right + +So that your users will know what this page is all about without scrolling down or even without reading too much. + +## Only h2 and h3 will be in the TOC by default. + +You can configure the TOC heading levels either per-document or in the theme configuration. + +The headers are well-spaced so that the hierarchy is clear. + +- lists will help you +- present the key points +- that you want your users to remember + - and you may nest them + - multiple times +``` + +:::note + +All files prefixed with an underscore (`_`) under the `docs` directory are treated as "partial" pages and will be ignored by default. + +Read more about [importing partial pages](../markdown-features/markdown-features-react.mdx#importing-markdown). + +::: + +## Doc front matter {#doc-front-matter} + +The [front matter](../markdown-features/markdown-features-intro.mdx#front-matter) is used to provide additional metadata for your doc page. Front matter is optional—Docusaurus will be able to infer all necessary metadata without the front matter. For example, the [doc tags](#doc-tags) feature introduced below requires using front matter. For all possible fields, see [the API documentation](../../api/plugins/plugin-content-docs.mdx#markdown-front-matter). + +## Doc tags {#doc-tags} + +Tags are declared in the front matter and introduce another dimension of categorization in addition to the [docs sidebar](./sidebar/index.mdx). + +It is possible to define tags inline, or to reference predefined tags declared in a [`tags file`](../../api/plugins/plugin-content-docs.mdx#tags-file) (optional, usually `docs/tags.yml`). + +In the following example: + +- `docusaurus` references a predefined tag key declared in `docs/tags.yml` +- `Releases` is an inline tag, because it does not exist in `docs/tags.yml` + +```md title="docs/my-doc.md" +--- +tags: + - Releases + - docusaurus +--- + +# Title + +Content +``` + +```yml title="docs/tags.yml" +docusaurus: + label: 'Docusaurus' + permalink: '/docusaurus' + description: 'Docs related to the Docusaurus framework' +``` + +:::tip + +Tags can also be declared with `tags: [Demo, Getting started]`. + +Read more about all the possible [Yaml array syntaxes](https://www.w3schools.io/file/yaml-arrays/). + +::: + +## Organizing folder structure {#organizing-folder-structure} + +How the Markdown files are arranged under the `docs` folder can have multiple impacts on Docusaurus content generation. However, most of them can be decoupled from the file structure. + +### Document ID {#document-id} + +Every document has a unique `id`. By default, a document `id` is the name of the document (without the extension) relative to the root docs directory. + +For example, the ID of `greeting.md` is `greeting`, and the ID of `guide/hello.md` is `guide/hello`. + +```bash +website # Root directory of your site +└── docs + ├── greeting.md + └── guide + └── hello.md +``` + +However, the **last part** of the `id` can be defined by the user in the front matter. For example, if `guide/hello.md`'s content is defined as below, its final `id` is `guide/part1`. + +```md +--- +id: part1 +--- + +Lorem ipsum +``` + +The ID is used to refer to a document when hand-writing sidebars, or when using docs-related layout components or hooks. + +### Doc URLs {#doc-urls} + +By default, a document's URL location is its file path relative to the `docs` folder, with a few exceptions. Namely, if a file is named one the following, the file name won't be included in the URL: + +- Named as `index` (case-insensitive): `docs/Guides/index.md` +- Named as `README` (case-insensitive): `docs/Guides/README.mdx` +- Same name as parent folder: `docs/Guides/Guides.md` + +In all cases, the default slug would only be `/Guides`, without the `/index`, `/README`, or duplicate `/Guides` segment. + +:::note + +This convention is exactly the same as [the category index convention](./sidebar/autogenerated.mdx#category-index-convention). However, the `isCategoryIndex` configuration does _not_ affect the document URL. + +::: + +Use the `slug` front matter to change a document's URL. + +For example, suppose your site structure looks like this: + +```bash +website # Root directory of your site +└── docs + └── guide + └── hello.md +``` + +By default `hello.md` will be available at `/docs/guide/hello`. You can change its URL location to `/docs/bonjour`: + +```md +--- +slug: /bonjour +--- + +Lorem ipsum +``` + +`slug` will be appended to the doc plugin's `routeBasePath`, which is `/docs` by default. See [Docs-only mode](docs-introduction.mdx#docs-only-mode) for how to remove the `/docs` part from the URL. + +:::note + +It is possible to use: + +- absolute slugs: `slug: /mySlug`, `slug: /`... +- relative slugs: `slug: mySlug`, `slug: ./../mySlug`... + +::: + +If you want a document to be available at the root, and have a path like `https://docusaurus.io/docs/`, you can use the slug front matter: + +```md +--- +id: my-home-doc +slug: / +--- + +Lorem ipsum +``` + +### Sidebars {#sidebars} + +When using [autogenerated sidebars](./sidebar/autogenerated.mdx), the file structure will determine the sidebar structure. + +Our recommendation for file system organization is: make your file system mirror the sidebar structure (so you don't need to handwrite your `sidebars.js` file), and use the `slug` front matter to customize URLs of each document. diff --git a/website/versioned_docs/version-3.7.0/guides/docs/docs-introduction.mdx b/website/versioned_docs/version-3.7.0/guides/docs/docs-introduction.mdx new file mode 100644 index 0000000000..3892c316be --- /dev/null +++ b/website/versioned_docs/version-3.7.0/guides/docs/docs-introduction.mdx @@ -0,0 +1,120 @@ +--- +id: introduction +sidebar_label: Introduction +slug: /docs-introduction +--- + +# Docs Introduction + +The docs feature provides users with a way to organize Markdown files in a hierarchical format. + +:::info + +Check the [Docs Plugin API Reference documentation](./../../api/plugins/plugin-content-docs.mdx) for an exhaustive list of options. + +::: + +Your site's documentation is organized by four levels, from lowest to highest: + +1. Individual pages. +2. Sidebars. +3. Versions. +4. Plugin instances. + +The guide will introduce them in that order: starting from [how individual pages can be configured](./docs-create-doc.mdx), to [how to create a sidebar or multiple ones](./sidebar/index.mdx), to [how to create and manage versions](./versioning.mdx), to [how to use multiple docs plugin instances](./docs-multi-instance.mdx). + +## Docs-only mode {#docs-only-mode} + +A freshly initialized Docusaurus site has the following structure: + +``` +example.com/ -> generated from `src/pages/index.js` + +example.com/docs/intro -> generated from `docs/intro.md` +example.com/docs/tutorial-basics/... -> generated from `docs/tutorial-basics/...` +... + +example.com/blog/2021/08/26/welcome -> generated from `blog/2021-08-26-welcome/index.md` +example.com/blog/2021/08/01/mdx-blog-post -> generated from `blog/2021-08-01-mdx-blog-post.mdx` +... +``` + +All docs will be served under the subroute `docs/`. But what if **your site only has docs**, or you want to prioritize your docs by putting them at the root? + +Assume that you have the following in your configuration: + +```js title="docusaurus.config.js" +export default { + // ... + presets: [ + [ + '@docusaurus/preset-classic', + { + docs: { + /* docs plugin options */ + }, + blog: { + /* blog plugin options */ + }, + // ... + }, + ], + ], +}; +``` + +To enter docs-only mode, change it to like this: + +```js title="docusaurus.config.js" +export default { + // ... + presets: [ + [ + '@docusaurus/preset-classic', + { + docs: { + // highlight-next-line + routeBasePath: '/', // Serve the docs at the site's root + /* other docs plugin options */ + }, + // highlight-next-line + blog: false, // Optional: disable the blog plugin + // ... + }, + ], + ], +}; +``` + +Note that you **don't necessarily have to give up on using the blog** or other plugins; all that `routeBasePath: '/'` does is that instead of serving the docs through `https://example.com/docs/some-doc`, they are now at the site root: `https://example.com/some-doc`. The blog, if enabled, can still be accessed through the `blog/` subroute. + +Don't forget to put some page at the root (`https://example.com/`) through adding the front matter: + +```md title="docs/intro.md" +--- +# highlight-next-line +slug: / +--- + +This page will be the home page when users visit https://example.com/. +``` + +:::warning + +If you added `slug: /` to a doc to make it the homepage, you should delete the existing homepage at `./src/pages/index.js`, or else there will be two files mapping to the same route! + +::: + +Now, the site's structure will be like the following: + +``` +example.com/ -> generated from `docs/intro.md` +example.com/tutorial-basics/... -> generated from `docs/tutorial-basics/...` +... +``` + +:::tip + +There's also a "blog-only mode" for those who only want to use the blog feature of Docusaurus. You can use the same method detailed above. Follow the setup instructions on [Blog-only mode](../../blog.mdx#blog-only-mode). + +::: diff --git a/website/versioned_docs/version-3.7.0/guides/docs/docs-multi-instance.mdx b/website/versioned_docs/version-3.7.0/guides/docs/docs-multi-instance.mdx new file mode 100644 index 0000000000..3fd9a607f9 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/guides/docs/docs-multi-instance.mdx @@ -0,0 +1,213 @@ +--- +id: multi-instance +description: Use multiple docs plugin instances on a single Docusaurus site. +slug: /docs-multi-instance +--- + +# Docs Multi-instance + +The `@docusaurus/plugin-content-docs` plugin can support [multi-instance](../../using-plugins.mdx#multi-instance-plugins-and-plugin-ids). + +:::note + +This feature is only useful for [versioned documentation](./versioning.mdx). It is recommended to be familiar with docs versioning before reading this page. If you just want [multiple sidebars](./sidebar/multiple-sidebars.mdx), you can do so within one plugin. + +::: + +## Use-cases {#use-cases} + +Sometimes you want a Docusaurus site to host 2 distinct sets of documentation (or more). + +These documentations may even have different versioning/release lifecycles. + +### Mobile SDKs documentation {#mobile-sdks-documentation} + +If you build a cross-platform mobile SDK, you may have 2 documentations: + +- Android SDK documentation (`v1.0`, `v1.1`) +- iOS SDK documentation (`v1.0`, `v2.0`) + +In this case, you can use a distinct docs plugin instance per mobile SDK documentation. + +:::warning + +If each documentation instance is very large, you should rather create 2 distinct Docusaurus sites. + +If someone edits the iOS documentation, is it really useful to rebuild everything, including the whole Android documentation that did not change? + +::: + +### Versioned and unversioned doc {#versioned-and-unversioned-doc} + +Sometimes, you want some documents to be versioned, while other documents are more "global", and it feels useless to version them. + +We use this pattern on the Docusaurus website itself: + +- The [/docs/\*](/docs) section is versioned +- The [/community/\*](/community/support) section is unversioned + +## Setup {#setup} + +Suppose you have 2 documentations: + +- Product: some versioned doc about your product +- Community: some unversioned doc about the community around your product + +In this case, you should use the same plugin twice in your site configuration. + +:::warning + +`@docusaurus/preset-classic` already includes a docs plugin instance for you! + +::: + +When using the preset: + +```js title="docusaurus.config.js" +export default { + presets: [ + [ + '@docusaurus/preset-classic', + { + docs: { + // highlight-start + // id: 'product', // omitted => default instance + // highlight-end + path: 'product', + routeBasePath: 'product', + sidebarPath: './sidebarsProduct.js', + // ... other options + }, + }, + ], + ], + plugins: [ + [ + '@docusaurus/plugin-content-docs', + { + // highlight-start + id: 'community', + // highlight-end + path: 'community', + routeBasePath: 'community', + sidebarPath: './sidebarsCommunity.js', + // ... other options + }, + ], + ], +}; +``` + +When not using the preset: + +```js title="docusaurus.config.js" +export default { + plugins: [ + [ + '@docusaurus/plugin-content-docs', + { + // highlight-start + // id: 'product', // omitted => default instance + // highlight-end + path: 'product', + routeBasePath: 'product', + sidebarPath: './sidebarsProduct.js', + // ... other options + }, + ], + [ + '@docusaurus/plugin-content-docs', + { + // highlight-start + id: 'community', + // highlight-end + path: 'community', + routeBasePath: 'community', + sidebarPath: './sidebarsCommunity.js', + // ... other options + }, + ], + ], +}; +``` + +Don't forget to assign a unique `id` attribute to plugin instances. + +:::note + +We consider that the `product` instance is the most important one, and make it the "default" instance by not assigning any ID. + +::: + +## Versioned paths {#versioned-paths} + +Each plugin instance will store versioned docs in a distinct folder. + +The default plugin instance will use these paths: + +- `website/versions.json` +- `website/versioned_docs` +- `website/versioned_sidebars` + +The other plugin instances (with an `id` attribute) will use these paths: + +- `website/[pluginId]_versions.json` +- `website/[pluginId]_versioned_docs` +- `website/[pluginId]_versioned_sidebars` + +:::tip + +You can omit the `id` attribute (defaults to `default`) for one of the docs plugin instances. + +The instance paths will be simpler, and retro-compatible with a single-instance setup. + +::: + +## Tagging new versions {#tagging-new-versions} + +Each plugin instance will have its own CLI command to tag a new version. They will be displayed if you run: + +```bash npm2yarn +npm run docusaurus -- --help +``` + +To version the product/default docs plugin instance: + +```bash npm2yarn +npm run docusaurus docs:version 1.0.0 +``` + +To version the non-default/community docs plugin instance: + +```bash npm2yarn +npm run docusaurus docs:version:community 1.0.0 +``` + +## Docs navbar items {#docs-navbar-items} + +Each docs-related [theme navbar items](../../api/themes/theme-configuration.mdx#navbar) take an optional `docsPluginId` attribute. + +For example, if you want to have one version dropdown for each mobile SDK (iOS and Android), you could do: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + items: [ + { + type: 'docsVersionDropdown', + // highlight-start + docsPluginId: 'ios', + // highlight-end + }, + { + type: 'docsVersionDropdown', + // highlight-start + docsPluginId: 'android', + // highlight-end + }, + ], + }, + }, +}; +``` diff --git a/website/versioned_docs/version-3.7.0/guides/docs/sidebar/autogenerated.mdx b/website/versioned_docs/version-3.7.0/guides/docs/sidebar/autogenerated.mdx new file mode 100644 index 0000000000..7e3bfcf0a0 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/guides/docs/sidebar/autogenerated.mdx @@ -0,0 +1,497 @@ +--- +slug: /sidebar/autogenerated +--- + +# Autogenerated + +```mdx-code-block +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +``` + +Docusaurus can **create a sidebar automatically** from your **filesystem structure**: each folder creates a sidebar category, and each file creates a doc link. + +```ts +type SidebarItemAutogenerated = { + type: 'autogenerated'; + dirName: string; // Source folder to generate the sidebar slice from (relative to docs) +}; +``` + +Docusaurus can generate a full sidebar from your docs folder: + +```js title="sidebars.js" +export default { + myAutogeneratedSidebar: [ + // highlight-start + { + type: 'autogenerated', + dirName: '.', // '.' means the current docs folder + }, + // highlight-end + ], +}; +``` + +An `autogenerated` item is converted by Docusaurus to a **sidebar slice** (also discussed in [category shorthands](items.mdx#category-shorthand)): a list of items of type `doc` or `category`, so you can splice **multiple `autogenerated` items** from multiple directories, interleaving them with regular sidebar items, in one sidebar level. + +
+A real-world example + +Consider this file structure: + +```bash +docs +├── api +│ ├── product1-api +│ │ └── api.md +│ └── product2-api +│ ├── basic-api.md +│ └── pro-api.md +├── intro.md +└── tutorials + ├── advanced + │ ├── advanced1.md + │ ├── advanced2.md + │ └── read-more + │ ├── resource1.md + │ └── resource2.md + ├── easy + │ ├── easy1.md + │ └── easy2.md + ├── tutorial-end.md + ├── tutorial-intro.md + └── tutorial-medium.md +``` + +And assume every doc's ID is just its file name. If you define an autogenerated sidebar like this: + +```js title="sidebars.js" +export default { + mySidebar: [ + 'intro', + { + type: 'category', + label: 'Tutorials', + items: [ + 'tutorial-intro', + // highlight-start + { + type: 'autogenerated', + dirName: 'tutorials/easy', // Generate sidebar slice from docs/tutorials/easy + }, + // highlight-end + 'tutorial-medium', + // highlight-start + { + type: 'autogenerated', + dirName: 'tutorials/advanced', // Generate sidebar slice from docs/tutorials/advanced + }, + // highlight-end + 'tutorial-end', + ], + }, + // highlight-start + { + type: 'autogenerated', + dirName: 'api', // Generate sidebar slice from docs/api + }, + // highlight-end + { + type: 'category', + label: 'Community', + items: ['team', 'chat'], + }, + ], +}; +``` + +It would be resolved as: + +```js title="sidebars.js" +export default { + mySidebar: [ + 'intro', + { + type: 'category', + label: 'Tutorials', + items: [ + 'tutorial-intro', + // highlight-start + // Two files in docs/tutorials/easy + 'easy1', + 'easy2', + // highlight-end + 'tutorial-medium', + // highlight-start + // Two files and a folder in docs/tutorials/advanced + 'advanced1', + 'advanced2', + { + type: 'category', + label: 'read-more', + items: ['resource1', 'resource2'], + }, + // highlight-end + 'tutorial-end', + ], + }, + // highlight-start + // Two folders in docs/api + { + type: 'category', + label: 'product1-api', + items: ['api'], + }, + { + type: 'category', + label: 'product2-api', + items: ['basic-api', 'pro-api'], + }, + // highlight-end + { + type: 'category', + label: 'Community', + items: ['team', 'chat'], + }, + ], +}; +``` + +Note how the autogenerate source directories themselves don't become categories: only the items they contain do. This is what we mean by "sidebar slice". + +
+ +## Category index convention {#category-index-convention} + +Docusaurus can automatically link a category to its index document. + +A category index document is a document following one of those filename conventions: + +- Named as `index` (case-insensitive): `docs/Guides/index.md` +- Named as `README` (case-insensitive): `docs/Guides/README.mdx` +- Same name as parent folder: `docs/Guides/Guides.md` + +This is equivalent to using a category with a [doc link](items.mdx#category-doc-link): + +```js title="sidebars.js" +export default { + docs: [ + // highlight-start + { + type: 'category', + label: 'Guides', + link: {type: 'doc', id: 'Guides/index'}, + items: [], + }, + // highlight-end + ], +}; +``` + +:::tip + +Naming your introductory document `README.md` makes it show up when browsing the folder using the GitHub interface, while using `index.md` makes the behavior more in line with how HTML files are served. + +::: + +:::tip + +If a folder only has one index page, it will be turned into a link instead of a category. This is useful for **asset collocation**: + +``` +some-doc +├── index.md +├── img1.png +└── img2.png +``` + +::: + +
+ +Customizing category index matching + +It is possible to opt out any of the category index conventions, or define even more conventions. You can inject your own `isCategoryIndex` matcher through the [`sidebarItemsGenerator`](#customize-the-sidebar-items-generator) callback. For example, you can also pick `intro` as another file name eligible for automatically becoming the category index. + +```js title="docusaurus.config.js" +export default { + plugins: [ + [ + '@docusaurus/plugin-content-docs', + { + async sidebarItemsGenerator({ + ...args, + isCategoryIndex: defaultCategoryIndexMatcher, // The default matcher implementation, given below + defaultSidebarItemsGenerator, + }) { + return defaultSidebarItemsGenerator({ + ...args, + // highlight-start + isCategoryIndex(doc) { + return ( + // Also pick intro.md in addition to the default ones + doc.fileName.toLowerCase() === 'intro' || + defaultCategoryIndexMatcher(doc) + ); + }, + // highlight-end + }); + }, + }, + ], + ], +}; +``` + +Or choose to not have any category index convention. + +```js title="docusaurus.config.js" +export default { + plugins: [ + [ + '@docusaurus/plugin-content-docs', + { + async sidebarItemsGenerator({ + ...args, + isCategoryIndex: defaultCategoryIndexMatcher, // The default matcher implementation, given below + defaultSidebarItemsGenerator, + }) { + return defaultSidebarItemsGenerator({ + ...args, + // highlight-start + isCategoryIndex() { + // No doc will be automatically picked as category index + return false; + }, + // highlight-end + }); + }, + }, + ], + ], +}; +``` + +The `isCategoryIndex` matcher will be provided with three fields: + +- `fileName`, the file's name without extension and with casing preserved +- `directories`, the list of directory names _from the lowest level to the highest level_, relative to the docs root directory +- `extension`, the file's extension, with a leading dot. + +For example, for a doc file at `guides/sidebar/autogenerated.md`, the props the matcher receives are + +```js +const props = { + fileName: 'autogenerated', + directories: ['sidebar', 'guides'], + extension: '.md', +}; +``` + +The default implementation is: + +```js +function isCategoryIndex({fileName, directories}) { + const eligibleDocIndexNames = [ + 'index', + 'readme', + directories[0].toLowerCase(), + ]; + return eligibleDocIndexNames.includes(fileName.toLowerCase()); +} +``` + +
+ +## Autogenerated sidebar metadata {#autogenerated-sidebar-metadata} + +For handwritten sidebar definitions, you would provide metadata to sidebar items through `sidebars.js`; for autogenerated, Docusaurus would read them from the item's respective file. In addition, you may want to adjust the relative position of each item because, by default, items within a sidebar slice will be generated in **alphabetical order** (using file and folder names). + +### Doc item metadata {#doc-item-metadata} + +The `label`, `className`, and `customProps` attributes are declared in front matter as `sidebar_label`, `sidebar_class_name`, and `sidebar_custom_props`, respectively. Position can be specified in the same way, via `sidebar_position` front matter. + +```md title="docs/tutorials/tutorial-easy.md" +--- +# highlight-start +sidebar_position: 2 +sidebar_label: Easy +sidebar_class_name: green +# highlight-end +--- + +# Easy Tutorial + +This is the easy tutorial! +``` + +### Category item metadata {#category-item-metadata} + +Add a `_category_.json` or `_category_.yml` file in the respective folder. You can specify any category metadata and also the `position` metadata. `label`, `className`, `position`, and `customProps` will default to the respective values of the category's linked doc, if there is one. + + + + +```json title="docs/tutorials/_category_.json" +{ + "position": 2.5, + "label": "Tutorial", + "collapsible": true, + "collapsed": false, + "className": "red", + "link": { + "type": "generated-index", + "title": "Tutorial overview" + }, + "customProps": { + "description": "This description can be used in the swizzled DocCard" + } +} +``` + + + + +```yml title="docs/tutorials/_category_.yml" +position: 2.5 # float position is supported +label: 'Tutorial' +collapsible: true # make the category collapsible +collapsed: false # keep the category open by default +className: red +link: + type: generated-index + title: Tutorial overview +customProps: + description: This description can be used in the swizzled DocCard +``` + + + + +:::info + +If the `link` is explicitly specified, Docusaurus will not apply any [default conventions](#category-index-convention). + +The doc links can be specified relatively, e.g. if the category is generated with the `guides` directory, `"link": {"type": "doc", "id": "intro"}` will be resolved to the ID `guides/intro`, only falling back to `intro` if a doc with the former ID doesn't exist. + +You can also use `link: null` to opt out of default conventions and not generate any category index page. + +::: + +:::info + +The position metadata is only used **within a sidebar slice**: Docusaurus does not re-order other items of your sidebar. + +::: + +## Using number prefixes {#using-number-prefixes} + +A simple way to order an autogenerated sidebar is to prefix docs and folders by number prefixes, which also makes them appear in the file system in the same order when sorted by file name: + +```bash +docs +├── 01-Intro.md +├── 02-Tutorial Easy +│ ├── 01-First Part.md +│ ├── 02-Second Part.md +│ └── 03-End.md +├── 03-Tutorial Advanced +│ ├── 01-First Part.md +│ ├── 02-Second Part.md +│ ├── 03-Third Part.md +│ └── 04-End.md +└── 04-End.md +``` + +To make it **easier to adopt**, Docusaurus supports **multiple number prefix patterns**. + +By default, Docusaurus will **remove the number prefix** from the doc id, title, label, and URL paths. + +:::warning + +**Prefer using [additional metadata](#autogenerated-sidebar-metadata)**. + +Updating a number prefix can be annoying, as it can require **updating multiple existing Markdown links**: + +```diff title="docs/02-Tutorial Easy/01-First Part.md" +- Check the [Tutorial End](../04-End.mdx); ++ Check the [Tutorial End](../05-End.mdx); +``` + +::: + +## Customize the sidebar items generator {#customize-the-sidebar-items-generator} + +You can provide a custom `sidebarItemsGenerator` function in the docs plugin (or preset) config: + +```js title="docusaurus.config.js" +export default { + plugins: [ + [ + '@docusaurus/plugin-content-docs', + { + // highlight-start + async sidebarItemsGenerator({ + defaultSidebarItemsGenerator, + numberPrefixParser, + item, + version, + docs, + categoriesMetadata, + isCategoryIndex, + }) { + // Example: return an hardcoded list of static sidebar items + return [ + {type: 'doc', id: 'doc1'}, + {type: 'doc', id: 'doc2'}, + ]; + }, + // highlight-end + }, + ], + ], +}; +``` + +:::tip + +**Re-use and enhance the default generator** instead of writing a generator from scratch: [the default generator we provide](https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-plugin-content-docs/src/sidebars/generator.ts) is 250 lines long. + +**Add, update, filter, re-order** the sidebar items according to your use case: + +```js title="docusaurus.config.js" +// highlight-start +// Reverse the sidebar items ordering (including nested category items) +function reverseSidebarItems(items) { + // Reverse items in categories + const result = items.map((item) => { + if (item.type === 'category') { + return {...item, items: reverseSidebarItems(item.items)}; + } + return item; + }); + // Reverse items at current level + result.reverse(); + return result; +} +// highlight-end + +export default { + plugins: [ + [ + '@docusaurus/plugin-content-docs', + { + // highlight-start + async sidebarItemsGenerator({defaultSidebarItemsGenerator, ...args}) { + const sidebarItems = await defaultSidebarItemsGenerator(args); + return reverseSidebarItems(sidebarItems); + }, + // highlight-end + }, + ], + ], +}; +``` + +::: diff --git a/website/versioned_docs/version-3.7.0/guides/docs/sidebar/index.mdx b/website/versioned_docs/version-3.7.0/guides/docs/sidebar/index.mdx new file mode 100644 index 0000000000..4d2c4d209b --- /dev/null +++ b/website/versioned_docs/version-3.7.0/guides/docs/sidebar/index.mdx @@ -0,0 +1,218 @@ +--- +slug: /sidebar +--- + +# Sidebar + +Creating a sidebar is useful to: + +- Group multiple **related documents** +- **Display a sidebar** on each of those documents +- Provide **paginated navigation**, with next/previous button + +To use sidebars on your Docusaurus site: + +1. Define a sidebars file that exports a dictionary of [sidebar objects](#sidebar-object). +2. Pass its path to the `@docusaurus/plugin-docs` plugin directly or via `@docusaurus/preset-classic`. + +```js title="docusaurus.config.js" +export default { + presets: [ + [ + '@docusaurus/preset-classic', + { + docs: { + // highlight-next-line + sidebarPath: './sidebars.js', + }, + }, + ], + ], +}; +``` + +:::important Node.js runtime + +The sidebars file is run with Node.js. You can't use or import browsers APIs, React or JSX in it. + +::: + +This section serves as an overview of miscellaneous features of the doc sidebar. In the following sections, we will more systematically introduce the following concepts: + +```mdx-code-block +import DocCardList from '@theme/DocCardList'; + + +``` + +## Default sidebar {#default-sidebar} + +If the `sidebarPath` is unspecified, Docusaurus [automatically generates a sidebar](autogenerated.mdx) for you, by using the filesystem structure of the `docs` folder: + +```js title="sidebars.js" +export default { + mySidebar: [ + { + type: 'autogenerated', + dirName: '.', // generate sidebar from the docs folder (or versioned_docs/) + }, + ], +}; +``` + +You can also define your sidebars explicitly. + +## Sidebar object {#sidebar-object} + +A sidebar is a hierarchy of categories, doc links, and other hyperlinks. + +```ts +type Sidebar = + // Normal syntax + | SidebarItem[] + // Shorthand syntax + | {[categoryLabel: string]: SidebarItem[]}; +``` + +For example: + +```js title="sidebars.js" +export default { + mySidebar: [ + { + type: 'category', + label: 'Getting Started', + items: [ + { + type: 'doc', + id: 'doc1', + }, + ], + }, + { + type: 'category', + label: 'Docusaurus', + items: [ + { + type: 'doc', + id: 'doc2', + }, + { + type: 'doc', + id: 'doc3', + }, + ], + }, + { + type: 'link', + label: 'Learn more', + href: 'https://example.com', + }, + ], +}; +``` + +This is a sidebars file that exports one sidebar, called `mySidebar`. It has three top-level items: two categories and one external link. Within each category, there are a few doc links. + +A sidebars file can contain [**multiple sidebar objects**](multiple-sidebars.mdx), identified by their object keys. + +```ts +type SidebarsFile = { + [sidebarID: string]: Sidebar; +}; +``` + +## Theme configuration {#theme-configuration} + +### Hideable sidebar {#hideable-sidebar} + +By enabling the `themeConfig.docs.sidebar.hideable` option, you can make the entire sidebar hideable, allowing users to better focus on the content. This is especially useful when content is consumed on medium-sized screens (e.g. tablets). + +```js title="docusaurus.config.js" +export default { + themeConfig: { + // highlight-start + docs: { + sidebar: { + hideable: true, + }, + }, + // highlight-end + }, +}; +``` + +### Auto-collapse sidebar categories {#auto-collapse-sidebar-categories} + +The `themeConfig.docs.sidebar.autoCollapseCategories` option would collapse all sibling categories when expanding one category. This saves the user from having too many categories open and helps them focus on the selected section. + +```js title="docusaurus.config.js" +export default { + themeConfig: { + // highlight-start + docs: { + sidebar: { + autoCollapseCategories: true, + }, + }, + // highlight-end + }, +}; +``` + +## Passing custom props {#passing-custom-props} + +To pass in custom props to a sidebar item, add the optional `customProps` object to any of the items. This is useful to apply site customizations by swizzling React components rendering sidebar items. + +```js +{ + type: 'doc', + id: 'doc1', + // highlight-start + customProps: { + badges: ['new', 'green'], + featured: true, + }, + // highlight-end +}; +``` + +## Sidebar Breadcrumbs {#sidebar-breadcrumbs} + +By default, breadcrumbs are rendered at the top, using the "sidebar path" of the current page. + +This behavior can be disabled with plugin options: + +```js title="docusaurus.config.js" +export default { + presets: [ + [ + '@docusaurus/preset-classic', + { + docs: { + // highlight-next-line + breadcrumbs: false, + }, + }, + ], + ], +}; +``` + +## Complex sidebars example {#complex-sidebars-example} + +A real-world example from the Docusaurus site: + +```mdx-code-block +import CodeBlock from '@theme/CodeBlock'; + + + {require('!!raw-loader!@site/sidebars.ts') + .default + .split('\n') + // remove comments + .map((line) => !['//','/*','*'].some(commentPattern => line.trim().startsWith(commentPattern)) && line) + .filter(Boolean) + .join('\n')} + +``` diff --git a/website/versioned_docs/version-3.7.0/guides/docs/sidebar/items.mdx b/website/versioned_docs/version-3.7.0/guides/docs/sidebar/items.mdx new file mode 100644 index 0000000000..1dd0c0100e --- /dev/null +++ b/website/versioned_docs/version-3.7.0/guides/docs/sidebar/items.mdx @@ -0,0 +1,619 @@ +--- +toc_max_heading_level: 4 +slug: /sidebar/items +--- + +# Sidebar items + +```mdx-code-block +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import BrowserWindow from '@site/src/components/BrowserWindow'; +``` + +We have introduced three types of item types in the example in the previous section: `doc`, `category`, and `link`, whose usages are fairly intuitive. We will formally introduce their APIs. There's also a fourth type: `autogenerated`, which we will explain in detail later. + +- **[Doc](#sidebar-item-doc)**: link to a doc page, associating it with the sidebar +- **[Link](#sidebar-item-link)**: link to any internal or external page +- **[Category](#sidebar-item-category)**: creates a dropdown of sidebar items +- **[Autogenerated](autogenerated.mdx)**: generate a sidebar slice automatically +- **[HTML](#sidebar-item-html)**: renders pure HTML in the item's position +- **[\*Ref](multiple-sidebars.mdx#sidebar-item-ref)**: link to a doc page, without making the item take part in navigation generation + +## Doc: link to a doc {#sidebar-item-doc} + +Use the `doc` type to link to a doc page and assign that doc to a sidebar: + +```ts +type SidebarItemDoc = + // Normal syntax + | { + type: 'doc'; + id: string; + label: string; // Sidebar label text + className?: string; // Class name for sidebar label + customProps?: Record; // Custom props + } + + // Shorthand syntax + | string; // docId shortcut +``` + +Example: + +```js title="sidebars.js" +export default { + mySidebar: [ + // Normal syntax: + // highlight-start + { + type: 'doc', + id: 'doc1', // document ID + label: 'Getting started', // sidebar label + }, + // highlight-end + + // Shorthand syntax: + // highlight-start + 'doc2', // document ID + // highlight-end + ], +}; +``` + +If you use the doc shorthand or [autogenerated](autogenerated.mdx) sidebar, you would lose the ability to customize the sidebar label through item definition. You can, however, use the `sidebar_label` Markdown front matter within that doc, which has higher precedence over the `label` key in the sidebar item. Similarly, you can use `sidebar_custom_props` to declare custom metadata for a doc page. + +:::note + +A `doc` item sets an [implicit sidebar association](./multiple-sidebars.mdx#sidebar-association). Don't assign the same doc to multiple sidebars: change the type to `ref` instead. + +::: + +:::tip + +Sidebar custom props is a useful way to propagate arbitrary doc metadata to the client side, so you can get additional information when using any doc-related hook that fetches a doc object. + +::: + +## Link: link to any page {#sidebar-item-link} + +Use the `link` type to link to any page (internal or external) that is not a doc. + +```ts +type SidebarItemLink = { + type: 'link'; + label: string; + href: string; + className?: string; + description?: string; +}; +``` + +Example: + +```js title="sidebars.js" +export default { + myLinksSidebar: [ + // highlight-start + // External link + { + type: 'link', + label: 'Facebook', // The link label + href: 'https://facebook.com', // The external URL + }, + // highlight-end + + // highlight-start + // Internal link + { + type: 'link', + label: 'Home', // The link label + href: '/', // The internal path + }, + // highlight-end + ], +}; +``` + +## HTML: render custom markup {#sidebar-item-html} + +Use the `html` type to render custom HTML within the item's `
  • ` tag. + +This can be useful for inserting custom items such as dividers, section titles, ads, and images. + +```ts +type SidebarItemHtml = { + type: 'html'; + value: string; + defaultStyle?: boolean; // Use default menu item styles + className?: string; +}; +``` + +Example: + +```js title="sidebars.js" +export default { + myHtmlSidebar: [ + // highlight-start + { + type: 'html', + value: 'Sponsor', // The HTML to be rendered + defaultStyle: true, // Use the default menu item styling + }, + // highlight-end + ], +}; +``` + +:::tip + +The menu item is already wrapped in an `
  • ` tag, so if your custom item is simple, such as a title, just supply a string as the value and use the `className` property to style it: + +```js title="sidebars.js" +export default { + myHtmlSidebar: [ + { + type: 'html', + value: 'Core concepts', + className: 'sidebar-title', + }, + ], +}; +``` + +::: + +## Category: create a hierarchy {#sidebar-item-category} + +Use the `category` type to create a hierarchy of sidebar items. + +```ts +type SidebarItemCategory = { + type: 'category'; + label: string; // Sidebar label text. + items: SidebarItem[]; // Array of sidebar items. + className?: string; + description?: string; + + // Category options: + collapsible: boolean; // Set the category to be collapsible + collapsed: boolean; // Set the category to be initially collapsed or open by default + link: SidebarItemCategoryLinkDoc | SidebarItemCategoryLinkGeneratedIndex; +}; +``` + +Example: + +```js title="sidebars.js" +export default { + docs: [ + { + type: 'category', + label: 'Guides', + collapsible: true, + collapsed: false, + items: [ + 'creating-pages', + { + type: 'category', + label: 'Docs', + items: ['introduction', 'sidebar', 'markdown-features', 'versioning'], + }, + ], + }, + ], +}; +``` + +:::tip + +Use the [**shorthand syntax**](#category-shorthand) when you don't need customizations: + +```js title="sidebars.js" +export default { + docs: { + Guides: [ + 'creating-pages', + { + Docs: ['introduction', 'sidebar', 'markdown-features', 'versioning'], + }, + ], + }, +}; +``` + +::: + +### Category links {#category-link} + +With category links, clicking on a category can navigate you to another page. + +:::tip + +Use category links to introduce a category of documents. + +Autogenerated categories can use the [`_category_.yml`](./autogenerated.mdx#category-item-metadata) file to declare the link. + +::: + +#### Generated index page {#generated-index-page} + +You can auto-generate an index page that displays all the direct children of this category. The `slug` allows you to customize the generated page's route, which defaults to `/category/[categoryName]`. + +```js title="sidebars.js" +export default { + docs: [ + { + type: 'category', + label: 'Guides', + // highlight-start + link: { + type: 'generated-index', + title: 'Docusaurus Guides', + description: 'Learn about the most important Docusaurus concepts!', + slug: '/category/docusaurus-guides', + keywords: ['guides'], + image: '/img/docusaurus.png', + }, + // highlight-end + items: ['pages', 'docs', 'blog', 'search'], + }, + ], +}; +``` + +See it in action on the [Docusaurus Guides page](/docs/category/guides). + +:::tip + +Use `generated-index` links as a quick way to get an introductory document. + +::: + +#### Doc link {#category-doc-link} + +A category can link to an existing document. + +```js title="sidebars.js" +export default { + docs: [ + { + type: 'category', + label: 'Guides', + // highlight-start + link: {type: 'doc', id: 'introduction'}, + // highlight-end + items: ['pages', 'docs', 'blog', 'search'], + }, + ], +}; +``` + +See it in action on the [i18n introduction page](../../../i18n/i18n-introduction.mdx). + +#### Embedding generated index in doc page {#embedding-generated-index-in-doc-page} + +You can embed the generated cards list in a normal doc page as well with the `DocCardList` component. It will display all the sidebar items of the parent category of the current document. + +```md title="docs/sidebar/index.md" +import DocCardList from '@theme/DocCardList'; + + +``` + +```mdx-code-block + + +import DocCardList from '@theme/DocCardList'; + + + + +``` + +### Collapsible categories {#collapsible-categories} + +We support the option to expand/collapse categories. Categories are collapsible by default, but you can disable collapsing with `collapsible: false`. + +```js title="sidebars.js" +export default { + docs: [ + { + type: 'category', + label: 'Guides', + items: [ + 'creating-pages', + { + type: 'category', + // highlight-next-line + collapsible: false, + label: 'Docs', + items: ['introduction', 'sidebar', 'markdown-features', 'versioning'], + }, + ], + }, + ], +}; +``` + +To make all categories non-collapsible by default, set the `sidebarCollapsible` option in `plugin-content-docs` to `false`: + +```js title="docusaurus.config.js" +export default { + presets: [ + [ + '@docusaurus/preset-classic', + { + docs: { + // highlight-next-line + sidebarCollapsible: false, + }, + }, + ], + ], +}; +``` + +:::note + +The option in `sidebars.js` takes precedence over plugin configuration, so it is possible to make certain categories collapsible when `sidebarCollapsible` is set to `false` globally. + +::: + +### Expanded categories by default {#expanded-categories-by-default} + +Collapsible categories are collapsed by default. If you want them to be expanded on the first render, you can set `collapsed` to `false`: + +```js title="sidebars.js" +export default { + docs: { + Guides: [ + 'creating-pages', + { + type: 'category', + label: 'Docs', + // highlight-next-line + collapsed: false, + items: ['markdown-features', 'sidebar', 'versioning'], + }, + ], + }, +}; +``` + +Similar to `collapsible`, you can also set the global configuration `options.sidebarCollapsed` to `false`. Individual `collapsed` options in `sidebars.js` will still take precedence over this configuration. + +```js title="docusaurus.config.js" +export default { + presets: [ + [ + '@docusaurus/preset-classic', + { + docs: { + // highlight-next-line + sidebarCollapsed: false, + }, + }, + ], + ], +}; +``` + +:::warning + +When a category has `collapsed: true` but `collapsible: false` (either through `sidebars.js` or through plugin configuration), the latter takes precedence and the category is still rendered as expanded. + +::: + +## Using shorthands {#using-shorthands} + +You can express typical sidebar items without much customization more concisely with **shorthand syntaxes**. There are two parts to this: [**doc shorthand**](#doc-shorthand) and [**category shorthand**](#category-shorthand). + +### Doc shorthand {#doc-shorthand} + +An item with type `doc` can be simply a string representing its ID: + +```mdx-code-block + + +``` + +```js title="sidebars.js" +export default { + sidebar: [ + // highlight-start + { + type: 'doc', + id: 'myDoc', + }, + // highlight-end + ], +}; +``` + +```mdx-code-block + + +``` + +```js title="sidebars.js" +export default { + sidebar: [ + // highlight-start + 'myDoc', + // highlight-end + ], +}; +``` + +```mdx-code-block + + +``` + +So it's possible to simplify the example above to: + +```js title="sidebars.js" +export default { + mySidebar: [ + { + type: 'category', + label: 'Getting Started', + items: [ + // highlight-next-line + 'doc1', + ], + }, + { + type: 'category', + label: 'Docusaurus', + items: [ + // highlight-start + 'doc2', + 'doc3', + // highlight-end + ], + }, + { + type: 'link', + label: 'Learn more', + href: 'https://example.com', + }, + ], +}; +``` + +### Category shorthand {#category-shorthand} + +A category item can be represented by an object whose key is its label, and the value is an array of subitems. + +```mdx-code-block + + +``` + +```js title="sidebars.js" +export default { + sidebar: [ + // highlight-start + { + type: 'category', + label: 'Getting started', + items: ['doc1', 'doc2'], + }, + // highlight-end + ], +}; +``` + +```mdx-code-block + + +``` + +```js title="sidebars.js" +export default { + sidebar: [ + // highlight-start + { + 'Getting started': ['doc1', 'doc2'], + }, + // highlight-end + ], +}; +``` + +```mdx-code-block + + +``` + +This permits us to simplify that example to: + +```js title="sidebars.js" +export default { + mySidebar: [ + // highlight-start + { + 'Getting started': ['doc1'], + }, + { + Docusaurus: ['doc2', 'doc3'], + }, + // highlight-end + { + type: 'link', + label: 'Learn more', + href: 'https://example.com', + }, + ], +}; +``` + +Each shorthand object after this transformation will contain exactly one entry. Now consider the further simplified example below: + +```js title="sidebars.js" +export default { + mySidebar: [ + // highlight-start + { + 'Getting started': ['doc1'], + Docusaurus: ['doc2', 'doc3'], + }, + // highlight-end + { + type: 'link', + label: 'Learn more', + href: 'https://example.com', + }, + ], +}; +``` + +Note how the two consecutive category shorthands are compressed into one object with two entries. This syntax generates a **sidebar slice**: you shouldn't see that object as one bulk item—this object is unwrapped, with each entry becoming a separate item, and they spliced together with the rest of the items (in this case, the "Learn more" link) to form the final sidebar level. Sidebar slices are also important when discussing [autogenerated sidebars](autogenerated.mdx). + +Wherever you have an array of items that is reduced to one category shorthand, you can omit that enclosing array as well. + +```mdx-code-block + + +``` + +```js title="sidebars.js" +export default { + sidebar: [ + { + 'Getting started': ['doc1'], + Docusaurus: [ + { + 'Basic guides': ['doc2', 'doc3'], + 'Advanced guides': ['doc4', 'doc5'], + }, + ], + }, + ], +}; +``` + +```mdx-code-block + + +``` + +```js title="sidebars.js" +export default { + sidebar: { + 'Getting started': ['doc1'], + Docusaurus: { + 'Basic guides': ['doc2', 'doc3'], + 'Advanced guides': ['doc4', 'doc5'], + }, + }, +}; +``` + +```mdx-code-block + + +``` diff --git a/website/versioned_docs/version-3.7.0/guides/docs/sidebar/multiple-sidebars.mdx b/website/versioned_docs/version-3.7.0/guides/docs/sidebar/multiple-sidebars.mdx new file mode 100644 index 0000000000..d5fa60cb92 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/guides/docs/sidebar/multiple-sidebars.mdx @@ -0,0 +1,143 @@ +--- +slug: /sidebar/multiple-sidebars +--- + +# Using multiple sidebars + +You can create a sidebar for each **set of Markdown files** that you want to **group together**. + +:::tip + +The Docusaurus site is a good example of using multiple sidebars: + +- [Docs](../../../introduction.mdx) +- [API](../../../cli.mdx) + +::: + +Consider this example: + +```js title="sidebars.js" +export default { + tutorialSidebar: { + 'Category A': ['doc1', 'doc2'], + }, + apiSidebar: ['doc3', 'doc4'], +}; +``` + +When browsing `doc1` or `doc2`, the `tutorialSidebar` will be displayed; when browsing `doc3` or `doc4`, the `apiSidebar` will be displayed. + +## Understanding sidebar association {#sidebar-association} + +Following the example above, if a `commonDoc` is included in both sidebars: + +```js title="sidebars.js" +export default { + tutorialSidebar: { + 'Category A': ['doc1', 'doc2', 'commonDoc'], + }, + apiSidebar: ['doc3', 'doc4', 'commonDoc'], +}; +``` + +How does Docusaurus know which sidebar to display when browsing `commonDoc`? Answer: it doesn't, and we don't guarantee which sidebar it will pick. + +When you add doc Y to sidebar X, it creates a two-way binding: sidebar X contains a link to doc Y, and when browsing doc Y, sidebar X will be displayed. But sometimes, we want to break either implicit binding: + +1. _How do I generate a link to doc Y in sidebar X without making sidebar X displayed on Y?_ For example, when I include doc Y in multiple sidebars as in the example above, and I want to explicitly tell Docusaurus to display one sidebar? +2. _How do I make sidebar X displayed when browsing doc Y, but sidebar X shouldn't contain the link to Y?_ For example, when Y is a "doc home page" and the sidebar is purely used for navigation? + +Front matter option `displayed_sidebar` will forcibly set the sidebar association. For the same example, you can still use doc shorthands without any special configuration: + +```js title="sidebars.js" +export default { + tutorialSidebar: { + 'Category A': ['doc1', 'doc2'], + }, + apiSidebar: ['doc3', 'doc4'], +}; +``` + +And then add a front matter: + +```md title="commonDoc.md" +--- +displayed_sidebar: apiSidebar +--- +``` + +Which explicitly tells Docusaurus to display `apiSidebar` when browsing `commonDoc`. Using the same method, you can make sidebar X which doesn't contain doc Y appear on doc Y: + +```md title="home.md" +--- +displayed_sidebar: tutorialSidebar +--- +``` + +Even when `tutorialSidebar` doesn't contain a link to `home`, it will still be displayed when viewing `home`. + +If you set `displayed_sidebar: null`, no sidebar will be displayed whatsoever on this page, and subsequently, no pagination either. + +## Generating pagination {#generating-pagination} + +Docusaurus uses the sidebar to generate the "next" and "previous" pagination links at the bottom of each doc page. It strictly uses the sidebar that is displayed: if no sidebar is associated, it doesn't generate pagination either. However, the docs linked as "next" and "previous" are not guaranteed to display the same sidebar: they are included in this sidebar, but in their front matter, they may have a different `displayed_sidebar`. + +If a sidebar is displayed by setting `displayed_sidebar` front matter, and this sidebar doesn't contain the doc itself, no pagination is displayed. + +You can customize pagination with front matter `pagination_next` and `pagination_prev`. Consider this sidebar: + +```js title="sidebars.js" +export default { + tutorial: [ + 'introduction', + { + installation: ['windows', 'linux', 'macos'], + }, + 'getting-started', + ], +}; +``` + +The pagination next link on "windows" points to "linux", but that doesn't make sense: you would want readers to proceed to "getting started" after installation. In this case, you can set the pagination manually: + +```md title="windows.md" +--- +# highlight-next-line +pagination_next: getting-started +--- + +# Installation on Windows +``` + +You can also disable displaying a pagination link with `pagination_next: null` or `pagination_prev: null`. + +The pagination label by default is the sidebar label. You can use the front matter `pagination_label` to customize how this doc appears in the pagination. + +## The `ref` item {#sidebar-item-ref} + +The `ref` type is identical to the [`doc` type](./items.mdx#sidebar-item-doc) in every way, except that it doesn't participate in generating navigation metadata. It only registers itself as a link. When [generating pagination](#generating-pagination) and [displaying sidebar](#sidebar-association), `ref` items are completely ignored. + +It is particularly useful where you wish to link to the same document from multiple sidebars. The document only belongs to one sidebar (the one where it's registered as `type: 'doc'` or from an autogenerated directory), but its link will appear in all sidebars that it's registered in. + +Consider this example: + +```js title="sidebars.js" +export default { + tutorialSidebar: { + 'Category A': [ + 'doc1', + 'doc2', + // highlight-next-line + {type: 'ref', id: 'commonDoc'}, + 'doc5', + ], + }, + apiSidebar: ['doc3', 'doc4', 'commonDoc'], +}; +``` + +You can think of the `ref` type as the equivalent to doing the following: + +- Setting `displayed_sidebar: tutorialSidebar` for `commonDoc` (`ref` is ignored in sidebar association) +- Setting `pagination_next: doc5` for `doc2` and setting `pagination_prev: doc2` for `doc5` (`ref` is ignored in pagination generation) diff --git a/website/versioned_docs/version-3.7.0/guides/docs/versioning.mdx b/website/versioned_docs/version-3.7.0/guides/docs/versioning.mdx new file mode 100644 index 0000000000..08fab227b5 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/guides/docs/versioning.mdx @@ -0,0 +1,329 @@ +--- +slug: /versioning +--- + +# Versioning + +You can use the versioning CLI to create a new documentation version based on the latest content in the `docs` directory. That specific set of documentation will then be preserved and accessible even as the documentation in the `docs` directory continues to evolve. + +```mdx-code-block +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +``` + +:::warning + +Think about it before starting to version your documentation - it can become difficult for contributors to help improve it! + +::: + +Most of the time, you don't need versioning as it will just increase your build time, and introduce complexity to your codebase. Versioning is **best suited for websites with high-traffic and rapid changes to documentation between versions**. If your documentation rarely changes, don't add versioning to your documentation. + +To better understand how versioning works and see if it suits your needs, you can read on below. + +## Overview {#overview} + +A typical versioned doc site looks like below: + +```bash +website +├── sidebars.json # sidebar for the current docs version +├── docs # docs directory for the current docs version +│ ├── foo +│ │ └── bar.md # https://mysite.com/docs/next/foo/bar +│ └── hello.md # https://mysite.com/docs/next/hello +├── versions.json # file to indicate what versions are available +├── versioned_docs +│ ├── version-1.1.0 +│ │ ├── foo +│ │ │ └── bar.md # https://mysite.com/docs/foo/bar +│ │ └── hello.md +│ └── version-1.0.0 +│ ├── foo +│ │ └── bar.md # https://mysite.com/docs/1.0.0/foo/bar +│ └── hello.md +├── versioned_sidebars +│ ├── version-1.1.0-sidebars.json +│ └── version-1.0.0-sidebars.json +├── docusaurus.config.js +└── package.json +``` + +The `versions.json` file is a list of version names, ordered from newest to oldest. + +The table below explains how a versioned file maps to its version and the generated URL. + +| Path | Version | URL | +| --------------------------------------- | -------------- | ----------------- | +| `versioned_docs/version-1.0.0/hello.md` | 1.0.0 | /docs/1.0.0/hello | +| `versioned_docs/version-1.1.0/hello.md` | 1.1.0 (latest) | /docs/hello | +| `docs/hello.md` | current | /docs/next/hello | + +:::tip + +The files in the `docs` directory belong to the `current` docs version. + +By default, the `current` docs version is labeled as `Next` and hosted under `/docs/next/*`, but it is entirely configurable to fit your project's release lifecycle. + +::: + +### Terminology {#terminology} + +Note the terminology we use here. + +
    +
    + Current version +
    +
    + {'The version placed in the '} + ./docs + {' folder.'} +
    +
    + Latest version / last version +
    +
    + {'The version served by default for docs navbar items. Usually has path '} + /docs + {'.'} +
    +
    + +Current version is defined by the **file system location**, while latest version is defined by the **the navigation behavior**. They may or may not be the same version! (And the default configuration, as shown in the table above, would treat them as different: current version at `/docs/next` and latest at `/docs`.) + +## Tutorials {#tutorials} + +### Tagging a new version {#tagging-a-new-version} + +1. First, make sure the current docs version (the `./docs` directory) is ready to be frozen. +2. Enter a new version number. + +```bash npm2yarn +npm run docusaurus docs:version 1.1.0 +``` + +When tagging a new version, the document versioning mechanism will: + +- Copy the full `docs/` folder contents into a new `versioned_docs/version-[versionName]/` folder. +- Create a versioned sidebars file based from your current [sidebar](./sidebar/index.mdx) configuration (if it exists) - saved as `versioned_sidebars/version-[versionName]-sidebars.json`. +- Append the new version number to `versions.json`. + +### Creating new docs {#creating-new-docs} + +1. Place the new file into the corresponding version folder. +2. Include the reference to the new file in the corresponding sidebar file according to the version number. + +```mdx-code-block + + +``` + +```bash +# The new file. +docs/new.md + +# Edit the corresponding sidebar file. +sidebars.js +``` + +```mdx-code-block + + +``` + +```bash +# The new file. +versioned_docs/version-1.0.0/new.md + +# Edit the corresponding sidebar file. +versioned_sidebars/version-1.0.0-sidebars.json +``` + +```mdx-code-block + + +``` + +:::tip + +Versioned sidebar files are, like standard sidebar files, relative to the content root for the given version — so for the example above, your versioned sidebar file may look like: + +```json +{ + "sidebar": [ + { + "type": "autogenerated", + "dirName": "." + } + ] +} +``` + +or for a manual sidebar: + +```json +{ + "sidebar": [ + { + "type": "doc", + "id": "new", + "label": "New" + } + ] +} +``` + +::: + +### Updating an existing version {#updating-an-existing-version} + +You can update multiple docs versions at the same time because each directory in `versioned_docs/` represents specific routes when published. + +1. Edit any file. +2. Commit and push changes. +3. It will be published to the version. + +Example: When you change any file in `versioned_docs/version-2.6/`, it will only affect the docs for version `2.6`. + +### Deleting an existing version {#deleting-an-existing-version} + +You can delete/remove versions as well. + +1. Remove the version from `versions.json`. + +Example: + +```diff +[ + "2.0.0", + "1.9.0", + // highlight-next-line +- "1.8.0" +] +``` + +2. Delete the versioned docs directory. Example: `versioned_docs/version-1.8.0`. +3. Delete the versioned sidebars file. Example: `versioned_sidebars/version-1.8.0-sidebars.json`. + +## Configuring versioning behavior {#configuring-versioning-behavior} + +The "current" version is the version name for the `./docs` folder. There are different ways to manage versioning, but two very common patterns are: + +- You release v1, and start immediately working on v2 (including its docs). In this case, the **current version** is v2, which is in the `./docs` source folder, and can be browsed at `example.com/docs/next`. The **latest version** is v1, which is in the `./versioned_docs/version-1` source folder, and is browsed by most of your users at `example.com/docs`. +- You release v1, and will maintain it for some time before thinking about v2. In this case, the **current version** and **latest version** will both be point to v1, since the v2 docs doesn't even exist yet! + +Docusaurus defaults work great for the first use case. We will label the current version as "next" and you can even choose not to publish it. + +**For the 2nd use case**: if you release v1 and don't plan to work on v2 anytime soon, instead of versioning v1 and having to maintain the docs in 2 folders (`./docs` + `./versioned_docs/version-1.0.0`), you may consider "pretending" that the current version is a cut version by giving it a path and a label: + +```js title="docusaurus.config.js" +export default { + presets: [ + '@docusaurus/preset-classic', + docs: { + // highlight-start + lastVersion: 'current', + versions: { + current: { + label: '1.0.0', + path: '1.0.0', + }, + }, + // highlight-end + }, + ], +}; +``` + +The docs in `./docs` will be served at `/docs/1.0.0` instead of `/docs/next`, and `1.0.0` will become the default version we link to in the navbar dropdown, and you will only need to maintain a single `./docs` folder. + +We offer these plugin options to customize versioning behavior: + +- `disableVersioning`: Explicitly disable versioning even with versions. This will make the site only include the current version. +- `includeCurrentVersion`: Include the current version (the `./docs` folder) of your docs. + - **Tip**: turn it off if the current version is a work-in-progress, not ready to be published. +- `lastVersion`: Sets which version "latest version" (the `/docs` route) refers to. + - **Tip**: `lastVersion: 'current'` makes sense if your current version refers to a major version that's constantly patched and released. The actual route base path and label of the latest version are configurable. +- `onlyIncludeVersions`: Defines a subset of versions from `versions.json` to be deployed. + - **Tip**: limit to 2 or 3 versions in dev and deploy previews to improve startup and build time. +- `versions`: A dictionary of version metadata. For each version, you can customize the following: + - `label`: the label displayed in the versions dropdown and banner. + - `path`: the route base path of this version. By default, latest version has `/` and current version has `/next`. + - `banner`: one of `'none'`, `'unreleased'`, and `'unmaintained'`. Determines what's displayed at the top of every doc page. Any version above the latest version would be "unreleased", and any version below would be "unmaintained". + - `badge`: show a badge with the version name at the top of a doc of that version. + - `className`: add a custom `className` to the `` element of doc pages of that version. + +See [docs plugin configuration](../../api/plugins/plugin-content-docs.mdx#configuration) for more details. + +## Navbar items {#navbar-items} + +We offer several navbar items to help you quickly set up navigation without worrying about versioned routes. + +- [`doc`](../../api/themes/theme-configuration.mdx#navbar-doc-link): a link to a doc. +- [`docSidebar`](../../api/themes/theme-configuration.mdx#navbar-doc-sidebar): a link to the first item in a sidebar. +- [`docsVersion`](../../api/themes/theme-configuration.mdx#navbar-docs-version): a link to the main doc of the currently viewed version. +- [`docsVersionDropdown`](../../api/themes/theme-configuration.mdx#navbar-docs-version-dropdown): a dropdown containing all the versions available. + +These links would all look for an appropriate version to link to, in the following order: + +1. **Active version**: the version that the user is currently browsing, if she is on a page provided by this doc plugin. If she's not on a doc page, fall back to... +2. **Preferred version**: the version that the user last viewed. If there's no history, fall back to... +3. **Latest version**: the default version that we navigate to, configured by the `lastVersion` option. + +## Recommended practices {#recommended-practices} + +### Version your documentation only when needed {#version-your-documentation-only-when-needed} + +For example, you are building documentation for your npm package `foo` and you are currently in version 1.0.0. You then release a patch version for a minor bug fix and it's now 1.0.1. + +Should you cut a new documentation version 1.0.1? **You probably shouldn't**. 1.0.1 and 1.0.0 docs shouldn't differ according to semver because there are no new features!. Cutting a new version for it will only just create unnecessary duplicated files. + +### Keep the number of versions small {#keep-the-number-of-versions-small} + +As a good rule of thumb, try to keep the number of your versions below 10. You will **very likely** to have a lot of obsolete versioned documentation that nobody even reads anymore. For example, [Jest](https://jestjs.io/versions) is currently in version `27.4`, and only maintains several latest documentation versions with the lowest being `25.X`. Keep it small 😊 + +:::tip archive older versions + +If you deploy your site on a Jamstack provider (e.g. [Netlify](../../deployment.mdx)), the provider will save each production build as a snapshot under an immutable URL. You can include archived versions that will never be rebuilt as external links to these immutable URLs. The Jest website and the Docusaurus website both use such pattern to keep the number of actively built versions low. + +::: + +### Use absolute import within the docs {#use-absolute-import-within-the-docs} + +Don't use relative paths import within the docs. Because when we cut a version the paths no longer work (the nesting level is different, among other reasons). You can utilize the `@site` alias provided by Docusaurus that points to the `website` directory. Example: + +```diff +- import Foo from '../src/components/Foo'; ++ import Foo from '@site/src/components/Foo'; +``` + +### Link docs by file paths {#link-docs-by-file-paths} + +Refer to other docs by relative file paths with the `.md` extension, so that Docusaurus can rewrite them to actual URL paths during building. Files will be linked to the correct corresponding version. + +```md +The [@hello](hello.mdx#paginate) document is great! + +See the [Tutorial](../getting-started/tutorial.mdx) for more info. +``` + +### Global or versioned collocated assets {#global-or-versioned-collocated-assets} + +You should decide if assets like images and files are per-version or shared between versions. + +If your assets should be versioned, put them in the docs version, and use relative paths: + +```md +![img alt](./myImage.png) + +[download this file](./file.pdf) +``` + +If your assets are global, put them in `/static` and use absolute paths: + +```md +![img alt](/myImage.png) + +[download this file](/file.pdf) +``` diff --git a/website/versioned_docs/version-3.7.0/guides/markdown-features/_markdown-partial-example.mdx b/website/versioned_docs/version-3.7.0/guides/markdown-features/_markdown-partial-example.mdx new file mode 100644 index 0000000000..5eb3f3bf11 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/guides/markdown-features/_markdown-partial-example.mdx @@ -0,0 +1,3 @@ +Hello {props.name} + +This is text some content from `_markdown-partial-example.md`. diff --git a/website/versioned_docs/version-3.7.0/guides/markdown-features/markdown-features-admonitions.mdx b/website/versioned_docs/version-3.7.0/guides/markdown-features/markdown-features-admonitions.mdx new file mode 100644 index 0000000000..39353f5873 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/guides/markdown-features/markdown-features-admonitions.mdx @@ -0,0 +1,372 @@ +--- +id: admonitions +description: Handling admonitions/callouts in Docusaurus Markdown +slug: /markdown-features/admonitions +--- + +# Admonitions + +import BrowserWindow from '@site/src/components/BrowserWindow'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import Admonition from '@theme/Admonition'; + +In addition to the basic Markdown syntax, we have a special admonitions syntax by wrapping text with a set of 3 colons, followed by a label denoting its type. + +Example: + +```md +:::note + +Some **content** with _Markdown_ `syntax`. Check [this `api`](#). + +::: + +:::tip + +Some **content** with _Markdown_ `syntax`. Check [this `api`](#). + +::: + +:::info + +Some **content** with _Markdown_ `syntax`. Check [this `api`](#). + +::: + +:::warning + +Some **content** with _Markdown_ `syntax`. Check [this `api`](#). + +::: + +:::danger + +Some **content** with _Markdown_ `syntax`. Check [this `api`](#). + +::: +``` + +```mdx-code-block + + +:::note + +Some **content** with _Markdown_ `syntax`. Check [this `api`](#). + +::: + +:::tip + +Some **content** with _Markdown_ `syntax`. Check [this `api`](#). + +::: + +:::info + +Some **content** with _Markdown_ `syntax`. Check [this `api`](#). + +::: + +:::warning + +Some **content** with _Markdown_ `syntax`. Check [this `api`](#). + +::: + +:::danger + +Some **content** with _Markdown_ `syntax`. Check [this `api`](#). + +::: + + +``` + +## Usage with Prettier {#usage-with-prettier} + +If you use [Prettier](https://prettier.io) to format your Markdown files, Prettier might auto-format your code to invalid admonition syntax. To avoid this problem, add empty lines around the starting and ending directives. This is also why the examples we show here all have empty lines around the content. + +{/* prettier-ignore */} +```md + +:::note + +Hello world + +::: + + +:::note +Hello world +::: + + +::: note Hello world::: +``` + +## Specifying title {#specifying-title} + +You may also specify an optional title. + +```md +:::note[Your Title **with** some _Markdown_ `syntax`!] + +Some **content** with some _Markdown_ `syntax`. + +::: +``` + +```mdx-code-block + + +:::note[Your Title **with** some _Markdown_ `syntax`!] + +Some **content** with some _Markdown_ `syntax`. + +::: + + +``` + +## Nested admonitions {#nested-admonitions} + +Admonitions can be nested. Use more colons `:` for each parent admonition level. + +```md +:::::info Parent + +Parent content + +::::danger Child + +Child content + +:::tip Deep Child + +Deep child content + +::: + +:::: + +::::: +``` + +```mdx-code-block + + +:::::info Parent + +Parent content + +::::danger Child + +Child content + +:::tip Deep Child + +Deep child content + +::: + +:::: + +::::: + + +``` + +## Admonitions with MDX {#admonitions-with-mdx} + +You can use MDX inside admonitions too! + +```jsx +import Tabs from '@theme/Tabs'; + +import TabItem from '@theme/TabItem'; + +:::tip[Use tabs in admonitions] + + + This is an apple 🍎 + This is an orange 🍊 + This is a banana 🍌 + + +::: +``` + +```mdx-code-block + + +:::tip[Use tabs in admonitions] + + + This is an apple 🍎 + This is an orange 🍊 + This is a banana 🍌 + + +::: + + +``` + +## Usage in JSX {#usage-in-jsx} + +Outside of Markdown, you can use the `@theme/Admonition` component to get the same output. + +```jsx title="MyReactPage.jsx" +import Admonition from '@theme/Admonition'; + +export default function MyReactPage() { + return ( +
    + +

    Some information

    +
    +
    + ); +} +``` + +The types that are accepted are the same as above: `note`, `tip`, `danger`, `info`, `warning`. Optionally, you can specify an icon by passing a JSX element or a string, or a title: + +```jsx title="MyReactPage.jsx" + + Use plugins to introduce shorter syntax for the most commonly used JSX + elements in your project. + +``` + +```mdx-code-block + + + Use plugins to introduce shorter syntax for the most commonly used JSX + elements in your project. + + +``` + +## Customizing admonitions {#customizing-admonitions} + +There are two kinds of customizations possible with admonitions: **parsing** and **rendering**. + +### Customizing rendering behavior {#customizing-rendering-behavior} + +You can customize how each individual admonition type is rendered through [swizzling](../../swizzling.mdx). You can often achieve your goal through a simple wrapper. For example, in the follow example, we swap out the icon for `info` admonitions only. + +```jsx title="src/theme/Admonition.js" +import React from 'react'; +import Admonition from '@theme-original/Admonition'; +import MyCustomNoteIcon from '@site/static/img/info.svg'; + +export default function AdmonitionWrapper(props) { + if (props.type !== 'info') { + return ; + } + return } {...props} />; +} +``` + +### Customizing parsing behavior {#customizing-parsing-behavior} + +Admonitions are implemented with a [Remark plugin](./markdown-features-plugins.mdx). The plugin is designed to be configurable. To customize the Remark plugin for a specific content plugin (docs, blog, pages), pass the options through the `admonitions` key. + +```js title="docusaurus.config.js" +export default { + presets: [ + [ + '@docusaurus/preset-classic', + { + docs: { + admonitions: { + keywords: ['note', 'tip', 'info', 'warning', 'danger'], + extendDefaults: true, + }, + }, + }, + ], + ], +}; +``` + +The plugin accepts the following options: + +- `keywords`: An array of keywords that can be used as the type for the admonition. +- `extendDefaults`: Should the provided options (such as `keywords`) be merged into the existing defaults. Defaults to `true`. + +The `keyword` will be passed as the `type` prop of the `Admonition` component. + +### Custom admonition type components {#custom-admonition-type-components} + +By default, the theme doesn't know what do to with custom admonition keywords such as `:::my-custom-admonition`. It is your responsibility to map each admonition keyword to a React component so that the theme knows how to render them. + +If you registered a new admonition type `my-custom-admonition` via the following config: + +```js title="docusaurus.config.js" +export default { + // ... + presets: [ + [ + 'classic', + { + // ... + docs: { + admonitions: { + keywords: ['my-custom-admonition'], + extendDefaults: true, + }, + }, + }, + ], + ], +}; +``` + +You can provide the corresponding React component for `:::my-custom-admonition` by creating the following file (unfortunately, since it's not a React component file, it's not swizzlable): + +```js title="src/theme/Admonition/Types.js" +import React from 'react'; +import DefaultAdmonitionTypes from '@theme-original/Admonition/Types'; + +function MyCustomAdmonition(props) { + return ( +
    +
    {props.title}
    +
    {props.children}
    +
    + ); +} + +const AdmonitionTypes = { + ...DefaultAdmonitionTypes, + + // Add all your custom admonition types here... + // You can also override the default ones if you want + 'my-custom-admonition': MyCustomAdmonition, +}; + +export default AdmonitionTypes; +``` + +Now you can use your new admonition keyword in a Markdown file, and it will be parsed and rendered with your custom logic: + +```md +:::my-custom-admonition[My Title] + +It works! + +::: +``` + + + +:::my-custom-admonition[My Title] + +It works! + +::: + + diff --git a/website/versioned_docs/version-3.7.0/guides/markdown-features/markdown-features-assets.mdx b/website/versioned_docs/version-3.7.0/guides/markdown-features/markdown-features-assets.mdx new file mode 100644 index 0000000000..fa75c8f676 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/guides/markdown-features/markdown-features-assets.mdx @@ -0,0 +1,235 @@ +--- +id: assets +description: Handling assets in Docusaurus Markdown +slug: /markdown-features/assets +--- + +# Assets + +import BrowserWindow from '@site/src/components/BrowserWindow'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Sometimes you want to link to assets (e.g. docx files, images...) directly from Markdown files, and it is convenient to co-locate the asset next to the Markdown file using it. + +Let's imagine the following file structure: + +``` +# Your doc +/website/docs/myFeature.mdx + +# Some assets you want to use +/website/docs/assets/docusaurus-asset-example-banner.png +/website/docs/assets/docusaurus-asset-example.docx +``` + +## Images {#images} + +You can display images in three different ways: Markdown syntax, CJS require, or ES imports syntax. + +```mdx-code-block + + +``` + +Display images using simple Markdown syntax: + +```md +![Example banner](./assets/docusaurus-asset-example-banner.png) +``` + +```mdx-code-block + + +``` + +Display images using inline CommonJS `require` in JSX image tag: + +```jsx +Example banner +``` + +```mdx-code-block + + +``` + +Display images using ES `import` syntax and JSX image tag: + +```jsx +import myImageUrl from './assets/docusaurus-asset-example-banner.png'; + +Example banner; +``` + +```mdx-code-block + + +``` + +All of the above result in displaying the image: + + + +![My image alternative text](../../assets/docusaurus-asset-example-banner.png) + + + +:::note + +If you are using [@docusaurus/plugin-ideal-image](../../api/plugins/plugin-ideal-image.mdx), you need to use the dedicated image component, as documented. + +::: + +## Files {#files} + +In the same way, you can link to existing assets by `require`'ing them and using the returned URL in `video`s, `a` anchor links, etc. + +```md +# My Markdown page + +
    Download this docx + +or + +[Download this docx using Markdown](./assets/docusaurus-asset-example.docx) +``` + + + + + {'Download this docx'} + + +[Download this docx using Markdown](../../assets/docusaurus-asset-example.docx) + + + +:::info Markdown links are always file paths + +If you use the Markdown image or link syntax, all asset paths will be resolved as file paths by Docusaurus and automatically converted to `require()` calls. You don't need to use `require()` in Markdown unless you use the JSX syntax, which you do have to handle yourself. + +::: + +## Inline SVGs {#inline-svgs} + +Docusaurus supports inlining SVGs out of the box. + +```jsx +import DocusaurusSvg from './docusaurus.svg'; + +; +``` + + + +import DocusaurusSvg from '@site/static/img/docusaurus.svg'; + + + + + +This can be useful if you want to alter the part of the SVG image via CSS. For example, you can change one of the SVG colors based on the current theme. + +```jsx +import DocusaurusSvg from './docusaurus.svg'; + +; +``` + +```css +[data-theme='light'] .themedDocusaurus [fill='#FFFF50'] { + fill: greenyellow; +} + +[data-theme='dark'] .themedDocusaurus [fill='#FFFF50'] { + fill: seagreen; +} +``` + + + + + +## Themed Images {#themed-images} + +Docusaurus supports themed images: the `ThemedImage` component (included in the themes) allows you to switch the image source based on the current theme. + +```jsx +import useBaseUrl from '@docusaurus/useBaseUrl'; +import ThemedImage from '@theme/ThemedImage'; + +; +``` + +```mdx-code-block +import useBaseUrl from '@docusaurus/useBaseUrl'; +import ThemedImage from '@theme/ThemedImage'; + + + + +``` + +### GitHub-style themed images {#github-style-themed-images} + +GitHub uses its own [image theming approach](https://github.blog/changelog/2021-11-24-specify-theme-context-for-images-in-markdown/) with path fragments, which you can easily implement yourself. + +To toggle the visibility of an image using the path fragment (for GitHub, it's `#gh-dark-mode-only` and `#gh-light-mode-only`), add the following to your custom CSS (you can also use your own suffix if you don't want to be coupled to GitHub): + +```css title="src/css/custom.css" +[data-theme='light'] img[src$='#gh-dark-mode-only'], +[data-theme='dark'] img[src$='#gh-light-mode-only'] { + display: none; +} +``` + +```md +![Docusaurus themed image](/img/docusaurus_keytar.svg#gh-light-mode-only)![Docusaurus themed image](/img/docusaurus_speed.svg#gh-dark-mode-only) +``` + + + +![Docusaurus themed image](/img/docusaurus_keytar.svg#gh-light-mode-only)![Docusaurus themed image](/img/docusaurus_speed.svg#gh-dark-mode-only) + + + +## Static assets {#static-assets} + +If a Markdown link or image has an absolute path, the path will be seen as a file path and will be resolved from the static directories. For example, if you have configured [static directories](../../static-assets.mdx) to be `['public', 'static']`, then for the following image: + +```md title="my-doc.md" +![An image from the static](/img/docusaurus.png) +``` + +Docusaurus will try to look for it in both `static/img/docusaurus.png` and `public/img/docusaurus.png`. The link will then be converted to a `require()` call instead of staying as a URL. This is desirable in two regards: + +1. You don't have to worry about the base URL, which Docusaurus will take care of when serving the asset; +2. The image enters Webpack's build pipeline and its name will be appended by a hash, which enables browsers to aggressively cache the image and improves your site's performance. + +If you intend to write URLs, you can use the `pathname://` protocol to disable automatic asset linking. + +```md +![banner](pathname:///img/docusaurus-asset-example-banner.png) +``` + +This link will be generated as `banner`, without any processing or file existence checking. diff --git a/website/versioned_docs/version-3.7.0/guides/markdown-features/markdown-features-code-blocks.mdx b/website/versioned_docs/version-3.7.0/guides/markdown-features/markdown-features-code-blocks.mdx new file mode 100644 index 0000000000..cfe3c3bfe6 --- /dev/null +++ b/website/versioned_docs/version-3.7.0/guides/markdown-features/markdown-features-code-blocks.mdx @@ -0,0 +1,852 @@ +--- +id: code-blocks +description: Handling code blocks in Docusaurus Markdown +slug: /markdown-features/code-blocks +--- + +# Code blocks + +import BrowserWindow from '@site/src/components/BrowserWindow'; +import CodeBlock from '@theme/CodeBlock'; + +Code blocks within documentation are super-powered 💪. + +## Code title {#code-title} + +You can add a title to the code block by adding a `title` key after the language (leave a space between them). + +````md +```jsx title="/src/components/HelloCodeTitle.js" +function HelloCodeTitle(props) { + return

    Hello, {props.name}

    ; +} +``` +```` + +```mdx-code-block + +``` + +```jsx title="/src/components/HelloCodeTitle.js" +function HelloCodeTitle(props) { + return

    Hello, {props.name}

    ; +} +``` + +```mdx-code-block +
    +``` + +## Syntax highlighting {#syntax-highlighting} + +Code blocks are text blocks wrapped around by strings of 3 backticks. You may check out [this reference](https://github.com/mdx-js/specification) for the specifications of MDX. + +````md +```js +console.log('Every repo must come with a mascot.'); +``` +```` + +Use the matching language meta string for your code block, and Docusaurus will pick up syntax highlighting automatically, powered by [Prism React Renderer](https://github.com/FormidableLabs/prism-react-renderer). + + + +```js +console.log('Every repo must come with a mascot.'); +``` + + + +### Theming {#theming} + +By default, the Prism [syntax highlighting theme](https://github.com/FormidableLabs/prism-react-renderer#theming) we use is [Palenight](https://github.com/FormidableLabs/prism-react-renderer/blob/master/packages/prism-react-renderer/src/themes/palenight.ts). You can change this to another theme by passing `theme` field in `prism` as `themeConfig` in your docusaurus.config.js. + +For example, if you prefer to use the `dracula` highlighting theme: + +```js title="docusaurus.config.js" +import {themes as prismThemes} from 'prism-react-renderer'; + +export default { + themeConfig: { + prism: { + // highlight-next-line + theme: prismThemes.dracula, + }, + }, +}; +``` + +Because a Prism theme is just a JS object, you can also write your own theme if you are not satisfied with the default. Docusaurus enhances the `github` and `vsDark` themes to provide richer highlight, and you can check our implementations for the [light](https://github.com/facebook/docusaurus/blob/main/website/src/utils/prismLight.ts) and [dark](https://github.com/facebook/docusaurus/blob/main/website/src/utils/prismDark.ts) code block themes. + +### Supported Languages {#supported-languages} + +By default, Docusaurus comes with a subset of [commonly used languages](https://github.com/FormidableLabs/prism-react-renderer/blob/master/packages/generate-prism-languages/index.ts#L9-L23). + +:::warning + +Some popular languages like Java, C#, or PHP are not enabled by default. + +::: + +To add syntax highlighting for any of the other [Prism-supported languages](https://prismjs.com/#supported-languages), define it in an array of additional languages. + +:::note + +Each additional language has to be a valid Prism component name. For example, Prism would map the _language_ `cs` to `csharp`, but only `prism-csharp.js` exists as a _component_, so you need to use `additionalLanguages: ['csharp']`. You can look into `node_modules/prismjs/components` to find all components (languages) available. + +::: + +For example, if you want to add highlighting for the PowerShell language: + +```js title="docusaurus.config.js" +export default { + // ... + themeConfig: { + prism: { + // highlight-next-line + additionalLanguages: ['powershell'], + }, + // ... + }, +}; +``` + +After adding `additionalLanguages`, restart Docusaurus. + +If you want to add highlighting for languages not yet supported by Prism, you can swizzle `prism-include-languages`: + +```bash npm2yarn +npm run swizzle @docusaurus/theme-classic prism-include-languages +``` + +It will produce `prism-include-languages.js` in your `src/theme` folder. You can add highlighting support for custom languages by editing `prism-include-languages.js`: + +```js title="src/theme/prism-include-languages.js" +const prismIncludeLanguages = (Prism) => { + // ... + + additionalLanguages.forEach((lang) => { + require(`prismjs/components/prism-${lang}`); + }); + + // highlight-next-line + require('/path/to/your/prism-language-definition'); + + // ... +}; +``` + +You can refer to [Prism's official language definitions](https://github.com/PrismJS/prism/tree/master/components) when you are writing your own language definitions. + +When adding a custom language definition, you do not need to add the language to the `additionalLanguages` config array, since Docusaurus only looks up the `additionalLanguages` strings in languages that Prism provides. Adding the language import in `prism-include-languages.js` is sufficient. + +## Line highlighting {#line-highlighting} + +### Highlighting with comments {#highlighting-with-comments} + +You can use comments with `highlight-next-line`, `highlight-start`, and `highlight-end` to select which lines are highlighted. + +````md +```js +function HighlightSomeText(highlight) { + if (highlight) { + // highlight-next-line + return 'This text is highlighted!'; + } + + return 'Nothing highlighted'; +} + +function HighlightMoreText(highlight) { + // highlight-start + if (highlight) { + return 'This range is highlighted!'; + } + // highlight-end + + return 'Nothing highlighted'; +} +``` +```` + +```mdx-code-block + +``` + +```js +function HighlightSomeText(highlight) { + if (highlight) { + // highlight-next-line + return 'This text is highlighted!'; + } + + return 'Nothing highlighted'; +} + +function HighlightMoreText(highlight) { + // highlight-start + if (highlight) { + return 'This range is highlighted!'; + } + // highlight-end + + return 'Nothing highlighted'; +} +``` + +```mdx-code-block + +``` + +Supported commenting syntax: + +| Style | Syntax | +| ---------- | ------------------------ | +| C-style | `/* ... */` and `// ...` | +| JSX-style | `{/* ... */}` | +| Bash-style | `# ...` | +| HTML-style | `` | + +We will do our best to infer which set of comment styles to use based on the language, and default to allowing _all_ comment styles. If there's a comment style that is not currently supported, we are open to adding them! Pull requests welcome. Note that different comment styles have no semantic difference, only their content does. + +You can set your own background color for highlighted code line in your `src/css/custom.css` which will better fit to your selected syntax highlighting theme. The color given below works for the default highlighting theme (Palenight), so if you are using another theme, you will have to tweak the color accordingly. + +```css title="/src/css/custom.css" +:root { + --docusaurus-highlighted-code-line-bg: rgb(72, 77, 91); +} + +/* If you have a different syntax highlighting theme for dark mode. */ +[data-theme='dark'] { + /* Color which works with dark mode syntax highlighting theme */ + --docusaurus-highlighted-code-line-bg: rgb(100, 100, 100); +} +``` + +If you also need to style the highlighted code line in some other way, you can target on `theme-code-block-highlighted-line` CSS class. + +### Highlighting with metadata string {#highlighting-with-metadata-string} + +You can also specify highlighted line ranges within the language meta string (leave a space after the language). To highlight multiple lines, separate the line numbers by commas or use the range syntax to select a chunk of lines. This feature uses the `parse-number-range` library and you can find [more syntax](https://www.npmjs.com/package/parse-numeric-range) on their project details. + +````md +```jsx {1,4-6,11} +import React from 'react'; + +function MyComponent(props) { + if (props.isBar) { + return
    Bar
    ; + } + + return
    Foo
    ; +} + +export default MyComponent; +``` +```` + +```mdx-code-block + +``` + +```jsx {1,4-6,11} +import React from 'react'; + +function MyComponent(props) { + if (props.isBar) { + return
    Bar
    ; + } + + return
    Foo
    ; +} + +export default MyComponent; +``` + +```mdx-code-block +
    +``` + +:::tip prefer comments + +Prefer highlighting with comments where you can. By inlining highlight in the code, you don't have to manually count the lines if your code block becomes long. If you add/remove lines, you also don't have to offset your line ranges. + +````diff +- ```jsx {3} ++ ```jsx {4} + function HighlightSomeText(highlight) { + if (highlight) { ++ console.log('Highlighted text found'); + return 'This text is highlighted!'; + } + + return 'Nothing highlighted'; + } + ``` +```` + +Below, we will introduce how the magic comment system can be extended to define custom directives and their functionalities. The magic comments would only be parsed if a highlight metastring is not present. + +::: + +### Custom magic comments {#custom-magic-comments} + +`// highlight-next-line` and `// highlight-start` etc. are called "magic comments", because they will be parsed and removed, and their purposes are to add metadata to the next line, or the section that the pair of start- and end-comments enclose. + +You can declare custom magic comments through theme config. For example, you can register another magic comment that adds a `code-block-error-line` class name: + +```mdx-code-block + + +``` + +```js +export default { + themeConfig: { + prism: { + magicComments: [ + // Remember to extend the default highlight class name as well! + { + className: 'theme-code-block-highlighted-line', + line: 'highlight-next-line', + block: {start: 'highlight-start', end: 'highlight-end'}, + }, + // highlight-start + { + className: 'code-block-error-line', + line: 'This will error', + }, + // highlight-end + ], + }, + }, +}; +``` + +```mdx-code-block + + +``` + +```css +.code-block-error-line { + background-color: #ff000020; + display: block; + margin: 0 calc(-1 * var(--ifm-pre-padding)); + padding: 0 var(--ifm-pre-padding); + border-left: 3px solid #ff000080; +} +``` + +```mdx-code-block + + +``` + +````md +In JavaScript, trying to access properties on `null` will error. + +```js +const name = null; +// This will error +console.log(name.toUpperCase()); +// Uncaught TypeError: Cannot read properties of null (reading 'toUpperCase') +``` +```` + +```mdx-code-block + + +``` + +```mdx-code-block + +``` + +In JavaScript, trying to access properties on `null` will error. + +```js +const name = null; +// This will error +console.log(name.toUpperCase()); +// Uncaught TypeError: Cannot read properties of null (reading 'toUpperCase') +``` + +```mdx-code-block + +``` + +If you use number ranges in metastring (the `{1,3-4}` syntax), Docusaurus will apply the **first `magicComments` entry**'s class name. This, by default, is `theme-code-block-highlighted-line`, but if you change the `magicComments` config and use a different entry as the first one, the meaning of the metastring range will change as well. + +You can disable the default line highlighting comments with `magicComments: []`. If there's no magic comment config, but Docusaurus encounters a code block containing a metastring range, it will error because there will be no class name to apply—the highlighting class name, after all, is just a magic comment entry. + +Every magic comment entry will contain three keys: `className` (required), `line`, which applies to the directly next line, or `block` (containing `start` and `end`), which applies to the entire block enclosed by the two comments. + +Using CSS to target the class can already do a lot, but you can unlock the full potential of this feature through [swizzling](../../swizzling.mdx). + +```bash npm2yarn +npm run swizzle @docusaurus/theme-classic CodeBlock/Line +``` + +The `Line` component will receive the list of class names, based on which you can conditionally render different markup. + +## Line numbering {#line-numbering} + +You can enable line numbering for your code block by using `showLineNumbers` key within the language meta string (don't forget to add space directly before the key). + +````md +```jsx {1,4-6,11} showLineNumbers +import React from 'react'; + +function MyComponent(props) { + if (props.isBar) { + return
    Bar
    ; + } + + return
    Foo
    ; +} + +export default MyComponent; +``` +```` + +```mdx-code-block + +``` + +```jsx {1,4-6,11} showLineNumbers +import React from 'react'; + +function MyComponent(props) { + if (props.isBar) { + return
    Bar
    ; + } + + return
    Foo
    ; +} + +export default MyComponent; +``` + +```mdx-code-block +
    +``` + +## Interactive code editor {#interactive-code-editor} + +(Powered by [React Live](https://github.com/FormidableLabs/react-live)) + +You can create an interactive coding editor with the `@docusaurus/theme-live-codeblock` plugin. First, add the plugin to your package. + +```bash npm2yarn +npm install --save @docusaurus/theme-live-codeblock +``` + +You will also need to add the plugin to your `docusaurus.config.js`. + +```js {3} +export default { + // ... + themes: ['@docusaurus/theme-live-codeblock'], + // ... +}; +``` + +To use the plugin, create a code block with `live` attached to the language meta string. + +````md +```jsx live +function Clock(props) { + const [date, setDate] = useState(new Date()); + useEffect(() => { + const timerID = setInterval(() => tick(), 1000); + + return function cleanup() { + clearInterval(timerID); + }; + }); + + function tick() { + setDate(new Date()); + } + + return ( +
    +

    It is {date.toLocaleTimeString()}.

    +
    + ); +} +``` +```` + +The code block will be rendered as an interactive editor. Changes to the code will reflect on the result panel live. + +```mdx-code-block + +``` + +```jsx live +function Clock(props) { + const [date, setDate] = useState(new Date()); + useEffect(() => { + const timerID = setInterval(() => tick(), 1000); + + return function cleanup() { + clearInterval(timerID); + }; + }); + + function tick() { + setDate(new Date()); + } + + return ( +
    +

    It is {date.toLocaleTimeString()}.

    +
    + ); +} +``` + +```mdx-code-block +
    +``` + +### Imports {#imports} + +:::warning react-live and imports + +It is not possible to import components directly from the react-live code editor, you have to define available imports upfront. + +::: + +By default, all React imports are available. If you need more imports available, swizzle the react-live scope: + +```bash npm2yarn +npm run swizzle @docusaurus/theme-live-codeblock ReactLiveScope -- --eject +``` + +```jsx title="src/theme/ReactLiveScope/index.js" +import React from 'react'; + +// highlight-start +const ButtonExample = (props) => ( +