<!--
  canonical-url: https://www.avonture.be/fr/blog/docusaurus-go-top
  published:     2025-09-12
  This is a static plain-Markdown mirror generated at build time.
  Visit the canonical URL above for the fully rendered page, with images and interactive components.
-->

# Ajouter un bouton « retour en haut » dans les articles Docusaurus

> Découvrez comment ajouter facilement un bouton « retour en haut », souvent accompagné d'une icône animée amusante, à vos articles de blog Docusaurus grâce à un composant React personnalisé et une surcharge de thème.

---
![Ajouter un bouton « retour en haut » dans les articles Docusaurus](/img/v2/go_top_banner.webp)

**TL;DR**

Cet article est un tutoriel rapide pour ajouter un bouton « retour en haut » à votre blog Docusaurus. Il vous guide dans l'implémentation d'un composant React personnalisé `<ScrollToTopButton>`, avec son CSS pour la mise en forme. Vous apprendrez à surcharger le composant de thème `BlogPostItem` par défaut afin d'injecter automatiquement le bouton au bas de chaque article. Le guide donne aussi des astuces pour ajouter le bouton à d'autres parties de votre site, comme l'archive du blog ou vos pages personnalisées.

Sur smartphone plus encore que sur ordinateur, c'est bien pratique d'avoir un bouton *Retour en haut de page* pour éviter de se luxer le pouce.

![Docux](/img/docux.webp) [Docux](https://github.com/Juniors017), un ami, a récemment développé cette fonctionnalité et j'ai été ravi de l'ajouter, d'autant qu'elle est terriblement simple à utiliser et apporte un côté fun ; c'est sympa.

Faites simplement défiler n'importe quelle page de ce blog pour voir un petit suricate apparaître en bas à droite. Cliquez dessus et prenez l'ascenseur jusqu'en haut de la page.

## À quoi ça ressemble {#what-it-looks-like}

Voici cette page même, après défilement. Le suricate se tient en bas à droite, flottant au-dessus de votre contenu :

> Screenshot — https\://www\.avonture.be/blog/docusaurus-go-top
>
> ![Le bouton retour en haut avec le suricate, en bas à droite, sur un article défilé](./images/go_top_button.webp)

De plus près, c'est un bouton rond qui contient l'icône que vous lui donnez :

![Gros plan du bouton rond de retour en haut affichant l'icône du suricate](./images/go_top_button_zoom.webp)

Le bouton reste masqué tant que vous n'avez pas défilé de plus de 300 pixels ; une page courte ne l'affiche donc jamais. Deux fichiers et une surcharge, c'est ci-dessous.

## Comment ça fonctionne {#how-it-works}

Docux a créé un [composant Docusaurus ScrollToTopButton](https://github.com/Juniors017/docux-blog/tree/main/src/components/ScrollToTopButton), c'est-à-dire un bout de Javascript avec du css ; rien de plus.

Créez les deux fichiers ci-dessous dans l'arborescence de votre blog :

**src/components/ScrollToTopButton/index.tsx**

```typescript
import { useState, useEffect, type JSX } from "react";
import clsx from "clsx";
import { translate } from "@docusaurus/Translate";
import styles from "./styles.module.css";
import buttontop from "@site/static/img/meerkat/suricate_no_background.webp";

export default function ScrollToTopButton(): JSX.Element {
  const [isVisible, setIsVisible] = useState(false);
  const [fly, setFly] = useState(false);

  useEffect(() => {
    const toggleVisibility = () => setIsVisible(window.scrollY > 300);
    window.addEventListener("scroll", toggleVisibility, { passive: true });
    return () => window.removeEventListener("scroll", toggleVisibility);
  }, []);

  const scrollToTop = () => {
    setFly(true);
    window.scrollTo({ top: 0, behavior: "smooth" });

    setTimeout(() => setFly(false), 800);
  };

  return (
    <button
      type="button"
      className={clsx(styles.scrollBtn, isVisible && styles.show, fly && styles.fly)}
      onClick={scrollToTop}
      aria-label={translate({
        id: "theme.common.scrollToTop",
        message: "Scroll to top",
        description: "The aria label for the scroll to top button",
      })}
    >
      <img
        src={buttontop}
        alt={translate({
          id: "theme.common.scrollToTop",
          message: "Scroll to top",
        })}
        className="no-zoom"
        width="30"
        height="30"
      />
    </button>
  );
}
```

**src/components/ScrollToTopButton/styles.module.css**

```css
.scrollBtn {
  position: fixed;
  bottom: 30px;
  right: 30px;
  width: 60px;
  height: 60px;
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.4s,
    visibility 0.4s;
  z-index: 1000;
  border: none;
  background: transparent;
  padding: 0;
}

.scrollBtn img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: 50%;
  box-shadow: var(--mk-shadow-3);
  transition: transform 0.3s;
}

.scrollBtn:hover img {
  transform: scale(1.1);
}

/* Bouton visible après scroll */
.scrollBtn.show {
  opacity: 1;
  visibility: visible;
}

/* Animation "vol vers le haut" */
.scrollBtn.fly img {
  animation: flyUp 0.8s ease-in forwards;
}

@keyframes flyUp {
  0% {
    transform: translateY(0) scale(1);
    opacity: 1;
  }
  100% {
    transform: translateY(-300px) scale(0.6);
    opacity: 0;
  }
}

/* The meerkat flying off the top of the page is the site's signature gesture,
   so it is kept — but it is pure decoration, and a reader who asked for less
   motion should get the plain jump. */
@media (prefers-reduced-motion: reduce) {
  .scrollBtn.fly img {
    animation: none;
  }

  .scrollBtn:hover img,
  .scrollBtn img {
    transition: none;
    transform: none;
  }
}

@media (max-width: 600px) {
  .scrollBtn {
    width: 44px;
    height: 44px;
    bottom: 16px;
    right: 16px;
  }
}
```

Ensuite, vous devez injecter `<ScrollToTopButton />` dans vos pages. *Cette injection se fait en swizzlant `BlogPostItem`, exactement comme dans [Displaying related posts below our Docusaurus article](/blog/docusaurus-relatedposts) et [Adding Reader Reactions to Your Docusaurus Blog](/blog/docusaurus-reactions) ; si vous avez déjà fait l'un des deux, vous avez déjà le fichier.*

> **Information:**
>
> Le composant importe son icône dès les premières lignes : `import buttontop from "@site/static/img/meerkat/suricate_no_background.webp"`. Faites pointer cet import vers votre propre image carrée dans `/static` et c'est réglé.

## Surcharger la page BlogPostItem {#overriding-the-blogpostitem-page}

Suivez le chapitre « [Nous devons surcharger la façon dont Docusaurus rend l'article](/blog/docusaurus-bluesky-share/#we-need-to-override-how-the-article-is-rendered-by-docusaurus) » d'un article précédent.

Vous devez créer le fichier `src/theme/BlogPostItem/index.js`.

Si vous ne voulez pas les détails, ne lisez pas ce chapitre et créez simplement ce fichier :

**src/theme/BlogPostItem/index.js**

```javascript
import React from 'react';
import clsx from 'clsx';
import {useBlogPost} from '@docusaurus/plugin-content-blog/client';
import BlogPostItemContainer from '@theme/BlogPostItem/Container';
import BlogPostItemHeader from '@theme/BlogPostItem/Header';
import BlogPostItemContent from '@theme/BlogPostItem/Content';
import BlogPostItemFooter from '@theme/BlogPostItem/Footer';
// apply a bottom margin in list view
function useContainerClassName() {
  const {isBlogPostPage} = useBlogPost();
  return !isBlogPostPage ? 'margin-bottom--xl' : undefined;
}
export default function BlogPostItem({children, className}) {
  const containerClassName = useContainerClassName();
  return (
    <BlogPostItemContainer className={clsx(containerClassName, className)}>
      <BlogPostItemHeader />
      <BlogPostItemContent>{children}</BlogPostItemContent>
      <BlogPostItemFooter />
    </BlogPostItemContainer>
  );
}
```

Une fois que vous l'avez, éditez-le car nous devons y injecter le code `<ScrollToTopButton />`.

Ci-dessous, voyez les deux lignes surlignées à ajouter :

**src/theme/BlogPostItem/index.js**

```javascript
import React from 'react';
import clsx from 'clsx';
import {useBlogPost} from '@docusaurus/plugin-content-blog/client';
import BlogPostItemContainer from '@theme/BlogPostItem/Container';
import BlogPostItemHeader from '@theme/BlogPostItem/Header';
import BlogPostItemContent from '@theme/BlogPostItem/Content';
import BlogPostItemFooter from '@theme/BlogPostItem/Footer';
// highlight-next-line
import ScrollToTopButton from "@site/src/components/ScrollToTopButton";

// apply a bottom margin in list view
function useContainerClassName() {
  const {isBlogPostPage} = useBlogPost();
  return !isBlogPostPage ? 'margin-bottom--xl' : undefined;
}
export default function BlogPostItem({children, className}) {
  const containerClassName = useContainerClassName();
  return (
    <BlogPostItemContainer className={clsx(containerClassName, className)}>
      <BlogPostItemHeader />
      <BlogPostItemContent>{children}</BlogPostItemContent>
      <BlogPostItemFooter />
      // highlight-next-line
      <ScrollToTopButton />
    </BlogPostItemContainer>
  );
}
```

> **Nous devons redémarrer Docusaurus:**
>
> Comme nous venons d'introduire une surcharge, nous devons redémarrer notre serveur Docusaurus pour que les changements soient pris en compte.

> **Lancez npm run start:**
>
> Si vous lancez Docusaurus en local, exécutez simplement `npm run start` dans votre console.
> Si, comme moi, vous lancez Docusaurus via Docker, tuez le container et démarrez-en un nouveau.

## Vous pouvez bien sûr le faire pour d'autres pages {#you-can-do-this-for-other-pages-for-sure}

Sur mon site, j'ai une page `archive`. Vous voulez y utiliser le bouton `<ScrollToTopButton />` aussi ? Swizzlez simplement la page en exécutant `yarn docusaurus swizzle @docusaurus/theme-classic BlogArchivePage` dans une console, puis mettez à jour le fichier `index.js` comme illustré ci-dessus.

Si vous avez d'autres pages dans votre dossier `src/pages/` (comme `about.mdx`, `index.mdx`, ...), pas besoin de swizzler d'abord : ajoutez directement les deux lignes dans ces fichiers aussi.

## Conclusion {#conclusion}

Fini les pouces luxés : un petit composant, un `BlogPostItem` swizzlé, et chaque article long de votre site obtient un chemin de retour vers le haut. Le plus amusant, c'est que l'icône est la vôtre ; la mienne fait signe aux lecteurs qui descendent trop loin.

Si vous constituez votre collection de composants Docusaurus, le prochain à ajouter est [les articles liés sous chaque article](/blog/docusaurus-relatedposts), qui réutilise exactement le même fichier de surcharge.
