From d2d5704bf76823cc692bd2d76f4c287bc77adc71 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Sat, 26 Feb 2022 18:10:44 +0800 Subject: [PATCH] docs: add basic documentation about client modules --- website/docs/advanced/client.md | 40 +++++++++++++++++++ website/docs/api/docusaurus.config.js.md | 4 +- .../docs/api/plugin-methods/lifecycle-apis.md | 2 +- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/website/docs/advanced/client.md b/website/docs/advanced/client.md index 4148f270318d..be140eac465d 100644 --- a/website/docs/advanced/client.md +++ b/website/docs/advanced/client.md @@ -75,3 +75,43 @@ The components in this "stack" are pushed in the order of `preset plugins > pres `@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="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.md#getClientModules) and [`siteConfig.clientModules`](../api/docusaurus.config.js.md#clientModules), respectively. + +Client modules are called during server-side rendering as well, so remember to check the [execution environment](./ssg.md#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.md#global-styles). + +```css title="mySiteGlobalCss.css" +/* This stylesheet is global. */ +.globalSelector { + color: red; +} +``` + + + diff --git a/website/docs/api/docusaurus.config.js.md b/website/docs/api/docusaurus.config.js.md index ab50dc53956c..301c5a5a3eef 100644 --- a/website/docs/api/docusaurus.config.js.md +++ b/website/docs/api/docusaurus.config.js.md @@ -450,7 +450,7 @@ module.exports = { ### `clientModules` {#clientmodules} -An array of client modules to load globally on your site: +An array of [client modules](../advanced/client.md#client-modules) to load globally on your site: Example: @@ -463,8 +463,6 @@ module.exports = { }; ``` -See also: [`getClientModules()`](./plugin-methods/lifecycle-apis.md#getClientModules). - ### `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`. diff --git a/website/docs/api/plugin-methods/lifecycle-apis.md b/website/docs/api/plugin-methods/lifecycle-apis.md index b25455eed31f..e8638d6bb956 100644 --- a/website/docs/api/plugin-methods/lifecycle-apis.md +++ b/website/docs/api/plugin-methods/lifecycle-apis.md @@ -378,7 +378,7 @@ module.exports = function (context, options) { ## `getClientModules()` {#getClientModules} -Returns an array of paths to the modules that are to be imported into the client bundle. These modules are imported globally before React even renders the initial UI. +Returns an array of paths to the [client modules](../../advanced/client.md#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: