/
githubmirror
/
docusaurus
Обзор
Документация
Войти
/
githubmirror
/
docusaurus
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
website/docs/docusaurus-core.mdx
779 строк
21 KB
lampovayatyan999
docs: improve useIsBrowser section, clarify hydration vs DOM availabi… (#12176)
18 июн 2026, 13:31
Не верифицирован
18 июн 2026, 13:31
698de7e
Код
Авторство
О чём код?
--- 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</title> <link rel="canonical" href="http://mysite.com/example" /> </Head> // highlight-end ); ``` Nested or latter components will override duplicate usages: ```jsx <Parent> {/* highlight-start */} <Head> <title>My Title</title> <meta name="description" content="Helmet application" /> </Head> {/* highlight-end */} <Child> {/* highlight-start */} <Head> <title>Nested Title</title> <meta name="description" content="Nested component" /> </Head> {/* highlight-end */} </Child> </Parent> ``` Outputs: ```html <head> <title>Nested Title</title> <meta name="description" content="Nested component" /> </head> ``` ### `<Link/>` {/* #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 `<Link>` 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 `<Link>` component that adds useful enhancements specific to Docusaurus. All props are passed through to react-router’s `<Link>` 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 = () => ( <div> <p> {/* highlight-next-line */} Check out my <Link to="/blog">blog</Link>! </p> <p> {/* highlight-next-line */} Follow me on <Link to="https://x.com/docusaurus">X</Link>! </p> </div> ); ``` #### `to`: string {/* #to-string */} The target location to navigate to. Example: `/docs/introduction`. ```jsx <Link to="/courses" /> ``` :::tip Prefer this component to vanilla `<a>` tags because Docusaurus does a lot of optimizations (e.g. broken path detection, prefetching, applying base URL...) if you use `<Link>`. ::: ### `<Redirect/>` {/* #redirect */} Rendering a `<Redirect>` 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 <Redirect to="/docs/test" />; }; ``` :::note `@docusaurus/router` implements [React Router](https://reacttraining.com/react-router/web/guides/quick-start) and supports its features. ::: ### `<BrowserOnly/>` {/* #browseronly */} The `<BrowserOnly>` 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 <BrowserOnly> {() => <span>page url = {window.location.href}</span>} </BrowserOnly> // 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 <BrowserOnly fallback={<div>Loading...</div>}> {() => { const LibComponent = require('some-lib').LibComponent; return <LibComponent {...props} />; }} </BrowserOnly> // highlight-end ); }; ``` ### `<Interpolate/>` {/* #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 <Interpolate values={{ firstName: 'Sébastien', website: ( <Link to="https://docusaurus.io" className="my-website-class"> website </Link> ), }}> {'Hello, {firstName}! How are you? Take a look at my {website}'} </Interpolate> // highlight-end ); } ``` ### `<Translate/>` {/* #translate */} When [localizing your site](./i18n/i18n-introduction.mdx), the `<Translate/>` component will allow providing **translation support to React components**, such as your homepage. The `<Translate>` 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 `<Translate/>` 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 ( <Layout> <h1> {/* highlight-start */} <Translate id="homepage.title" description="The homepage welcome message"> Welcome to my website </Translate> {/* highlight-end */} </h1> <main> {/* highlight-start */} <Translate values={{firstName: 'Sébastien'}}> {'Welcome, {firstName}! How are you?'} </Translate> {/* highlight-end */} </main> </Layout> ); } ``` :::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 <Translate id="homepage.title" /> ``` ::: :::info The `<Translate>` 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<string, PluginVersionInformation>; }; type I18nLocaleConfig = { label: string; direction: string; }; type I18n = { defaultLocale: string; locales: [string, ...string[]]; currentLocale: string; localeConfigs: Record<string, I18nLocaleConfig>; }; type DocusaurusContext = { siteConfig: DocusaurusConfig; siteMetadata: SiteMetadata; globalData: Record<string, unknown>; i18n: I18n; codeTranslations: Record<string, string>; }; ``` Usage example: ```jsx import React from 'react'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; const MyComponent = () => { // highlight-next-line const {siteConfig, siteMetadata} = useDocusaurusContext(); return ( <div> {/* highlight-start */} <h1>{siteConfig.title}</h1> <div>{siteMetadata.siteVersion}</div> <div>{siteMetadata.docusaurusVersion}</div> {/* highlight-end */} </div> ); }; ``` :::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` after initial hydration completes in the browser. :::warning Use this hook instead of `typeof window !== 'undefined'` in React rendering logic. The initial render output must be consistent between server and client — components should not depend on browser-only state during the initial render. See [The Perils of Rehydration](https://www.joshwcomeau.com/react/the-perils-of-rehydration/). `useIsBrowser()` and `typeof window !== 'undefined'` serve different purposes: - **`useIsBrowser()`** — tracks hydration state. Use it to gate UI behavior that should only activate after initial hydration. - **`typeof window !== 'undefined'`** — detects the runtime environment. Use it when you need to check DOM availability outside of React rendering logic. | Context | `useIsBrowser()` | `typeof window !== 'undefined'` | | --- | --- | --- | | Node.js / SSR | `false` | `false` | | During initial client render | `false` | `true` (DOM is available) | | After initial hydration | `true` | `true` | ::: Usage example: ```jsx import React from 'react'; import useIsBrowser from '@docusaurus/useIsBrowser'; const MyComponent = () => { const isBrowser = useIsBrowser(); return <div>{isBrowser ? 'Browser' : 'Server'}</div>; }; ``` ### `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 to="/my/path/">link</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 <img src={imgSrc} />; }; ``` :::tip In most cases, you don't need `useBaseUrl`. Prefer a `require()` call for [assets](./guides/markdown-features/markdown-features-assets.mdx): ```jsx <img src={require('@site/static/img/myImage.png').default} /> ``` ::: ### `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 <div>{/* ... */}</div>; }; ``` ### `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 <div>{myPluginData.someAttribute}</div>; // 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 <div>{myPluginData.someAttribute}</div>; // 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 <div>{myPluginData.someAttribute}</div>; // 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>`](#link) component will collect links for you - the `@theme/Heading` (used for Markdown headings) will collect anchors Use `useBrokenLinks()` if you implement your own `<Heading>` or `<Link>` component. ::: Usage example: ```js title="MyHeading.js" import useBrokenLinks from '@docusaurus/useBrokenLinks'; export default function MyHeading(props) { useBrokenLinks().collectAnchor(props.id); return <h2 {...props} />; } ``` ```js title="MyLink.js" import useBrokenLinks from '@docusaurus/useBrokenLinks'; export default function MyLink(props) { useBrokenLinks().collectLink(props.href); return <a {...props} />; } ``` ## Functions {/* #functions */} ### `interpolate` {/* #interpolate-1 */} The imperative counterpart of the [`<Interpolate>`](#interpolate) component. #### Signature {/* #signature */} ```ts // Simple string interpolation function interpolate(text: string, values: Record<string, string>): string; // JSX interpolation function interpolate( text: string, values: Record<string, ReactNode>, ): 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>`](#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, string>, ): 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 ( <Layout // highlight-next-line title={translate({message: 'My page meta title'})}> <img src={'https://docusaurus.io/logo.png'} aria-label={ // highlight-start translate( { message: 'The logo of site {siteName}', // Optional id: 'homepage.logo.ariaLabel', description: 'The home page logo aria label', }, {siteName: 'Docusaurus'}, ) // highlight-end } /> </Layout> ); } ``` ## 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>`](#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` |