Aller au contenu

Routage

Astro utilise le routage basé sur les fichiers pour générer vos URLs de construction en fonction de la disposition des fichiers dans le répertoire src/pages/ de votre projet.

Astro utilise des éléments HTML standard <a> pour naviguer entre les routes. Il n’y a pas de composant <Link> spécifique au framework.

src/pages/index.astro
<p>En savoir plus <a href="/about/">about</a> Astro !</p>
<!-- Avec `base: "/docs"` de configuré -->
<p>Apprenez-en plus dans notre section <a href="/docs/reference/">référence</a> !</p>

Les composants de page .astro ainsi que les fichiers Markdown et MDX (.md, .mdx) dans le répertoire src/pages deviennent automatiquement des pages de votre site web. La route de chaque page correspond à son chemin et à son nom de fichier dans le répertoire src/pages.

# Exemple : Routes Statiques
src/pages/index.astro -> mysite.com/
src/pages/about.astro -> mysite.com/about
src/pages/about/index.astro -> mysite.com/about
src/pages/about/me.astro -> mysite.com/about/me
src/pages/posts/1.md -> mysite.com/posts/1

Un fichier de page Astro peut spécifier des paramètres de route dynamiques dans son nom de fichier pour générer des pages correspondantes. Par exemple, vous pouvez créer un fichier authors/[author].astro qui génère une page de biographie pour chaque auteur de votre blog. author devient un paramètre accessible depuis l’intérieur de la page.

Dans le mode statique par défaut d’Astro, ces pages sont générées au moment de la construction, et vous devez donc prédéterminer la liste des author qui obtiendront un fichier correspondant. En mode SSR, une page sera générée sur demande pour toute route correspondante.

Parce que toutes les routes doivent être déterminées au moment de la construction, une route dynamique doit exporter une fonction getStaticPaths() qui renvoie un tableau d’objets avec une propriété params. Chacun de ces objets générera une route correspondante.

[dog].astro définit le paramètre dynamique dog dans son nom de fichier, donc les objets retournés par getStaticPaths() doivent inclure dog dans leurs params. La page peut alors accéder à ce paramètre en utilisant Astro.params.

src/pages/dogs/[dog].astro
---
export function getStaticPaths() {
return [
{params: {dog: 'clifford'}},
{params: {dog: 'rover'}},
{params: {dog: 'spot'}},
];
}
const { dog } = Astro.params;
---
<div>Bon chien, {dog} !</div>

Cela va générer trois pages : /dogs/clifford, /dogs/rover, et /dogs/spot, chacune affichant le nom du chien correspondant.

Le nom du fichier peut inclure plusieurs paramètres, qui doivent tous être inclus dans les objets params de getStaticPaths() :

src/pages/[lang]-[version]/info.astro
---
export function getStaticPaths () {
return [
{params: {lang: 'en', version: 'v1'}},
{params: {lang: 'fr', version: 'v2'}},
];
}
const { lang, version } = Astro.params;
---
...

Cela va générer /en-v1/info et /fr-v2/info.

Les paramètres peuvent être inclus dans des parties séparées du chemin, ainsi nous pourrions utiliser src/pages/[lang]/[version]/info.astro avec le même getStaticPaths pour générer /en/v1/info et /fr/v2/info.

Les params fournis à la fonction getStaticPaths() ne sont pas décodés. Utilisez la fonction decodeURI lorsque vous avez besoin de décoder les valeurs des paramètres.

src/pages/[slug].astro
---
export function getStaticPaths() {
return [
{ params: { slug: decodeURI("%5Bpage%5D") } }, // est décodé en "[page]"
]
}
---
En apprendre plus sur getStaticPaths().

Si vous avez besoin de plus de flexibilité dans le routage de vos URL, vous pouvez utiliser un paramètre REST ([...path]) dans votre nom de fichier .astro pour correspondre à des chemins de fichiers de n’importe quelle profondeur :

src/pages/sequences/[...path].astro
---
export function getStaticPaths() {
return [
{params: {path: 'one/two/three'}},
{params: {path: 'four'}},
{params: {path: undefined }}
]
}
const { path } = Astro.params;
---
...

Cela générera /sequences/one/two/three, /sequences/four, et /sequences. (Définir le paramètre REST à undefined lui permet de correspondre à la page de premier niveau).

Les paramètres REST peuvent être utilisés avec d’autres paramètres nommés. Par exemple, nous pourrions représenter la visionneuse de fichiers de GitHub avec une route dynamique comme celle-ci :

/[org]/[repo]/tree/[branch]/[...file]

Dans cet exemple, une requête pour /withastro/astro/tree/main/docs/public/favicon.svg serait divisée en paramètres nommés suivants :

{
org: 'withastro',
repo: 'astro',
branch: 'main',
file: 'docs/public/favicon.svg'
}

Exemple : Pages dynamiques à plusieurs niveaux

Titre de la section Exemple : Pages dynamiques à plusieurs niveaux

Ici, nous utilisons un paramètre REST ([...slug]) et la fonctionnalité props de getStaticPaths() pour générer des pages pour des slugs de différentes profondeurs.

src/pages/[...slug].astro
---
export async function getStaticPaths() {
const pages = [
{
slug: undefined,
title: "Magasin Astro",
text: "Bienvenue dans le magasin Astro !",
},
{
slug: "products",
title: "Produits Astro",
text: "Nous avons beaucoup de produits pour vous",
},
{
slug: "products/astro-handbook",
title: "L'ultime manuel d'Astro",
text: "Si vous voulez apprendre Astro, vous devez lire ce livre.",
},
];
return pages.map(({ slug, title, text }) => {
return {
params: { slug },
props: { title, text },
};
});
}
const { title, text } = Astro.props;
---
<html>
<head>
<title>{title}</title>
</head>
<body>
<h1>{title}</h1>
<p>{text}</p>
</body>
</html>

En mode SSR, les routes dynamiques sont définies de la même manière : incluez des crochets [param] ou [...path] dans vos noms de fichiers pour faire correspondre des chaînes ou des chemins arbitraires. Mais comme les routes ne sont plus construites à l’avance, la page sera servie à toute route correspondante. Comme il ne s’agit pas de routes « statiques », getStaticPaths ne doit pas être utilisé.

src/pages/resources/[resource]/[id].astro
---
const { resource, id } = Astro.params;
---
<h1>{resource}: {id}</h1>

Cette page sera servie pour toute valeur de resource et id : resources/users/1, resources/colors/blue, etc.

Modification de l’exemple [...slug] pour le mode SSR

Titre de la section Modification de l’exemple [...slug] pour le mode SSR

Comme les pages SSR ne peuvent pas utiliser getStaticPaths, elles ne peuvent pas recevoir de props. Ici, nous modifions notre exemple précédent pour qu’il fonctionne en SSR en cherchant la valeur du paramètre slug dans un objet. Si la route est à la racine (« / »), le paramètre slug sera undefined. Si la valeur n’existe pas dans l’objet, nous redirigeons vers une page 404.

src/pages/[...slug].astro
---
const pages = [
{
slug: undefined,
title: 'Magasin Astro',
text: 'Bienvenue dans le magasin Astro !',
},
{
slug: 'products',
title: 'Produits Astro',
text: 'Nous avons beaucoup de produits pour vous',
},
{
slug: 'products/astro-handbook',
title: "L'ultime manuel d'Astro",
text: 'Si vous voulez apprendre Astro, vous devez lire ce livre.',
}
];
const { slug } = Astro.params;
const page = pages.find((page) => page.slug === slug);
if (!page) return Astro.redirect("/404");
const { title, text } = page;
---
<html>
<head>
<title>{title}</title>
</head>
<body>
<h1>{title}</h1>
<p>{text}</p>
</body>
</html>

Parfois, vous devrez rediriger vos lecteurs vers une nouvelle page, soit de manière permanente parce que la structure de votre site a changé, soit en réponse à une action telle que la connexion à une route authentifiée.

Vous pouvez définir des règles pour rediriger les utilisateurs vers des pages déplacées de façon permanente dans votre configuration Astro. Ou rediriger les utilisateurs dynamiquement au fur et à mesure qu’ils utilisent votre site.

Ajouté à la version : astro@2.9.0

Vous pouvez spécifier une correspondance de redirections permanentes dans votre configuration Astro avec la valeur redirects. Pour la plupart des redirections, il s’agit d’une correspondance entre l’ancienne et la nouvelle route :

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
redirects: {
'/ancienne-page': '/nouvelle-page'
}
});

Ces redirections suivent les mêmes règles de priorité que les routes basées sur des fichiers et auront toujours une priorité inférieure à celle d’une page existante ayant le même nom dans votre projet. Par exemple, /ancienne-page ne redirigera pas vers /nouvelle-page si votre projet contient le fichier src/pages/ancienne-page.astro.

Les routes dynamiques sont autorisées tant que les nouvelles et les anciennes routes contiennent les mêmes paramètres, par exemple :

{
"/blog/[...slug]": "/articles/[...slug]"
}

En utilisant SSR ou un adaptateur statique, vous pouvez également fournir un objet comme valeur, ce qui vous permet de spécifier le code status en plus de la nouvelle destination :

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
redirects: {
'/ancienne-page': {
status: 302,
destination: '/nouvelle-page'
}
}
});

Lors de l’exécution de astro build, Astro produira des fichiers HTML avec la balise meta refresh par défaut. Les adaptateurs supportés écriront à la place le fichier de configuration de l’hôte avec les redirections.

Le code de statut est 301 par défaut. Si l’on construit des fichiers HTML, le code de statut n’est pas utilisé par le serveur.

Globalement sur Astro, la méthode Astro.redirect vous permet de rediriger vers une autre page dynamiquement. Vous pouvez le faire après avoir vérifié que l’utilisateur est connecté en récupérant sa session à partir d’un cookie.

src/pages/account.astro
---
import { isLoggedIn } from '../utils';
const cookie = Astro.request.headers.get('cookie');
// Si l'utilisateur n'est pas connecté, le rediriger vers la page de connexion.
if (!isLoggedIn(cookie)) {
return Astro.redirect('/login');
}
---
<html>
<!-- Page ici... -->
</html>

Ajouté à la version : astro@4.13.0

Une réécriture vous permet de servir une route différente sans rediriger le navigateur vers une page différente. Le navigateur affichera l’adresse originale dans la barre d’URL, mais il affichera à la place le contenu de l’URL fournie à Astro.rewrite().

Les réécritures peuvent être utiles pour afficher le même contenu sur plusieurs chemins (par exemple, /products/shoes/men/ et /products/men/shoes/) sans avoir à maintenir deux fichiers sources différents.

Les réécritures sont également utiles à des fins de référencement et d’expérience utilisateur. Elles vous permettent d’afficher un contenu qui, autrement, nécessiterait de rediriger votre visiteur vers une autre page ou renverrait un statut 404. Une utilisation courante des réécritures consiste à afficher le même contenu localisé pour différentes variantes d’une langue.

L’exemple suivant utilise une réécriture pour afficher la version /es/ d’une page lorsque le chemin URL /es-CU/ (espagnol cubain) est visité. Lorsqu’un visiteur se rend à l’URL /es-cu/articles/introduction, Astro affiche le contenu généré par le fichier src/pages/es/articles/introduction.astro.

src/pages/es-cu/articles/introduction.astro
---
return Astro.rewrite("/es/articles/introduction")
---

Utilisez context.rewrite() dans vos fichiers de destination pour rediriger vers une autre page :

src/pages/api.js
export function GET(context) {
if (!context.locals.allowed) {
return context.rewrite("/")
}
}

Si l’URL passée à Astro.rewrite() émet une erreur d’exécution, Astro affichera l’erreur en superposition dans le cadre du développement et renverra un code d’état 500 dans le cadre de la production. Si l’URL n’existe pas dans votre projet, un code d’état 404 sera retourné.

Vous pouvez intentionnellement créer une réécriture pour afficher votre page /404, par exemple pour indiquer qu’un produit de votre boutique e-commerce n’est plus disponible :

src/pages/[item].astro
---
const { item } = Astro.params;
if (!itemExists(item)) {
return Astro.rewrite("/404")
}
---
<div>...</div>

Vous pouvez également procéder à une réécriture conditionnelle sur la base d’un statut de réponse HTTP, par exemple pour afficher une certaine page de votre site lorsque vous visitez une URL qui n’existe pas :

src/middleware.mjs
export const onRequest = async (context, next) => {
const response = await next();
if (response.status === 404) {
return context.rewrite("/");
}
return response;
}

Avant d’afficher le contenu du chemin de réécriture spécifié, la fonction Astro.rewrite() déclenche une nouvelle phase complète d’affichage. Celle-ci ré-exécute tout middleware pour la nouvelle route/demande.

Voir la référence de l’API Astro.rewrite() pour plus d’informations.

Il est possible que plusieurs routes définies tentent de construire le même chemin d’URL. Par exemple, toutes ces routes pourraient construire /posts/create :

  • Répertoiresrc/pages/
    • […slug].astro
    • Répertoireposts/
      • create.astro
      • [page].astro
      • [pid].ts
      • […slug].astro

Astro a besoin de savoir quelle route doit être utilisée pour construire la page. Pour ce faire, il les trie dans l’ordre selon les règles suivantes :

  • Les routes réservées dans Astro
  • Les routes avec plus de segments de chemin seront prioritaires sur les itinéraires moins spécifiques. Dans l’exemple ci-dessus, toutes les routes sous /posts/ sont prioritaires sur /[...slug].astro à la racine.
  • Les routes statiques sans paramètres de chemin sont prioritaires sur les routes dynamiques. Par exemple, /posts/create.astro est prioritaire sur toutes les autres routes de l’exemple.
  • Les routes dynamiques utilisant des paramètres nommés sont prioritaires sur les paramètres restants. Par exemple, /posts/[page].astro est prioritaire sur /posts/[...slug].astro.
  • Les routes dynamiques pré-rendues ont la priorité sur les routes dynamiques du serveur.
  • Les points de terminaison ont la priorité sur les pages.
  • Les routes basées sur des fichiers ont priorité sur les redirections.
  • Si aucune des règles ci-dessus ne décide de l’ordre, les routes sont triées par ordre alphabétique en fonction des paramètres régionaux par défaut de votre installation Node.

Dans l’exemple ci-dessus, voici quelques exemples de la manière dont les règles feront correspondre une URL demandée à la route utilisée pour construire le code HTML :

  • pages/post/create.astro - Ne construira que des /post/create.
  • pages/post/[pid].ts - Construira /post/abc, /post/xyz, etc. Mais pas /post/create.
  • pages/posts/[page].astro - Construira /posts/1, /posts/2, etc. Mais pas /posts/create, /posts/abc ni /posts/xyz.
  • pages/post/[...slug].astro - Construira /post/1/2, /post/a/b/c, etc. Mais pas /post/create, /post/1, /post/abc etc.
  • pages/[...slug].astro - Construira /abc, /xyz, /abc/xyz, etc. Mais pas /posts/create, /posts/1, /posts/abc, etc.

Les routes internes ont la priorité sur les routes définies par l’utilisateur ou par l’intégration, car elles sont nécessaires au déroulement des fonctionnalités d’Astro. Les routes réservées d’Astro sont les suivantes :

  • _astro/ : Fournit toutes les ressources statiques au client, y compris les documents CSS, les scripts client intégrés, les images optimisées et toutes les ressources Vite.
  • _server_islands/ : Sert les composants dynamiques différés dans une Île de serveur (EN).
  • _actions/ : Sert toutes les actions définies.

Astro prend en charge la pagination intégrée pour les grandes collections de données qui doivent être divisées en plusieurs pages. Astro génère les propriétés de pagination courantes, y compris les URL des pages précédentes/suivantes, le nombre total de pages, etc.

Les noms des routes paginées doivent utiliser la même syntaxe de [crochets] que les routes dynamiques standard. Par exemple, le nom de fichier /astronauts/[page].astro générera des routes pour /astronauts/1, /astronauts/2, etc, là où [page] est le numéro de la page générée.

Vous pouvez utiliser la fonction paginate() pour générer ces pages pour un tableau de valeurs comme ceci :

src/pages/astronauts/[page].astro
---
export async function getStaticPaths({ paginate }) {
const astronautPages = [{
astronaut: 'Neil Armstrong',
}, {
astronaut: 'Buzz Aldrin',
}, {
astronaut: 'Jean-Loup Chrétien',
}, {
astronaut: 'Thomas Pesquet',
}];
// Génère des pages à partir de notre tableau d'astronautes, avec 2 par page
return paginate(astronautPages, { pageSize: 2 });
}
// Toutes les données paginées sont passées dans la propriété "page"
const { page } = Astro.props;
---
<!-- Affiche le numéro de la page actuelle. Astro.params.page peut aussi être utilisé ! -->
<h1>Page {page.currentPage}</h1>
<ul>
<!-- Fait la liste de notre tableau d'astronautes -->
{page.data.map(({ astronaut }) => <li>{astronaut}</li>)}
</ul>

Cela génère les pages suivantes, avec deux éléments par page :

  • /astronauts/1 - Page 1: Affiche « Neil Armstrong » et « Buzz Aldrin »
  • /astronauts/2 - Page 2: Affiche « Jean-Loup Chrétien » et « Thomas Pesquet »

Lorsque vous utilisez la fonction paginate(), chaque page recevra ses données via une propriété page. Celle-ci possède de nombreuses propriétés utiles que vous pouvez utiliser pour créer des pages et des liens entre elles :

interface Page<T = any> {
/** Tableau contenant la tranche de données de la page que vous avez transmise à la fonction paginate() */
data: T[];
/** Métadonnées */
/** Nombre du premier élément de la page, à partir de 0 */
start: number;
/** Nombre du dernier élément de la page, à partir de 0 */
end: number;
/** Nombre total de résultats */
total: number;
/** Numéro de la page actuelle, à partir de 1 */
currentPage: number;
/** Nombre d'éléments par page (par défaut : 10) */
size: number;
/** Nombre de la dernière page */
lastPage: number;
url: {
/** URL de la page actuelle */
current: string;
/** URL de la page précédente (s'il y en a une) */
prev: string | undefined;
/** URL de la page suivante (s'il y en a une) */
next: string | undefined;
/** url de la première page (si la page actuelle n'est pas la première page) */
first: string | undefined;
/** url de la dernière page (si la page actuelle n'est pas la dernière) */
last: string | undefined;
};
}

L’exemple suivant affiche les informations actuelles de la page ainsi que des liens pour naviguer entre les pages :

src/pages/astronauts/[page].astro
---
// Paginons la même liste d'objets { astronaut } que l'exemple précédent
export async function getStaticPaths({ paginate }) { /* ... */ }
const { page } = Astro.props;
---
<h1>Page {page.currentPage}</h1>
<ul>
{page.data.map(({ astronaut }) => <li>{astronaut}</li>)}
</ul>
{page.url.first ? <a href={page.url.first}>Début</a> : null}
{page.url.prev ? <a href={page.url.prev}>Précédent</a> : null}
{page.url.next ? <a href={page.url.next}>Suivant</a> : null}
{page.url.last ? <a href={page.url.last}>Fin</a> : null}
En savoir plus sur la propriété page de pagination.

Un cas d’utilisation plus avancé de la pagination est la pagination imbriquée, c’est-à-dire lorsque la pagination est combinée avec d’autres paramètres d’itinéraires dynamiques. Vous pouvez utiliser la pagination imbriquée pour regrouper votre collection paginée en fonction d’une propriété ou d’une balise.

Par exemple, si vous voulez grouper vos posts Markdown paginés par une balise, vous utiliserez la pagination imbriquée en créant une page /src/pages/[tag]/[page].astro qui correspondra aux URLS suivantes :

  • /red/1 (tag=red)
  • /red/2 (tag=red)
  • /blue/1 (tag=blue)
  • /green/1 (tag=green)

La pagination imbriquée fonctionne en renvoyant un tableau de résultats paginate() de getStaticPaths(), un pour chaque groupe.

Dans l’exemple suivant, nous allons implémenter la pagination imbriquée pour construire les URLs listées ci-dessus :

src/pages/[tag]/[page].astro
---
export function getStaticPaths({paginate}) {
const allTags = ['red', 'blue', 'green'];
const allPosts = Object.values(import.meta.glob('../pages/post/*.md', { eager: true }));
// Pour chaque tag, retourne un résultat paginate().
// Assurez-vous de passer `{params: {tag}}` à la fonction `paginate()`
// afin qu'Astro sache à quel groupe de tags le résultat est destiné.
return allTags.map((tag) => {
const filteredPosts = allPosts.filter((post) => post.frontmatter.tag === tag);
return paginate(filteredPosts, {
params: { tag },
pageSize: 10
});
});
}
const { page } = Astro.props;
const params = Astro.params;

Vous pouvez exclure des pages ou des répertoires dans src/pages de la construction en préfixant leurs noms par un trait de soulignement (_). Les fichiers avec le préfixe _ ne seront pas reconnus par le routeur et ne seront pas placés dans le répertoire dist/.

Cela vous permet de créer des pages privées, et aussi de placer les tests, les utilitaires et les composants dans les pages correspondantes, en les empêchant d’être construits dans des fichiers .html et placés dans le répertoire dist/.

Dans cet exemple, seuls src/pages/index.astro et src/pages/projects/project1.md seront construits comme routes de pages et fichiers HTML.

  • Répertoiresrc/pages/
    • Répertoire_répertoire-caché/
      • page1.md
      • page2.md
    • _page-cachée.astro
    • index.astro
    • Répertoireprojects/
      • _SomeComponent.astro
      • _utils.js
      • project1.md
Contribuer

Comment pouvons-nous vous aider ?

Créer une issue GitHub

Le moyen le plus rapide d'alerter notre équipe d'un problème.

Communauté