Aller au contenu

Tutoriel - Élargir avec les transitions de vue

Les transitions de vue (View Transitions) sont un moyen de contrôler ce qui se passe lorsque les visiteurs naviguent au milieu des pages de votre site. L’API View Transitions d’Astro vous permet d’ajouter des fonctions de navigation optionnelles, notamment des transitions et des animations fluides, le contrôle de la pile d’historique des pages visitées du navigateur et la prévention des rafraîchissements complets de la page afin de conserver certains éléments et états de la page tout en mettant à jour le contenu affiché.

Préparez-vous à…

  • Importer et ajouter le routeur <ViewTransitions /> à un élément head commun
  • Ajouter des listeners (écouteurs) d’événements pendant le processus de navigation pour déclencher des <script> lorsque c’est nécessaire
  • Ajouter des animations de transition de page en utilisant des directives de transition
  • Désactiver le routage côté client pour un lien de page individuel

Vous aurez besoin d’un projet Astro existant avec une mise en page de base commune ou un composant <Head />.

Ce tutoriel utilise le projet fini du tutoriel Construire un blog pour démontrer l’ajout de transitions de vue (routage côté client) à un projet Astro existant. Vous pouvez forker et utiliser cette base de code localement, ou compléter le tutoriel dans le navigateur en éditant le code du tutoriel du blog dans StackBlitz.

Vous pouvez suivre ces étapes avec votre propre projet Astro, mais vous devrez adapter les instructions à votre base de code.

Nous vous recommandons d’utiliser d’abord notre exemple de projet pour compléter ce court tutoriel. Ensuite, vous pourrez utiliser ce que vous avez appris pour créer des transitions de vue dans votre propre projet.

Construire un blog sur des tutoriels de code

Titre de la section Construire un blog sur des tutoriels de code

Dans le Tutoriel d’introduction à la création d’un blog, vous avez découvert le routage intégré basé sur les fichiers d’Astro : tout fichier .astro, .md, ou .mdx situé dans le dossier src/pages/ devient automatiquement une nouvelle page de votre site.

Pour naviguer entre ces pages, vous avez utilisé l’élément HTML standard <a>. Par exemple, pour créer un lien vers votre page “À propos”, vous avez ajouté <a href="/about/">À propos</a> à l’en-tête de votre page. Lorsqu’un visiteur de votre site clique sur ce lien, le navigateur se rafraîchit et charge une nouvelle page avec un contenu entièrement nouveau.

Titre de la section Navigation pleine page vs routage côté client (mode SPA)

Lorsqu’un navigateur actualise et charge une nouvelle page, il n’y a pas de continuité entre l’ancienne et la nouvelle page. Lors du routage côté client, une nouvelle page est affichée sans qu’il soit nécessaire de rafraîchir le navigateur.

Le routage côté client est une caractéristique des sites d’application à page unique (SPA), où l’ensemble du site ou de l’application est une “page” de JavaScript dont le contenu est mis à jour en fonction de l’interaction avec le visiteur.

Comme chaque nouvelle page ne nécessite pas un rafraîchissement complet du navigateur, le routage côté client vous permet de contrôler les transitions entre les pages de plusieurs façons. Les éléments persistants, tels que l’en-tête d’une page commune, n’ont pas besoin d’être entièrement re-rendus à l’écran. La transition d’une page à l’autre peut sembler beaucoup plus fluide. De plus, l’état peut être préservé, ce qui vous permet de transférer des valeurs d’une page à l’autre, ou même de continuer à diffuser une vidéo pendant que vos visiteurs naviguent au sein des pages !

Il arrive que vous souhaitiez ou ayez besoin d’un rafraîchissement complet du navigateur. Par exemple, lorsqu’un lien amène un visiteur à un document .pdf, vous aurez besoin que le navigateur charge cette nouvelle page à partir du serveur. Même si les transitions de vue sont activées dans votre projet Astro, vous pourrez spécifier comment le navigateur doit naviguer par défaut et par lien, et même renoncer complètement au routage côté client.

Pour en savoir plus sur les transitions de vue d’Astro, consultez notre guide, ou plongez dans les instructions ci-dessous pour étendre le blog avec les transitions de vue.

  1. Ajout de transitions de vue à mon site Astro…

  2. Qu’est-ce qui n’est pas un avantage des transitions de vue d’Astro ?

  3. La vue transitant par le routeur…

Ajouter des transitions de vue au tutoriel sur les blogs

Titre de la section Ajouter des transitions de vue au tutoriel sur les blogs

Les étapes ci-dessous vous montrent comment enrichir le produit final du tutoriel Construire un blog en ajoutant un routage côté client pour améliorer les transitions entre les pages.

  1. Mettez à jour la dernière version d’Astro, et mettez à jour toutes les intégrations vers leurs dernières versions en exécutant les commandes suivantes dans votre terminal :

    Fenêtre de terminal
    # Upgrade to Astro v4.x
    npm install astro@latest
    # Exemple: mettre à jour le tutoriel du blog intégration de Preact
    npm install @astrojs/preact@latest
  1. Importez et ajoutez le composant <ViewTransitions /> dans le <head> de votre mise en page.

    Dans l’exemple du tutoriel Blog, l’élément <head> se trouve dans src/layouts/BaseLayout.astro. Le routeur ViewTransitions doit d’abord être importé dans le frontmatter du composant. Ensuite, ajoutez le composant de routage à l’intérieur de l’élément <head>.

    src/layouts/BaseLayout.astro
    ---
    import { ViewTransitions } from "astro:transitions";
    import Header from "../components/Header.astro";
    import Footer from "../components/Footer.astro";
    import "../styles/global.css";
    const { pageTitle } = Astro.props;
    ---
    <html lang="fr">
    <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>{pageTitle}</title>
    <ViewTransitions />
    </head>
    <body>
    <Header />
    <h1>{pageTitle}</h1>
    <slot />
    <Footer />
    <script>
    import "../scripts/menu.js";
    </script>
    </body>
    </html>

    Aucune autre configuration n’est nécessaire pour activer la navigation par défaut côté client d’Astro ! Astro créera des animations de page par défaut basées sur les similitudes entre l’ancienne et la nouvelle page, et fournira également un comportement de repli pour les navigateurs non pris en charge.

  2. Naviguer au fil des pages dans l’aperçu de votre site.

    Affichez l’aperçu de votre site sur un grand écran, par exemple en mode bureau. Lorsque vous passez d’une page à l’autre sur votre site, vous remarquez que le contenu de l’ancienne page s’efface au fur et à mesure que le contenu de la nouvelle page s’affiche. Utilisez le guide des transitions d’affichage pour ajouter un comportement personnalisé si vous n’êtes pas satisfait des valeurs par défaut.

    Affichez l’aperçu de votre site à une taille d’écran plus petite, et essayez d’utiliser le menu hamburger pour naviguer entre les pages. Remarquez que votre menu ne fonctionnera plus après le chargement de la première page.

Avec les transitions de vue, certains scripts peuvent ne plus se réexécuter après la navigation dans la page, comme c’est le cas lors de l’actualisation complète du navigateur. Il existe plusieurs événements au cours du routage côté client que vous pouvez écouter, et déclencher des événements lorsqu’ils se produisent. Les scripts de votre projet devront maintenant s’accrocher à deux événements pour s’exécuter au bon moment pendant la navigation dans la page : astro:page-load et astro:after-swap.

  1. Rendre le script contrôlant le composant de menu mobile <Hamburger /> disponible après avoir navigué vers une nouvelle page.

    Pour rendre votre menu mobile interactif après avoir navigué vers une nouvelle page, ajoutez le code suivant qui écoute l’événement astro:page-load qui s’exécute à la fin de la navigation sur la page, et en réponse, exécute le script existant pour faire fonctionner le menu hamburger lorsqu’on clique dessus :

    src/scripts/menu.js
    document.addEventListener('astro:page-load', () => {
    document.querySelector('.hamburger').addEventListener('click', () => {
    document.querySelector('.nav-links').classList.toggle('expanded');
    });
    });
  2. Rendre le script contrôlant le changement de thème disponible après la navigation de la page.

    Le <script> qui contrôle le basculement du thème clair/foncé est situé dans le composant <ThemeIcon />. Pour que le basculement de thème continue à fonctionner sur chaque page, supprimez l’attribut is:inline du script et ajoutez le même écouteur d’événement que dans l’exemple précédent afin que l’événement astro:page-load puisse déclencher votre fonction existante.

    Mettez à jour la balise script existante pour que votre fonction s’exécute en réponse à l’événement astro:page-load, rendant ainsi votre thème interactif une fois que la nouvelle page est entièrement chargée et visible par l’utilisateur :

    src/components/ThemeIcon.astro
    ---
    ---
    <button id="themeToggle"> /* ... */ </button>
    <style> /* ... */ </style>
    <script is:inline>
    document.addEventListener('astro:page-load', () => {
    const theme = (() => {
    if (typeof localStorage !== "undefined" && localStorage.getItem("theme")) {
    return localStorage.getItem("theme");
    }
    if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
    return "dark";
    }
    return "light";
    })();
    if (theme === "light") {
    document.documentElement.classList.remove("dark");
    } else {
    document.documentElement.classList.add("dark");
    }
    window.localStorage.setItem("theme", theme);
    const handleToggleClick = () => {
    const element = document.documentElement;
    element.classList.toggle("dark");
    const isDark = element.classList.contains("dark");
    localStorage.setItem("theme", isDark ? "dark" : "light");
    };
    document
    .getElementById("themeToggle")
    .addEventListener("click", handleToggleClick);
    });
    </script>

    Désormais, le changement de thème est interactif sur chaque page lorsque l’on utilise le routeur <ViewTransitions />, une fois que la page a fini de se charger.

  3. Vérifier la présence d’un thème précédent pour éviter le clignotement en mode sombre.

    Le changement de thème fonctionne sur chaque page, mais son script est chargé à la fin du processus de navigation, après le chargement complet de la nouvelle page dans le navigateur. Il peut y avoir un flash de la version à thème léger du site avant que le script de basculement de thème ne s’exécute et ne vérifie quel thème il doit utiliser sur la page.

    Pour vérifier et, si nécessaire, définir le mode sombre plus tôt dans le processus de navigation, créez une fonction qui s’exécutera en réponse à l’événement astro:after-swap. La fonction suivante, qui vérifie le localStorage du navigateur pour le thème sombre, sera exécutée immédiatement après que la nouvelle page soit remplacée par l’ancienne, avant que les éléments du DOM ne soient peints à l’écran.

    Ajoutez ce nouveau script au composant <ThemeIcon />, en plus du script qui contrôle le basculement du thème.

    src/components/ThemeIcon.astro
    <script> ... <script>
    <script>
    document.addEventListener('astro:after-swap', () => {
    localStorage.theme === 'dark'
    ? document.documentElement.classList.add("dark")
    : document.documentElement.classList.remove("dark");
    });
    </script>

    Désormais, chaque changement de page qui utilise le routeur <ViewTransitions /> pour la navigation côté client (et donc l’accès à l’événement astro:after-swap) sera en mesure de détecter theme : dark à partir du localStorage du navigateur et de mettre à jour la page actuelle en conséquence avant que la page ne soit rendue pour l’observateur.

    Quel est l’ordre correct des événements après qu’un visiteur a cliqué sur un lien pour accéder à une nouvelle page lors de la navigation côté client ?

Personnaliser les animations de transition

Titre de la section Personnaliser les animations de transition
  1. Remplacer l’animation fade par défaut par une animation slide pour le titre de la page.

    Lorsque les transitions d’affichage sont activées, vous disposez actuellement d’un petit fondu entrant et sortant pour toutes les animations de transition de page. Astro fournit également une animation intégrée de type slide. Pour changer le type d’animation pour un seul élément, ajoutez la directive transition:animate="".

    Par exemple, pour faire glisser les titres de la page au lieu de les faire apparaître en fondu, ajoutez transition:animate="slide" à l’élément <h1> de la BaseLayout :

    src/layouts/BaseLayout.astro
    ---
    import Header from "../components/Header.astro";
    import Footer from "../components/Footer.astro";
    import "../styles/global.css";
    import { ViewTransitions } from "astro:transitions";
    const { pageTitle } = Astro.props;
    ---
    <html lang="fr">
    <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>{pageTitle}</title>
    <ViewTransitions />
    </head>
    <body>
    <Header />
    <h1 transition:animate="slide">{pageTitle}</h1>
    <slot />
    <Footer />
    <script>
    import "../scripts/menu.js";
    </script>
    </body>
    </html>

    Dans l’aperçu de votre navigateur, vous verrez maintenant les titres de la page glisser sur l’écran, tandis que d’autres éléments tels que le corps du texte continuent à s’effacer.

    Essayez-le vous-même - Faites glisser les liens de navigation à l’intérieur

    Titre de la section Essayez-le vous-même - Faites glisser les liens de navigation à l’intérieur

    Ajoutez une directive d’animation, pour que le <div> dans Navigation.Astro contenant tous les liens d’en-tête, glisse dans la page de navigation, en suivant les mêmes étapes que ci-dessus.

    Montrez-moi le code.
    src/components/Navigation.astro
    ---
    ---
    <div transition:animate="slide" class="nav-links">
    <a href="/">Home</a>
    <a href="/about/">About</a>
    <a href="/blog/">Blog</a>
    <a href="/tags/">Tags</a>
    </div>

    Vérifiez l’aperçu de votre navigateur et vous constaterez que le titre de la page et les liens de l’en-tête sont désormais insérés dans chaque page de navigation.

  2. Ajoutez un fondu plus long aux descriptions de vos articles de blog.

    Vous pouvez également personnaliser les animations intégrées d’Astro en les important, puis en fournissant les propriétés d’animation CSS.

    Par exemple, pour que la description s’estompe lentement lorsque vous naviguez vers un article de blog, importez l’animation fade dans votre mise en page pour les articles de blog Markdown. Ensuite, ajoutez la directive de transition pour le fade d’Astro avec une durée de 2s :

    src/layouts/MarkdownPostLayout.astro
    ---
    import BaseLayout from "./BaseLayout.astro";
    import { fade } from "astro:transitions";
    const { frontmatter } = Astro.props;
    ---
    <BaseLayout pageTitle={frontmatter.title}>
    <p>{frontmatter.pubDate.slice(0, 10)}</p>
    <p transition:animate={fade({ duration: '2s' })} ><em>{frontmatter.description}</em></p>
    <p>Écrit par : {frontmatter.author}</p>
    <img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} />
    <slot />
    </BaseLayout>

    Naviguez vers n’importe quel article de blog dans l’aperçu de votre navigateur, et vous verrez que la description s’affiche en fondu plus lentement que le reste du texte.

    En savoir plus sur les différentes directives de transition et personnalisation des animations.

Forcer le rechargement complet du navigateur pour certains liens

Titre de la section Forcer le rechargement complet du navigateur pour certains liens
  1. Empêcher le routage côté client et demander au navigateur de se recharger lorsqu’il navigue vers votre page “À propos”.

    Il peut arriver que vous souhaitiez que le navigateur soit entièrement rechargé lorsque les visiteurs cliquent sur un certain lien. Par exemple, vous pouvez créer un lien vers une page qui n’utilise pas le routeur <ViewTransitions />, ou vers un fichier directement, comme un .pdf.

    Pour que votre navigateur se rafraîchisse à chaque fois que vous cliquez sur le lien de navigation pour aller à votre page “About”, ajoutez l’attribut data-astro-reload à la balise <a> de votre composant <Navigation />. Cela remplacera entièrement le routeur <ViewTransitions />, et toutes les animations de transition de vue, pour ce seul lien.

    src/components/Navigation.astro
    ---
    ---
    <div transition:animate="slide" class="nav-links">
    <a href="/">Home</a>
    <a href="/about/" data-astro-reload>À propos</a>
    <a href="/blog/">Blog</a>
    <a href="/tags/">Tags</a>
    </div>

    Désormais, lorsque vous cliquez sur le lien de navigation vers votre page “À propos”, aucune animation ne se produira. Les liens et le titre de la page ne glisseront pas et le contenu de la page ne s’affichera pas en fondu lorsque vous naviguerez vers votre page À propos en utilisant ce lien.

  2. Ajoutez un lien vers votre page “À propos” à partir de votre nom d’auteur dans votre mise en page Markdown pour les articles de blog.

    data-astro-reload ne déclenche un rafraîchissement complet du navigateur que lorsque l’on accède à une nouvelle page à partir du lien auquel il a été ajouté. Il ne contrôle pas tous les cas où l’on navigue vers votre page “À propos”.

Dans votre composant <MarkdownPostLayout />, ajoutez un lien vers votre page “À propos” sur votre nom d’auteur :

src/layouts/MarkdownPostLayout.astro
---
import BaseLayout from "./BaseLayout.astro";
import { fade } from "astro:transitions";
const { frontmatter } = Astro.props;
---
<BaseLayout pageTitle={frontmatter.title}>
<p>{frontmatter.pubDate.slice(0, 10)}</p>
<p transition:animate={fade({ duration: '2s' })} ><em>{frontmatter.description}</em></p>
<p>Écrit par : <a href="/about/">{frontmatter.author}</a></p>
<img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} />
<slot />
</BaseLayout>

Si vous visitez un article de blog dans l’aperçu de votre navigateur et que vous cliquez sur le nom de l’auteur pour accéder à la page “À propos”, à quoi ressemble la navigation dans la page ?

Lorsqu’un visiteur clique sur un lien vers la page “À propos” à partir d’un article de blog, le titre de la page et les liens de navigation de l’en-tête parce que .

Il y a encore beaucoup de choses à explorer ! Consultez notre guide complet des transitions de vue pour découvrir d’autres choses que vous pouvez faire avec les transitions de vue.

Pour l’exemple complet du tutoriel du blog utilisant les transitions de vue, voir la branche View Transitions du répertoire du tutoriel.