Modifier la façon dont Docusaurus génère les balises img
Personnalisez la manière dont Docusaurus génère les balises <img> pour mieux contrôler le rendu et le comportement des images.
Traduction automatique
Cet article a plus d'un an, mais il a été relu le 30 juillet 2026 — son contenu est toujours exact.
Cet article fait partie de la série Créer des composants Docusaurus :
- Modifier la façon dont Docusaurus génère les balises img
- Surcharger la génération des balises img avec Docusaurus
- Organisez votre contenu Docusaurus avec un composant Series personnalisé
- Ajouter un bouton « retour en haut » dans les articles Docusaurus
- Créer un plugin de recherche/remplacement pour Docusaurus
- Un composant pour afficher des snippets de code dans un blog Docusaurus
- Un composant Docusaurus qui prévient le lecteur que l'article a plus d'un an
- Afficher le changelog de votre article
- Injecter de l'ASCII art dans toutes les pages HTML générées par Docusaurus
- Best Practice - Personnaliser le flux RSS de Docusaurus pour un contenu complet et des images
- Quelques vérifications sur les images de votre site Docusaurus
- Gestion des tags dans Docusaurus
- Automatiser les résumés TL;DR avec Gemini AI
- Le composant ProjectSetup - Une façon standardisée de partager des structures de projet
- Comment signaler un contenu assisté par IA dans un blog Docusaurus
- Donnez vie à vos tutoriels CLI avec un terminal machine à écrire
- Espiègleries de suricate : semer des easter eggs partout sur mon blog
- Tooltips de code assistés par l'IA dans Docusaurus — Explique-moi comme à un enfant de cinq ans
- Ajouter des réactions de lecteurs à votre blog Docusaurus
- Votre blog est illisible pour une IA. Voici la solution.
- Secouez votre téléphone, surprenez le suricate
- Ajouter un bouton « Copy as Markdown » à votre blog Docusaurus
- Ask My Blog : transformer 259 articles en 2 160 questions cherchables
- La troisième porte : une bulle de chat flottante, et la fonctionnalité que personne ne trouvait
- Dessiner une carte de mon propre blog
- Laissez vos lecteurs signaler les problèmes — un widget de feedback multi-types pour Docusaurus

Cet article explique comment personnaliser le rendu des images dans Docusaurus en créant un composant React <Image> sur mesure. Vous allez apprendre à construire le composant, à le styler en CSS, puis à utiliser un plugin Remark personnalisé pour remplacer automatiquement les images Markdown standard par votre nouveau composant. Le guide couvre aussi la configuration du plugin pour ignorer la première image d'un article et son enregistrement dans la configuration de Docusaurus, ce qui vous donne un contrôle total sur l'affichage de vos images.
Je démarre une série sur l'écriture de composants pour Docusaurus.
Comme c'est toujours plus sympa de commencer par quelque chose de très concret et pratique, voici ce que nous allons faire : nous allons intercepter la conversion de  vers une balise HTML <img>. Nous allons forcer Docusaurus à utiliser à la place notre propre composant <Image>.
Nous allons personnaliser notre balise <Image> pour d'abord injecter un <div> parent, puis forcer notre <img> avec des attributs comme le CSS, le lazy loading, ... mais pas pour toutes les balises de l'article, puisque nous allons ignorer la première.
En effet, l'image d'introduction de l'article doit rester inchangée ; nous commencerons à modifier les autres images.
Et voici le résultat de notre composant <Image> fait main :

Comme vous le voyez, l'image est centrée, elle a un effet au survol, des coins arrondis, ... Si vous regardez le code HTML, vous verrez l'attribut loading="lazy".
C'est plutôt chouette : notre composant fonctionne ! Construisons-le.
Il y a plusieurs choses à faire, alors commençons par la première : créer notre composant <Image>.
1. Création de notre composant Image
Écrire un composant pour Docusaurus est assez simple. Il faut créer un nouveau dossier dans le dossier existant src/components.
Dans cet article, nous allons créer un composant Image ; créons donc le fichier src/components/Image/index.tsx avec ce contenu :
/** * 🖼️ Image Component * * A lightweight wrapper for rendering images in Docusaurus with base URL resolution. * Ensures that image paths are correctly resolved relative to the site's base URL, * making it ideal for static assets stored in the `static/img` directory. * * 🔍 Behavior: * - Uses `useBaseUrl()` to resolve the image path * - Applies scoped styling via CSS modules * - Supports optional `alt` and `title` attributes for accessibility and tooltips * - Enables lazy loading for performance optimization */
import type { JSX } from "react";import styles from "./styles.module.css";import useBaseUrl from "@docusaurus/useBaseUrl";
interface Props { /** Path to the image (e.g. `/img/example.png`), or a `require()`d asset */ src: string | { default: string }; /** Tooltip text shown on hover */ title?: string; /** Alternative text for accessibility (if missing, reuse the Title property) */ alt?: string;}
export default function Image({ src, alt, title }: Props): JSX.Element { const isAbsolutePath = typeof src === "string" && src.startsWith("/"); const resolvedUrl = useBaseUrl(isAbsolutePath ? src : undefined); const imgSrc = (isAbsolutePath ? resolvedUrl : src) as string;
return ( <div className={styles.container}> <img src={imgSrc} alt={alt || title} title={title} loading="lazy" /> </div> );}Ce composant React enveloppe le rendu d'images dans Docusaurus en résolvant correctement leurs chemins relatifs à l'URL de base du site. Il utilise useBaseUrl() pour les chemins absolus, applique du style via CSS modules, supporte des attributs alt et title pour l'accessibilité, et active le chargement différé pour optimiser les performances.
Notre composant Image attend trois paramètres, mais seul img est obligatoire. On peut aussi passer un titre (title) et le texte alternatif (alt).
Comme vous le comprenez facilement, le composant <Image> va simplement créer un div contenant une balise img.
Rien d'extraordinaire, sauf que nous utiliserons un peu de CSS pour le look & feel et que nous forcerons le lazy loading.
Créez également le fichier src/components/Image/styles.module.css :
.container { text-align: center; padding: 10px; background: rgb(255, 255, 255, 0.15); border: 1px solid rgb(255, 255, 255, 0.3); border-radius: 16px; backdrop-filter: blur(10px) saturate(180%);}
.container img { border-radius: 12px; box-shadow: 0 8px 20px rgb(0, 0, 0, 0.15); transition: transform 0.4s ease, box-shadow 0.4s ease, filter 0.4s ease;}
.container img:hover { transform: scale(1.05) translateY(-4px); box-shadow: 0 12px 25px rgb(0, 0, 0, 0.25); filter: brightness(1.05) saturate(1.1);}Ce fichier CSS définit un conteneur avec un effet de verre dépoli (frosted glass) et ajoute des animations d'interaction sur les images à l'intérieur. Quand on survole une image, elle s'agrandit légèrement, remonte, et devient plus lumineuse, avec des transitions fluides entre ces états.
2. Informer Docusaurus de l'existence de notre composant
Avant de pouvoir utiliser le composant <Image>, il faut dire à Docusaurus quoi faire quand il le rencontrera.
Éditez le fichier src/theme/MDXComponents.js (et s'il n'existe pas, créez-le)
import MDXComponents from "@theme-original/MDXComponents";import Image from "@site/src/components/Image";
export default { // Reusing the default mapping ...MDXComponents, Image,};Ce fichier exporte un objet de composants MDX personnalisés en réutilisant tous les composants par défaut et en remplaçant le composant Image par une version personnalisée du projet. C'est un mécanisme courant pour étendre ou modifier le comportement des composants MDX sans tout réécrire.
Tout est maintenant en place.
3. Utiliser le composant Image
Dès maintenant, dans un article de blog, au lieu d'écrire

nous pouvons écrire
<Image src={require("./images/happy.webp").default} title="A happy meerkat" />
La partie require est nécessaire parce que l'image se trouve dans un sous-dossier de l'article. C'est exactement la balise rendue en haut de cet article.
Si la source était quelque chose comme /img/happy.jpg, le code est plus simple :
<Image src="/img/happy.jpg" title="A happy meerkat" />
Attention
Mais, oh oh, sur ce blog, j'ai plus de 250 articles à l'heure actuelle (août 2025) ; je ne vais quand même pas parcourir tous mes articles pour remplacer mes images, si ?
Et puis, peut-être que demain je ne voudrai plus de cette balise ; je veux donc garder mes articles en Markdown vanilla (le langage standard). Comment faire ? La réponse : écrire un plugin (j'ai utilisé exactement la même astuce pour mon plugin de recherche & remplacement).
Le plugin va pouvoir intercepter le code Markdown de l'article et le manipuler. C'est exactement ce que nous voulons ici !
Nous allons intercepter la conversion des images de Markdown vers HTML et dire à Docusaurus d'utiliser notre balise Image au lieu de img.
4. Écrire et enregistrer un plugin (optionnel — seulement si vous avez des centaines d'articles comme moi)
Si vous n'avez qu'une poignée d'articles, il est plus simple de les éditer à la main et de sauter cette section. Nous avons donc besoin d'un plugin pour intercepter la conversion de  vers une balise image HTML ; automatiquement.
Attention
Ajoutons une complexité : nous ne voulons pas modifier la première image, c'est-à-dire l'image d'introduction de l'article. Pour cette première image, laissons Docusaurus faire son travail (il le fait très bien). Nous intercepterons à partir de la deuxième image de l'article.
Créez le fichier plugins/remark-image-transformer/index.cjs :
/** * @fileoverview * A Remark plugin for transforming Markdown image nodes (``) into MDX-compatible `<Image />` components. * This plugin is tailored for Docusaurus environments, where image paths often need to be resolved using `require()` or `useBaseUrl()`. * It supports: * - Relative paths (e.g. `./image.png`) → converted to `require()` expressions * - Absolute paths (e.g. `/img/banner.png`) → passed directly, as Docusaurus resolves them * - External URLs → passed directly as string literals * Additionally, it preserves `alt` and `title` attributes. * * @module remarkReplaceImgToImage */
// cspell:ignore mdxjs
const { visit } = require("unist-util-visit");const acorn = require("acorn");
/** * Parses a JavaScript expression string into an ESTree-compatible expression node. * * @param {string} expression - A valid JavaScript expression as a string. * @returns {object} ESTree expression node representing the parsed expression. */function expressionToEstree(expression) { return acorn.parse(expression, { ecmaVersion: 2020, sourceType: "module", }).body[0].expression;}
/** * Creates an MDX JSX attribute node with an embedded JavaScript expression. * * @param {string} name - The name of the JSX attribute (e.g. "src"). * @param {string} expr - A JavaScript expression string to embed in the attribute. * @returns {object} MDX AST node representing the JSX attribute with expression value. */function makeJsxAttributeExpression(name, expr) { return { type: "mdxJsxAttribute", name, value: { type: "mdxJsxAttributeValueExpression", value: expr, data: { estree: { type: "Program", body: [ { type: "ExpressionStatement", expression: expressionToEstree(expr), }, ], sourceType: "module", }, }, }, };}
/** * Remark plugin that replaces Markdown image nodes with MDX `<Image />` components. * * @param {object} [options={}] - Plugin configuration options. * @param {boolean} [options.skipFirst=true] - Whether to skip transforming the first image node. * @returns {function} Transformer function to be used by Remark. */function remarkReplaceImgToImage({ skipFirst = true } = {}) { return (tree) => { let imageCount = 0;
visit(tree, "image", (node, index, parent) => { imageCount++; if (skipFirst && imageCount === 1) return;
const url = node.url || ""; const attributes = [ { type: "mdxJsxAttribute", name: "alt", value: node.alt || "" }, ]; if (node.title) attributes.push({ type: "mdxJsxAttribute", name: "title", value: node.title, });
if (/^\.+\//.test(url)) { // Relative to MD file -> use require() const expr = `require("${url}").default`; attributes.unshift(makeJsxAttributeExpression("src", expr)); } else if (/^\//.test(url)) { // Absolute -> just pass the path, Docusaurus will handle it. attributes.unshift({ type: "mdxJsxAttribute", name: "src", value: url, }); } else { // Fallback: external URL attributes.unshift({ type: "mdxJsxAttribute", name: "src", value: url, }); }
const imageNode = { type: "mdxJsxFlowElement", name: "Image", attributes, children: [], };
parent.children.splice(index, 1, imageNode); });
// The useBaseUrl import is no longer needed. };}
module.exports = remarkReplaceImgToImage;Ce plugin Remark transforme les images Markdown en composants MDX `<Image />` adaptés à Docusaurus. Il détecte les chemins relatifs, absolus et externes, puis construit des nœuds JSX avec les attributs appropriés — les chemins relatifs utilisent `require()`, tandis que les chemins absolus et URLs externes sont passés directement.
Ce plugin est plus complexe parce qu'il faut s'assurer que les chemins vers les images sont correctement gérés (on utilise des chemins relatifs comme , ou absolus (), ou même externes).
Une fois le plugin créé, il faut mettre à jour la configuration de Docusaurus pour le charger.
Pour cela, éditez votre fichier docusaurus.config.js et ajoutez les lignes mises en évidence comme illustré ci-dessous.
const config = { // [ ... ] presets: [ [ 'classic', ({ blog: { // highlight-next-line beforeDefaultRemarkPlugins: [require('./plugins/remark-image-transformer')], }, // [ ... ] }), ], ],};
export default config;Ce fichier exporte une configuration Docusaurus qui personnalise le préset 'classic' en injectant un plugin remark personnalisé pour transformer les images dans le blog avant que les plugins par défaut ne s'exécutent.
Redémarrez maintenant votre serveur Docusaurus (pour que le plugin soit enregistré).
Si tout est correctement en place, ouvrez n'importe lequel de vos anciens articles et vous verrez que ça fonctionne.
Conclusion
À vous maintenant d'éditer le fichier src/components/Image/styles.module.css et d'utiliser votre propre CSS.
Et une fois que chaque image passe par votre propre composant, il devient facile de les auditer : voyez Quelques vérifications sur les images de votre site Docusaurus.
Cet article fait partie de la série Créer des composants Docusaurus :
- Modifier la façon dont Docusaurus génère les balises img
- Surcharger la génération des balises img avec Docusaurus
- Organisez votre contenu Docusaurus avec un composant Series personnalisé
- Ajouter un bouton « retour en haut » dans les articles Docusaurus
- Créer un plugin de recherche/remplacement pour Docusaurus
- Un composant pour afficher des snippets de code dans un blog Docusaurus
- Un composant Docusaurus qui prévient le lecteur que l'article a plus d'un an
- Afficher le changelog de votre article
- Injecter de l'ASCII art dans toutes les pages HTML générées par Docusaurus
- Best Practice - Personnaliser le flux RSS de Docusaurus pour un contenu complet et des images
- Quelques vérifications sur les images de votre site Docusaurus
- Gestion des tags dans Docusaurus
- Automatiser les résumés TL;DR avec Gemini AI
- Le composant ProjectSetup - Une façon standardisée de partager des structures de projet
- Comment signaler un contenu assisté par IA dans un blog Docusaurus
- Donnez vie à vos tutoriels CLI avec un terminal machine à écrire
- Espiègleries de suricate : semer des easter eggs partout sur mon blog
- Tooltips de code assistés par l'IA dans Docusaurus — Explique-moi comme à un enfant de cinq ans
- Ajouter des réactions de lecteurs à votre blog Docusaurus
- Votre blog est illisible pour une IA. Voici la solution.
- Secouez votre téléphone, surprenez le suricate
- Ajouter un bouton « Copy as Markdown » à votre blog Docusaurus
- Ask My Blog : transformer 259 articles en 2 160 questions cherchables
- La troisième porte : une bulle de chat flottante, et la fonctionnalité que personne ne trouvait
- Dessiner une carte de mon propre blog
- Laissez vos lecteurs signaler les problèmes — un widget de feedback multi-types pour Docusaurus
Chargement des commentaires…





