diff --git a/packages/docusaurus-module-type-aliases/src/index.d.ts b/packages/docusaurus-module-type-aliases/src/index.d.ts index ff62e02e2832..1762316fde77 100644 --- a/packages/docusaurus-module-type-aliases/src/index.d.ts +++ b/packages/docusaurus-module-type-aliases/src/index.d.ts @@ -280,6 +280,12 @@ declare module '@docusaurus/useDocusaurusContext' { export default function useDocusaurusContext(): DocusaurusContext; } +declare module '@docusaurus/useThemeConfig' { + import type {ThemeConfig} from '@docusaurus/types'; + + export default function useThemeConfig(): ThemeConfig; +} + declare module '@docusaurus/useRouteContext' { import type {PluginRouteContext} from '@docusaurus/types'; diff --git a/packages/docusaurus-preset-classic/src/options.ts b/packages/docusaurus-preset-classic/src/options.ts index 6ac62497e7eb..6363bc478f6c 100644 --- a/packages/docusaurus-preset-classic/src/options.ts +++ b/packages/docusaurus-preset-classic/src/options.ts @@ -5,6 +5,9 @@ * LICENSE file in the root directory of this source tree. */ +// Adds the Algolia fields to the @docusaurus/types UserThemeConfig interface +/// + 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'; @@ -14,9 +17,8 @@ import type {Options as GtagPluginOptions} from '@docusaurus/plugin-google-gtag' import type {Options as GTMPluginOptions} from '@docusaurus/plugin-google-tag-manager'; import type {Options as CssCascadeLayersPluginOptions} from '@docusaurus/plugin-css-cascade-layers'; import type {Options as ThemeOptions} from '@docusaurus/theme-classic'; -import type {ThemeConfig as BaseThemeConfig} from '@docusaurus/types'; -import type {UserThemeConfig as ClassicThemeConfig} from '@docusaurus/theme-common'; -import type {UserThemeConfig as AlgoliaThemeConfig} from '@docusaurus/theme-search-algolia'; +// Importing from theme-common also adds the classic theme fields +import type {UserThemeConfig} from '@docusaurus/theme-common'; export type Options = { /** @@ -49,6 +51,5 @@ export type Options = { cssCascadeLayers?: false | CssCascadeLayersPluginOptions; }; -export type ThemeConfig = BaseThemeConfig & - ClassicThemeConfig & - AlgoliaThemeConfig; +// Theme config fields of all the themes of this preset, including Algolia's +export type ThemeConfig = UserThemeConfig; diff --git a/packages/docusaurus-theme-classic/src/options.ts b/packages/docusaurus-theme-classic/src/options.ts index 52501b718ab9..d310544ef1ab 100644 --- a/packages/docusaurus-theme-classic/src/options.ts +++ b/packages/docusaurus-theme-classic/src/options.ts @@ -13,6 +13,7 @@ import type { } from '@theme/NavbarItem/DocsVersionDropdownNavbarItem'; import type {Options, PluginOptions} from '@docusaurus/theme-classic'; import type {ThemeConfig} from '@docusaurus/theme-common'; +import type {ClassicThemeConfig} from '@docusaurus/theme-common/internal'; import type { ThemeConfigValidationContext, OptionValidationContext, @@ -58,7 +59,7 @@ const DEFAULT_COLOR_MODE_CONFIG: ThemeConfig['colorMode'] = { respectPrefersColorScheme: false, }; -export const DEFAULT_CONFIG: ThemeConfig = { +export const DEFAULT_CONFIG: ClassicThemeConfig = { colorMode: DEFAULT_COLOR_MODE_CONFIG, docs: DEFAULT_DOCS_CONFIG, blog: DEFAULT_BLOG_CONFIG, diff --git a/packages/docusaurus-theme-common/src/internal.ts b/packages/docusaurus-theme-common/src/internal.ts index fa8979347891..ece229aeb8cb 100644 --- a/packages/docusaurus-theme-common/src/internal.ts +++ b/packages/docusaurus-theme-common/src/internal.ts @@ -31,6 +31,8 @@ export { } from './utils/tabsUtils'; export type {TabValue, TabsProps, TabItemProps} from './utils/tabsUtils'; +export type {ClassicThemeConfig} from './utils/useThemeConfig'; + export {useNavbarMobileSidebar} from './contexts/navbarMobileSidebar'; export {useNavbarSecondaryMenu} from './contexts/navbarSecondaryMenu/display'; diff --git a/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts b/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts index d15df936d1fa..d3eed612ef0e 100644 --- a/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts +++ b/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts @@ -5,9 +5,10 @@ * LICENSE file in the root directory of this source tree. */ -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import useCoreThemeConfig from '@docusaurus/useThemeConfig'; import type {PrismTheme} from 'prism-react-renderer'; import type {DeepPartial} from 'utility-types'; +import type {ThemeConfig, UserThemeConfig} from '@docusaurus/types'; import type {MagicCommentConfig} from './codeBlockUtils'; import type {ColorMode} from '../contexts/colorMode'; @@ -104,9 +105,8 @@ type TableOfContents = { maxHeadingLevel: number; }; -// TODO Docusaurus v4: use interface + declaration merging to enhance -// Theme config after validation/normalization -export type ThemeConfig = { +// Theme config fields of the classic theme, after validation/normalization +export type ClassicThemeConfig = { docs: { versionPersistence: DocsVersionPersistence; sidebar: { @@ -136,12 +136,17 @@ export type ThemeConfig = { tableOfContents: TableOfContents; }; -// User-provided theme config, unnormalized -export type UserThemeConfig = DeepPartial; +// Adds the classic theme fields to the @docusaurus/types interfaces +declare module '@docusaurus/types' { + interface ThemeConfig extends ClassicThemeConfig {} + interface UserThemeConfig extends DeepPartial {} +} + +export type {ThemeConfig, UserThemeConfig}; /** - * A convenient/more semantic way to get theme config from context. + * Same as the `@docusaurus/useThemeConfig` hook of Docusaurus core. */ export function useThemeConfig(): ThemeConfig { - return useDocusaurusContext().siteConfig.themeConfig as ThemeConfig; + return useCoreThemeConfig(); } diff --git a/packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.ts b/packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.ts index 8ad793e64055..91c3b062070c 100644 --- a/packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.ts +++ b/packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.ts @@ -8,12 +8,10 @@ import {describe, expect, it} from 'vitest'; import {validateThemeConfig, DEFAULT_CONFIG} from '../validateThemeConfig'; import type {Joi} from '@docusaurus/utils-validation'; +import type {ThemeConfig} from '@docusaurus/theme-live-codeblock'; function testValidateThemeConfig(themeConfig: {[key: string]: unknown}) { - function validate( - schema: Joi.ObjectSchema<{[key: string]: unknown}>, - cfg: {[key: string]: unknown}, - ) { + function validate(schema: Joi.ObjectSchema, cfg: ThemeConfig) { const {value, error} = schema.validate(cfg, { convert: false, }); @@ -23,7 +21,11 @@ function testValidateThemeConfig(themeConfig: {[key: string]: unknown}) { return value; } - return validateThemeConfig({validate, themeConfig}); + // Some tests pass invalid theme configs on purpose + return validateThemeConfig({ + validate, + themeConfig: themeConfig as ThemeConfig, + }); } describe('validateThemeConfig', () => { diff --git a/packages/docusaurus-theme-live-codeblock/src/theme-live-codeblock.d.ts b/packages/docusaurus-theme-live-codeblock/src/theme-live-codeblock.d.ts index 550623f1fa31..0fe0b13b87b3 100644 --- a/packages/docusaurus-theme-live-codeblock/src/theme-live-codeblock.d.ts +++ b/packages/docusaurus-theme-live-codeblock/src/theme-live-codeblock.d.ts @@ -11,11 +11,26 @@ declare module '@docusaurus/theme-live-codeblock' { import type {PlaygroundPosition} from '@theme/Playground'; + export type ThemeConfigLiveCodeBlock = { + playgroundPosition: PlaygroundPosition; + }; + export type ThemeConfig = { - liveCodeBlock: { - playgroundPosition: PlaygroundPosition; - }; + liveCodeBlock: ThemeConfigLiveCodeBlock; }; + + // Adds the theme config fields to the @docusaurus/types interfaces + // Their names intentionally shadow the ThemeConfig types of this module + /* eslint-disable @typescript-eslint/no-shadow */ + module '@docusaurus/types' { + interface ThemeConfig { + liveCodeBlock: ThemeConfigLiveCodeBlock; + } + interface UserThemeConfig { + liveCodeBlock?: Partial; + } + } + /* eslint-enable @typescript-eslint/no-shadow */ } declare module '@theme/LiveCodeBlock' { diff --git a/packages/docusaurus-theme-live-codeblock/src/theme/Playground/Layout/index.tsx b/packages/docusaurus-theme-live-codeblock/src/theme/Playground/Layout/index.tsx index 157b7993e887..2d563d7a278f 100644 --- a/packages/docusaurus-theme-live-codeblock/src/theme/Playground/Layout/index.tsx +++ b/packages/docusaurus-theme-live-codeblock/src/theme/Playground/Layout/index.tsx @@ -6,20 +6,13 @@ */ import type {ReactNode} from 'react'; -import {useThemeConfig} from '@docusaurus/theme-common'; +import useThemeConfig from '@docusaurus/useThemeConfig'; import PlaygroundPreview from '@theme/Playground/Preview'; import PlaygroundEditor from '@theme/Playground/Editor'; import type {Props} from '@theme/Playground/Layout'; -import type {ThemeConfig} from '@docusaurus/theme-live-codeblock'; - -function useLiveCodeBlockThemeConfig() { - const themeConfig = useThemeConfig() as unknown as ThemeConfig; - return themeConfig.liveCodeBlock; -} - export default function PlaygroundLayout(props: Props): ReactNode { - const themeConfig = useLiveCodeBlockThemeConfig(); + const themeConfig = useThemeConfig().liveCodeBlock; const position = props.position ?? themeConfig.playgroundPosition; return ( <> diff --git a/packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.ts b/packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.ts index d642214987de..7a3421df8eb9 100644 --- a/packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.ts +++ b/packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.ts @@ -6,10 +6,8 @@ */ import {Joi} from '@docusaurus/utils-validation'; -import type { - ThemeConfig, - ThemeConfigValidationContext, -} from '@docusaurus/types'; +import type {ThemeConfig} from '@docusaurus/theme-live-codeblock'; +import type {ThemeConfigValidationContext} from '@docusaurus/types'; export const DEFAULT_CONFIG = { playgroundPosition: 'bottom', diff --git a/packages/docusaurus-theme-mermaid/src/client/index.ts b/packages/docusaurus-theme-mermaid/src/client/index.ts index c850cce7cad4..50c7cec8edb3 100644 --- a/packages/docusaurus-theme-mermaid/src/client/index.ts +++ b/packages/docusaurus-theme-mermaid/src/client/index.ts @@ -6,17 +6,18 @@ */ import {useState, useEffect, useMemo, useId, useRef} from 'react'; -import {useColorMode, useThemeConfig} from '@docusaurus/theme-common'; +import useThemeConfig from '@docusaurus/useThemeConfig'; +import {useColorMode} from '@docusaurus/theme-common'; import {loadMermaid} from './loadMermaid'; import type {RenderResult, MermaidConfig} from 'mermaid'; -import type {ThemeConfig} from '@docusaurus/theme-mermaid'; +import type {ThemeConfigMermaid} from '@docusaurus/theme-mermaid'; // Stable className to allow users to easily target with CSS export const MermaidContainerClassName = 'docusaurus-mermaid-container'; -export function useMermaidThemeConfig(): ThemeConfig['mermaid'] { - return (useThemeConfig() as unknown as ThemeConfig).mermaid; +export function useMermaidThemeConfig(): ThemeConfigMermaid { + return useThemeConfig().mermaid; } export function useMermaidConfig(): MermaidConfig { diff --git a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts index 33142adbd423..395e34460a48 100644 --- a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts +++ b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts @@ -12,17 +12,32 @@ declare module '@docusaurus/theme-mermaid' { import type {MermaidConfig} from 'mermaid'; import type {Plugin} from '@docusaurus/types'; - export type ThemeConfig = { - mermaid: { - theme: { - light: NonNullable; - dark: NonNullable; - }; - options: MermaidConfig; + export type ThemeConfigMermaid = { + theme: { + light: NonNullable; + dark: NonNullable; }; + options: MermaidConfig; + }; + + export type ThemeConfig = { + mermaid: ThemeConfigMermaid; }; export type UserThemeConfig = DeepPartial; + // Adds the theme config fields to the @docusaurus/types interfaces + // Their names intentionally shadow the ThemeConfig types of this module + /* eslint-disable @typescript-eslint/no-shadow */ + module '@docusaurus/types' { + interface ThemeConfig { + mermaid: ThemeConfigMermaid; + } + interface UserThemeConfig { + mermaid?: DeepPartial; + } + } + /* eslint-enable @typescript-eslint/no-shadow */ + export default function themeMermaid(): Plugin; } diff --git a/packages/docusaurus-theme-search-algolia/src/theme-search-algolia.d.ts b/packages/docusaurus-theme-search-algolia/src/theme-search-algolia.d.ts index c9360342fd93..d4b5778add2e 100644 --- a/packages/docusaurus-theme-search-algolia/src/theme-search-algolia.d.ts +++ b/packages/docusaurus-theme-search-algolia/src/theme-search-algolia.d.ts @@ -59,25 +59,40 @@ declare module '@docusaurus/theme-search-algolia' { }; }; + export type UserThemeConfigAlgolia = Overwrite< + DeepPartial, + { + // Required fields: + appId: ThemeConfigAlgolia['appId']; + apiKey: ThemeConfigAlgolia['apiKey']; + indexName: ThemeConfigAlgolia['indexName']; + // askAi also accepts a shorter string form + askAi?: string | Optional; + } + >; + export type ThemeConfig = { algolia: ThemeConfigAlgolia; }; export type UserThemeConfig = { - algolia?: Overwrite< - DeepPartial, - { - // Required fields: - appId: ThemeConfigAlgolia['appId']; - apiKey: ThemeConfigAlgolia['apiKey']; - indexName: ThemeConfigAlgolia['indexName']; - // askAi also accepts a shorter string form - askAi?: - | string - | Optional; - } - >; + algolia?: UserThemeConfigAlgolia; }; + + // Adds the theme config fields to the @docusaurus/types interfaces + // Their names intentionally shadow the ThemeConfig types of this module + /* eslint-disable @typescript-eslint/no-shadow */ + module '@docusaurus/types' { + interface ThemeConfig { + // Optional: the classic preset only enables this theme when the + // "algolia" field is provided + algolia?: ThemeConfigAlgolia; + } + interface UserThemeConfig { + algolia?: UserThemeConfigAlgolia; + } + } + /* eslint-enable @typescript-eslint/no-shadow */ } declare module '@theme/SearchPage' { diff --git a/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx b/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx index 6b46c11930ad..aa0cd473396e 100644 --- a/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx +++ b/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx @@ -15,6 +15,7 @@ import {useHistory} from '@docusaurus/router'; import {isRegexpStringMatch} from '@docusaurus/theme-common'; import { useAlgoliaContextualFacetFilters, + useAlgoliaThemeConfig, useSearchResultUrlProcessor, useAlgoliaAskAi, mergeFacetFilters, @@ -310,14 +311,14 @@ function DocSearch({externalUrlRegex, ...props}: DocSearchV4Props) { } export default function SearchBar(props: Partial): ReactNode { - const {siteConfig} = useDocusaurusContext(); + const {algolia} = useAlgoliaThemeConfig(); - const docSearchProps: DocSearchV4Props = { - ...(siteConfig.themeConfig.algolia as DocSearchV4Props), + const docSearchProps = { + ...algolia, // Let props override theme config // See https://github.com/facebook/docusaurus/pull/11581 ...props, - }; + } as DocSearchV4Props; return ; } diff --git a/packages/docusaurus-types/src/config.d.ts b/packages/docusaurus-types/src/config.d.ts index 96dff8c2ac0a..4c63b9d6eb62 100644 --- a/packages/docusaurus-types/src/config.d.ts +++ b/packages/docusaurus-types/src/config.d.ts @@ -15,9 +15,32 @@ import type {MarkdownConfig} from './markdown'; export type RouterType = 'browser' | 'hash'; -export type ThemeConfig = { +/** + * Theme config, after validation and normalization by themes and plugins. + * + * Themes and plugins can declare their own fields with declaration merging: + * + * ```ts + * declare module '@docusaurus/types' { + * interface ThemeConfig { + * myTheme: {position: 'top' | 'bottom'}; + * } + * } + * ``` + */ +export interface ThemeConfig { [key: string]: unknown; -}; +} + +/** + * Theme config, as written by users in their site config, before validation. + * + * Themes and plugins can declare their own fields with declaration merging, + * like for {@link ThemeConfig}. + */ +export interface UserThemeConfig { + [key: string]: unknown; +} export type StorageConfig = { type: SiteStorage['type']; @@ -403,5 +426,6 @@ export type Config = Overwrite< */ webpack?: boolean | WebpackConfig; future?: DeepPartial; + themeConfig?: UserThemeConfig; } >; diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index c523c79e4fb8..07abf4e4cd0b 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -8,6 +8,7 @@ export { RouterType, ThemeConfig, + UserThemeConfig, DocusaurusConfig, FutureConfig, WebpackConfig, diff --git a/packages/docusaurus/src/client/exports/useThemeConfig.ts b/packages/docusaurus/src/client/exports/useThemeConfig.ts new file mode 100644 index 000000000000..e99e4aed8070 --- /dev/null +++ b/packages/docusaurus/src/client/exports/useThemeConfig.ts @@ -0,0 +1,13 @@ +/** + * 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 './useDocusaurusContext'; +import type {ThemeConfig} from '@docusaurus/types'; + +export default function useThemeConfig(): ThemeConfig { + return useDocusaurusContext().siteConfig.themeConfig; +} diff --git a/packages/docusaurus/src/server/configValidation.ts b/packages/docusaurus/src/server/configValidation.ts index cbd96ef3595f..8d656833477d 100644 --- a/packages/docusaurus/src/server/configValidation.ts +++ b/packages/docusaurus/src/server/configValidation.ts @@ -27,6 +27,7 @@ import type { MarkdownConfig, MarkdownHooks, StorageConfig, + ThemeConfig, VcsConfig, VcsPreset, WebpackConfig, @@ -142,7 +143,8 @@ export const DEFAULT_CONFIG: Pick< scripts: [], clientModules: [], customFields: {}, - themeConfig: {}, + // Themes add their own fields when validating the theme config + themeConfig: {} as ThemeConfig, titleDelimiter: '|', noIndex: false, tagline: '', diff --git a/packages/docusaurus/src/webpack/__tests__/__snapshots__/base.test.ts.snap b/packages/docusaurus/src/webpack/__tests__/__snapshots__/base.test.ts.snap index 997ed1b3f24f..ea927f171235 100644 --- a/packages/docusaurus/src/webpack/__tests__/__snapshots__/base.test.ts.snap +++ b/packages/docusaurus/src/webpack/__tests__/__snapshots__/base.test.ts.snap @@ -22,6 +22,7 @@ exports[`base webpack config > creates webpack aliases 1`] = ` "@docusaurus/useIsBrowser": "../../../../client/exports/useIsBrowser.ts", "@docusaurus/useIsomorphicLayoutEffect": "../../../../client/exports/useIsomorphicLayoutEffect.tsx", "@docusaurus/useRouteContext": "../../../../client/exports/useRouteContext.tsx", + "@docusaurus/useThemeConfig": "../../../../client/exports/useThemeConfig.ts", "@generated": "../../../../../../..", "@mdx-js/react": "../../../../../../../node_modules/@mdx-js/react", "@site": "", diff --git a/packages/docusaurus/src/webpack/aliases/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus/src/webpack/aliases/__tests__/__snapshots__/index.test.ts.snap index 50f0f435fe47..137839bad8f2 100644 --- a/packages/docusaurus/src/webpack/aliases/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus/src/webpack/aliases/__tests__/__snapshots__/index.test.ts.snap @@ -22,6 +22,7 @@ exports[`getDocusaurusAliases > returns appropriate webpack aliases 1`] = ` "@docusaurus/useIsBrowser": "/packages/docusaurus/src/client/exports/useIsBrowser.ts", "@docusaurus/useIsomorphicLayoutEffect": "/packages/docusaurus/src/client/exports/useIsomorphicLayoutEffect.tsx", "@docusaurus/useRouteContext": "/packages/docusaurus/src/client/exports/useRouteContext.tsx", + "@docusaurus/useThemeConfig": "/packages/docusaurus/src/client/exports/useThemeConfig.ts", } `; diff --git a/website/docs/api/plugin-methods/static-methods.mdx b/website/docs/api/plugin-methods/static-methods.mdx index 6cd5e5124e58..e29f1cab5309 100644 --- a/website/docs/api/plugin-methods/static-methods.mdx +++ b/website/docs/api/plugin-methods/static-methods.mdx @@ -81,3 +81,20 @@ export function validateThemeConfig({themeConfig, validate}) { } // highlight-end ``` + +### TypeScript types {/* #validateThemeConfig-types */} + +The `@docusaurus/types` package declares the theme config types with 2 interfaces: `ThemeConfig` after validation and normalization, and `UserThemeConfig` as written in `docusaurus.config.js`. Your theme can add its own fields to them with TypeScript [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation): + +```ts title="my-theme/src/index.ts" +declare module '@docusaurus/types' { + interface ThemeConfig { + myTheme: {position: 'top' | 'bottom'}; + } + interface UserThemeConfig { + myTheme?: {position?: 'top' | 'bottom'}; + } +} +``` + +Once your theme types are loaded, [`useThemeConfig()`](../../docusaurus-core.mdx#useThemeConfig) returns a typed `myTheme` field, and site authors get autocompletion for `myTheme` in their `themeConfig`. diff --git a/website/docs/docusaurus-core.mdx b/website/docs/docusaurus-core.mdx index f5f15b989e89..bcdff16ce328 100644 --- a/website/docs/docusaurus-core.mdx +++ b/website/docs/docusaurus-core.mdx @@ -407,6 +407,25 @@ The `siteConfig` object only contains **serializable values** (values that are p ::: +### `useThemeConfig` {/* #useThemeConfig */} + +React hook to access the [`themeConfig`](api/docusaurus.config.js.mdx#themeConfig) object of the site, after themes and plugins have [validated and normalized it](api/plugin-methods/static-methods.mdx#validateThemeConfig). + +Its TypeScript type includes the fields declared by the themes and plugins you installed. + +Usage example: + +```jsx +import React from 'react'; +import useThemeConfig from '@docusaurus/useThemeConfig'; + +const MyComponent = () => { + // highlight-next-line + const {navbar} = useThemeConfig(); + return
{navbar.title}
; +}; +``` + ### `useIsBrowser` {/* #useIsBrowser */} Returns `true` after initial hydration completes in the browser. diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 2c1b5f4c769e..81466d301a48 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -4,6 +4,10 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ + +// Adds the liveCodeBlock fields to the Preset.ThemeConfig type +/// + import path from 'node:path'; import npm2yarn from '@docusaurus/remark-plugin-npm2yarn'; @@ -34,9 +38,6 @@ import type {Options as BlogOptions} from '@docusaurus/plugin-content-blog'; import type {Options as PageOptions} from '@docusaurus/plugin-content-pages'; import type {Options as IdealImageOptions} from '@docusaurus/plugin-ideal-image'; import type {Options as ClientRedirectsOptions} from '@docusaurus/plugin-client-redirects'; -import type {ThemeConfig as LiveCodeBlockThemeConfig} from '@docusaurus/theme-live-codeblock'; - -type ThemeConfig = Preset.ThemeConfig & LiveCodeBlockThemeConfig; const ArchivedVersionsDropdownItems = Object.entries(VersionsArchived).splice( 0, @@ -887,6 +888,6 @@ export default async function createConfigAsync() { }, copyright: `Copyright © ${new Date().getFullYear()} Meta Platforms, Inc. Built with Docusaurus.`, }, - } satisfies ThemeConfig, + } satisfies Preset.ThemeConfig, } satisfies Config; }