Retour aux articles

6 Routes à connaître si tu utilises Remix (guide complet)

6 types de routes
9 minutes de lecture- 780 vues

Envisages-tu de tester ou même d'utiliser le framework Remix pour ton prochain projet ?

Pour cela, il va falloir te familiariser avec son puissant routing. Cet article te liste les 6 types de routes que tu vas utiliser au quotidien avec Remix. Si tu préfères lire la doc, Remix explique tout en détail sur le site.

Le routing, c'est quoi ?

Commençons par définir ce qu'est le routing

C'est le chemin (sous forme d'URL) qui permet d'accéder à ton site internet

Exemples :

  • leboncoin.fr te permet d'accéder à la page d'accueil du bon coin, sa route "index".
  • leboncoin.fr/annonces/offres te permet d'accéder à une deuxième page du bon coin. La page est différente de la première, le chemin d'accès dans l'URL est différent. C'est une deuxième route.

Tous les sites possèdent minimum une route (qu'on va appeler route index, ou route par défaut).

Ce concept n'est pas récent. À mes débuts dans le développement, j'intégrais mes premières pages en HTML et PHP. La convention était de nommer nos fichiers index.html et index.php. Ces fichiers étaient ensuite accessibles au nom de domaine local. Par exemple, localhost:8000. Sans le savoir, j'avais déjà créé ma première route index.

Avec l'arrivée de React et de ses framework, le routing se fait généralement sans configuration de notre part. (sauf si tu utilises React-Router, mais si c'est le cas, tu es au bon endroit !)

Explication vidéo

Nous avons fait un guide vidéo pour t'expliquer le routing de Remix avec plus d'exemples.

Créer sa première route (type 1)

Lorsques tu génères un nouveau projet Remix avec l'un de ses nombreux template, une route par défaut aura déjà été créée. Elle se situe dans ton dossier app/routes et se nomme __index.tsx.

app/routes/_index.tsx

_10
export default function Index() {
_10
return (
_10
<h1>Hello world !</h1>
_10
);
_10
}

Voici les 2 règles à respecter pour créer une route avec la configuration par défaut de Remix :

  • Créer un fichier au format .jsx ou .tsx dans le dossier app/routes.
  • Le nommer (son nom va définir le chemin pour y accéder dans l'URL.

Dans l'exemple ci-dessous, nous avons ajouté un composant React à l'intérieur de notre fichier. Cette vue sera accessible à la page d'accueil de notre site (par défaut localhost:3000)

Mais il n'est pas obligatoire d'exporter des composants React depuis nos routes.

Cela dépend de ton besoin. Si tu veux juste créer un endpoint API (une route qui renvoie du JSON, par exemple), tu n'as pas besoin de déclarer un composant React.

app/routes/users.tsx

_10
export const loader = () => {
_10
return { name: 'Virgile' }
_10
}

Voici un exemple d'une route Remix, accessible à l'URL localhost:3000/api. Elle renvoie un objet au format JSON.


_10
{ name: "Virgile" }

Création d'une route dynamique (type 2)

Pour créer une route dynamique, nous devons utiliser un nommage de fichier précis. Il nous suffit d'ajouter le préfixe $ à notre nom de fichier.

Par exemple, si je souhaite afficher le détail de l'utilisateur Virgile* à l'adresse http://localhost:3000/users/virgile, je vais implémenter cette logique en deux étapes :

  • Nommer un fichier dans le dossier app/routes, nommé users.$username.tsx
  • Exporter par défaut un composant React pour afficher une vue, avec les informations de cet utilisateur

Regardons avec un exemple.

app/routes/users.$username.tsx

_10
import { useParams } from '@remix-run/react';
_10
export default function Username() {
_10
const username = useParams().username;
_10
return (
_10
<h1>Salut {username} !</h1>
_10
);
_10
}

Ici, nous donnons une instruction à Remix. Nous lui demandons de créer une route au chemin users/virgile. Le point (.) dans le nommage du fichier nous permet d'ajouter un slash dans l'URL. Ensuite, le $ nous permet de nommer la clé du paramètre dans l'URL.

Nous récupérons ensuite ce paramètre dynamique, nommé username dans notre composant React, côté client à l'aide du hook useParams() que nous importons depuis Remix.

Ce fichier nous permet donc de créer une route qui va afficher une vue côté client, avec une valeur dynamique en fonction de la valeur que nous entrons dans l'URL.

salut virgile

La valeur de notre variable username est déterminée par le paramètre d'URL (soit virgile, dans cet exemple)

Création d'une route imbriquée (type 3)

La route imbriquée est similaire à la route dynamique. Nous nommons le fichier de la même manière qu'une route dynamique. La seule différence, c'est le contenu de la route parent (dans notre exemple, la route users.tsx) est visible sur la page. C'est très pratique pour afficher par exemple système d'onglets dans notre application.

Exemple de page avec des onglets

Nous pourrions très bien reproduire cet exemple sous forme de route imbriquée. La route parent afficherait les onglets, et le contenu de l'onglet (Subtopic 1) serait affiché dans la route enfant.

Faisons d'abord une petite refactorisation.

app/routes/users.tsx

_16
import { Link } from '@remix-run/react';
_16
_16
export default function Users() {
_16
return (
_16
<div>
_16
<h1>Liste des utilisateurs</h1>
_16
<ul>
_16
{['Virgile', 'Cédric'].map((username) => (
_16
<Link to={`/users/${username}`} key={username}>
_16
{username}
_16
</Link>
_16
))}
_16
</ul>
_16
</div>
_16
);
_16
}

Nous affichons maintenant une liste de deux utilisateurs sur la route localhost:3000/users, Virgile et Cédric. Nous avons également des liens pour accéder à leur information.

Spoiler, mais ça ne va pas avoir l'effet désiré. On n'est cependant pas loin du but. En théorie, il suffirait de changer l'URL à localhost:3000/cedric pour afficher la vue pour cet utilisateur (c'est la route dynamique que nous avons créée plus haut).

Malheureusement, après avoir cliqué sur le lien, on se rend compte que la page n'a pas changé 🤔 ??

image.png

Et bien, si. Nous avons réussi à donne l'instruction à Remix de créer une route imbriquée. Sauf qu'on a oublié un composant magique nous permettant de placer la position de l'enfant dans le DOM.

En fait, la page ci-dessus affiche toujours le contenu du parent (les liens de nos utilisateurs), mais elle n'affiche pas la route enfant car on ne lui a pas donné l'instruction. (il n'y a donc aucun bug, rassurez-vous)

Que dois-je faire pour faire apparaître ma route enfant ?

Le composant <Outlet/> est la pièce manquante pour bénéficier des routes imbriquées avec Remix. En effet, si nous accédons à la route parent (localhost:3000/users), Remix affiche la route users.tsx. Mais si on accède à la route localhost:3000/users/cedric, Remix va regarder le nom de notre fichier users.$userId.tsx.

Et il va vérifier trois éléments :

  • Est-ce qu'il y a un paramètre d'URL dynamique (symbolisé par le $)
  • Est-ce qu'il existe une route parent (dans notre cas, users.tsx
  • Est-ce que la route parent possède un composant <Outlet/>

Rajoutons maintenant le composant Outlet et regardons ce qui se passe.

tsx

_17
import { Link, Outlet } from '@remix-run/react';
_17
_17
export default function Users() {
_17
return (
_17
<div>
_17
<h1>Liste des utilisateurs</h1>
_17
<ul>
_17
{['Virgile', 'Cédric'].map((username) => (
_17
<Link to={`/users/${username}`} key={username}>
_17
{username}
_17
</Link>
_17
))}
_17
</ul>
_17
<Outlet />
_17
</div>
_17
);
_17
}

La route imbriquée s'affiche correctement

En résumé, ajouter une route imbriquée est relativement simple. Il suffit de rajouter le composant <Outlet/> dans la route parent. Et Remix se charge du reste.

Création d'une route layout (type 4)

Reprenons l'exemple de nos onglets pour mieux comprendre l'intérêt d'une route layout. On va commencer par la définir, en la comparant à une route imbriquée.

Une route layout, c'est une route imbriquée, mais le chemin n'est pas visible dans l'URL.

Par exemple, si vous souhaitez afficher un composant spécial sur certaines pages, mais pas sur d'autres (ou bien un modal qui apparaît après 5 secondes, c'est vous qui voyez), c'est totalement possible grâce aux routes Layout.

Pour créer une route layout, il suffit de rajouter le préfixe _ (underscore) à la route parent. Son nom va disparaître de l'URL. Essayons tout de suite avec notre route users.tsx.

(Le contenu du fichier ne change pas, seulement son nom)

app/routes/_users.tsx

_17
import { Link, Outlet } from '@remix-run/react';
_17
_17
export default function Users() {
_17
return (
_17
<div>
_17
<h1>Liste des utilisateurs</h1>
_17
<ul>
_17
{['Virgile', 'Cédric'].map((username) => (
_17
<Link to={`/${username}`} key={username}>
_17
{username}
_17
</Link>
_17
))}
_17
</ul>
_17
<Outlet />
_17
</div>
_17
);
_17
}

Il faut aussi modifier le fichier users.$username.tsx pour qu'il soit considéré comme "faisant partie du layout".

app/routes/_users.$username.tsx

_10
import { useParams } from '@remix-run/react';
_10
_10
export default function Username() {
_10
const username = useParams().username;
_10
return <h1>Salut {username} !</h1>;
_10
}

Maintenant, notre liste d'utilisateurs ne sera plus visible au chemin localhost:3000/users. Elle ne sera plus visible du coup, pas même à l'URL localhost:3000 (c'est la route _index.tsx qui s'affiche à la place).

Le détail de notre utilisateur sera cependant accessible à la route enfant localhost:3000/cedric, ainsi que le contneu de notre layout (la liste de nos deux utilisateurs)

Créer une route ressource (JSON, PDF, CSV ...) (type 5)

Vous vous souvenez de la route basique qu'on a créé en tout début de l'article ? Une route ressource est exactement pareil.

Il suffit de créer un fichier dans le dossier app/routes, mais au lieu d'exporter un composant React par défaut (notre vue), nous exportons une méthode nommée loader (pas besoin de l'exporter par défaut)

Essayons avec un exemple. Je souhaite afficher une image aléatoire à l'URL localhost:3000/image. Je vais donc récupérer mon image depuis le site picsum.photos

Il me suffit donc de créer un fichier nommé image.tsx (dans le dossier app/routes), puis d'exporter une fonction nommée loader Essayons voir.

app/routes/image.tsx

_10
export const loader = async () => {
_10
const response = await fetch('https://picsum.photos/200/300');
_10
const blob = await response.blob();
_10
return new Response(blob, {
_10
headers: {
_10
'Content-Type': 'image/jpeg',
_10
},
_10
});
_10
};

resource-route.gif

Je n'ai jamais créé une route API aussi facilement.

Créer une route 404 (type 6)

Nous allons maintenant créer notre dernier type de route, la fameuse page Erreur 404. Si vous lisez l'article depuis le début, vous comprendrez vite comment l'implémenter. Indice : C'est comme une route dynamique, mais le paramètre d'URL n'est pas nommé.

Il faut nommer le fichier $.tsx

Pour afficher une vue à n'importe quelle page que Remix n'identifie pas comme étant un chemin valide, il faut également exporter un composant React par défaut. Passons à l'implémentation.

app/routes/$.tsx

_11
import { useLocation } from '@remix-run/react';
_11
_11
export default function FourOhFour() {
_11
const location = useLocation();
_11
return (
_11
<h1 style={{ fontSize: 18 }}>
_11
Oops, on a pas trouvé la route{' '}
_11
<span style={{ color: 'GrayText' }}>{location.pathname}</span> !
_11
</h1>
_11
);
_11
}

Essayons un chemin pour voir. Au hasard, localhost:3000/youtube/abonnez-vous.

Route 404

Petites précisions :

  • Remix priorise les routes nommées. Si vous tapez localhost:3000/image dans l'URL, Remix va d'abord regarder les routes nommées, pas dynamiques (un match exact) avec le nom. C'est le cas pour nous avec le fichier image.tsx
  • Ensuite s'il ne trouve pas, il va chercher une route dynamique (avec le préfixe $). C'est le cas avec le fichier _users.$username.tsx, qui va matcher n'importe qu'elle URL à la place de l'étoile localhost:3000/*, à l'exception des routes nommées (exact match), et des routes imbriquées (plusieurs / (slash) dans l'URL)
  • Nous essayons d'accéder à la route localhost:3000/youtube/abonnez-vous, qui n'est donc pas un paramètre d'URL car il y a un /. On renvoie donc sur une page 404.

Conclusion

Nous venons de voir tous les types de page nécessaires pour vous permettre de créer des belles applications web sur mesure. Si vous voulez aller plus loin et configurer vous-même vos règles de routing (ou changer les préfixes, tels que ., $ et _, c'est possible. La librairie remix-flat-routes vous le permet, et je l'utilise dans tous mes projets !

Articles similaires
Gère les erreurs avec le framework Remix.js
6 minutes de lecture - 695 vuesRemixReactJS

Comment gérer les erreurs avec Remix ? (ErrorBoundary)

Avoir des erreurs Javascript ne fait jamais plaisir. Mais il existe le composant ErrorBoundary). Dans ce guide, tu vas découvrir comment afficher un composant d'erreur personnalisé en pour protéger toutes les pages de ton application.

Rejoins la

newsletter