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;
}