Aller au contenu principal
Version : 2.4.3

Swizzling

Cette section détaille comment personnaliser une mise en page dans Docusaurus.

Un petit goût de déjà vu ?... 

This section is similar to Styling and Layout, but this time, we will write actual React code instead of playing with stylesheets. We will talk about a central concept in Docusaurus: swizzling, which allows deeper site customizations.

In practice, swizzling permits to swap a theme component with your own implementation, and it comes in 2 patterns:

  • Ejecting: creates a copy of the original theme component, which you can fully customize
  • Wrapping: creates a wrapper around the original theme component, which you can enhance
Why is it called swizzling?

The name comes from Objective-C and Swift-UI: method swizzling is the process of changing the implementation of an existing selector (method).

For Docusaurus, component swizzling means providing an alternative component that takes precedence over the component provided by the theme.

You can think of it as Monkey Patching for React components, enabling you to override the default implementation. Gatsby has a similar concept called theme shadowing.

To gain a deeper understanding of this, you have to understand how theme components are resolved.

Processus du swizzling

Vue d'ensemble

Docusaurus provides an convenient interactive CLI to swizzle components. En général, vous avez seulement besoin de retenir la commande suivante :

npm run swizzle

It will generate a new component in your src/theme directory, which should look like this example:

src/theme/SomeComponent.js
import React from 'react';

export default function SomeComponent(props) {
// You can fully customize this implementation
// including changing the JSX, CSS and React hooks
return (
<div className="some-class">
<h1>Some Component</h1>
<p>Some component implementation details</p>
</div>
);
}

Pour obtenir un aperçu de tous les thèmes et composants disponibles à swizzler, exécutez :

npm run swizzle -- --list

Use --help to see all available CLI options, or refer to the reference swizzle CLI documentation.

remarque

After swizzling a component, restart your dev server in order for Docusaurus to know about the new component.

Prefer staying on the safe side

Be sure to understand which components are safe to swizzle. Some components are internal implementation details of a theme.

info

docusaurus swizzle is only an automated way to help you swizzle the component. You can also create the src/theme/SomeComponent.js file manually, and Docusaurus will resolve it. Il n'y a pas de magie interne derrière cette commande !

Ejecting

Ejecting a theme component is the process of creating a copy of the original theme component, which you can fully customize and override.

To eject a theme component, use the swizzle CLI interactively, or with the --eject option:

npm run swizzle [nom du thème] [nom du composant] -- --eject

Exemple :

npm run swizzle @docusaurus/theme-classic Footer -- --eject

This will copy the current <Footer /> component's implementation to your site's src/theme directory. Docusaurus will now use this <Footer> component copy instead of the original one. You are now free to completely re-implement the <Footer> component.

src/theme/Footer/index.js
import React from 'react';

export default function Footer(props) {
return (
<footer>
<h1>This is my custom site footer</h1>
<p>And it is very different from the original</p>
</footer>
);
}
attention

Ejecting an unsafe component can sometimes lead to copying a large amount of internal code, which you now have to maintain yourself. Cela peut rendre les mises à jour de Docusaurus plus difficiles, car vous devrez migrer vos personnalisations si les propriétés reçues ou les API de thème internes utilisées ont changé.

Prefer wrapping whenever possible: the amount of code to maintain is smaller.

Re-swizzling

To keep ejected components up-to-date after a Docusaurus upgrade, re-run the eject command and compare the changes with git diff. Il est également recommandé d'écrire un bref commentaire en haut du fichier expliquant les modifications que vous avez apportées, afin de pouvoir plus facilement réappliquer vos modifications après la ré-éjection.

Wrapping

Wrapping a theme component is the process of creating a wrapper around the original theme component, which you can enhance.

To wrap a theme component, use the swizzle CLI interactively, or with the --wrap option:

npm run swizzle [theme name] [component name] -- --wrap

Exemple :

npm run swizzle @docusaurus/theme-classic Footer -- --wrap

This will create a wrapper in your site's src/theme directory. Docusaurus will now use the <FooterWrapper> component instead of the original one. Vous pouvez alors ajouter des personnalisations autour du composant original.

src/theme/Footer/index.js
import React from 'react';
import Footer from '@theme-original/Footer';

export default function FooterWrapper(props) {
return (
<>
<section>
<h2>Extra section</h2>
<p>This is an extra section that appears above the original footer</p>
</section>
<Footer {...props} />
</>
);
}
What is this @theme-original thing?

Docusaurus uses theme aliases to resolve the theme components to use. The newly created wrapper takes the @theme/SomeComponent alias. @theme-original/SomeComponent permits to import original component that the wrapper shadows without creating an infinite import loop where the wrapper imports itself.

astuce

Wrapping a theme is a great way to add extra components around existing one without ejecting it. Par exemple, vous pouvez facilement ajouter un système de commentaires personnalisés sous chaque article de blog :

src/theme/BlogPostItem.js
import React from 'react';
import BlogPostItem from '@theme-original/BlogPostItem';
import MyCustomCommentSystem from '@site/src/MyCustomCommentSystem';

export default function BlogPostItemWrapper(props) {
return (
<>
<BlogPostItem {...props} />
<MyCustomCommentSystem />
</>
);
}

Qu'est-ce qui est sans danger pour swizzler ?

Un grand pouvoir implique de grandes responsabilités.

Some theme components are internal implementation details of a theme. Docusaurus allows you to swizzle them, but it might be risky.

Why is it risky?

Les auteurs de thèmes (dont nous faisons partie) peuvent être amenés à mettre à jour leur thème au fil du temps : changement des composants, de leur nom, de l'emplacement du système de fichiers, des types... For example, consider a component that receives two props name and age, but after a refactor, it now receives a person prop with the above two properties. Your component, which still expects these two props, will render undefined instead.

Par ailleurs, les composants internes peuvent tout simplement disparaître. If a component is called Sidebar and it's later renamed to DocSidebar, your swizzled component will be completely ignored.

Theme components marked as unsafe may change in a backward-incompatible way between theme minor versions. When upgrading a theme (or Docusaurus), your customizations might behave unexpectedly, and can even break your site.

For each theme component, the swizzle CLI will indicate 3 different levels of safety declared by theme authors:

  • Safe: this component is safe to be swizzled, its public API is considered stable, and no breaking changes should happen within a theme major version
  • Unsafe: this component is a theme implementation detail, not safe to be swizzled, and breaking changes might happen within a theme minor version
  • Forbidden: the swizzle CLI will prevent you from swizzling this component, because it is not designed to be swizzled at all
remarque

Certains composants peuvent être sûrs pour l'enveloppement, mais pas pour l'éjection.

info

Don't be too afraid to swizzle unsafe components: just keep in mind that breaking changes might happen, and you might need to upgrade your customizations manually on minor version upgrades.

Report your use-case

If you have a strong use-case for swizzling an unsafe component, please report it here and we will work together to find a solution to make it safe.

Quel composant devrais-je swizzler ?

Il n'est pas toujours facile d'identifier le composant à swizzler pour atteindre le résultat souhaité. @docusaurus/theme-classic, which provides most of the theme components, has about 100 components!

astuce

To print an overview of all the @docusaurus/theme-classic components:

npm run swizzle @docusaurus/theme-classic -- --list

Pour localiser le bon composant à swizzler, suivez ces étapes :

  1. Component description. Some components provide a short description, which is a good way to find the right one.
  2. Component name. Official theme components are semantically named, so you should be able to infer its function from the name. La commande Swizzle du CLI vous permet de saisir une partie du nom d'un composant pour restreindre les choix disponibles. For example, if you run yarn swizzle @docusaurus/theme-classic, and enter Doc, only the docs-related components will be listed.
  3. Start with a higher-level component. Components form a tree with some components importing others. Every route will be associated with one top-level component that the route will render (most of them listed in Routing in content plugins). For example, all blog post pages have @theme/BlogPostPage as the topmost component. Vous pouvez commencer par swizzler ce composant, puis descendre dans l'arborescence des composants pour trouver le composant qui rend exactement ce que vous ciblez. N'oubliez pas de déswizzler le reste en supprimant les fichiers après avoir trouvé le bon, afin de ne pas conserver trop de composants.
  4. Read the theme source code and use search wisely.
Just ask!

If you still have no idea which component to swizzle to achieve the desired effect, you can reach out for help in one of our support channels.

We also want to understand better your fanciest customization use-cases, so please report them.

Ai-je besoin de swizzler ?

Le swizzling signifie en fin de compte que vous devez maintenir du code React supplémentaire qui interagit avec les API internes de Docusaurus. Si vous le pouvez, pensez aux alternatives suivantes lors de la personnalisation de votre site :

  1. Use CSS. CSS rules and selectors can often help you achieve a decent degree of customization. Refer to styling and layout for more details.
  2. Use translations. It may sound surprising, but translations are ultimately just a way to customize the text labels. For example, if your site's default language is en, you can still run yarn write-translations -l en and edit the code.json emitted. Refer to the i18n tutorial for more details.
astuce

The smaller, the better. If swizzling is inevitable, prefer to swizzle only the relevant part and maintain as little code on your own as possible. Swizzling a small component often means less risk of breaking changes during upgrade.

Wrapping is also a far safer alternative to ejecting.

Wrapping your site with <Root>

The <Root> component is rendered at the very top of the React tree, above the theme <Layout>, and never unmounts. C'est l'endroit idéal pour ajouter une logique d'état qui ne doit pas être réinitialisée au fil des navigations (statut d'authentification de l'utilisateur, état du panier d'achat...).

Swizzle it manually by creating a file at src/theme/Root.js:

src/theme/Root.js
import React from 'react';

// Default implementation, that you can customize
export default function Root({children}) {
return <>{children}</>;
}
astuce

Utilisez ce composant pour afficher les fournisseurs de contexte de React.