Retour • 09/12/2024
Le guide pour avoir des Intercepting Routes en Next.js qui fonctionnent
Écris par Melvyn Malherbe le 09/12/2024
Les Intercepting Routes en Next.js
sont très pratiques pour pouvoir afficher des Dialogs
au lieu d'afficher une page tout en gérant les informations de la page dans l'URL
.
Tu peux voir que quand je clique sur un des produits, ça m'affiche une Dialog
et que l'URL devient https://www.producthunt.com/posts/vela-os
.
Mais si tu vas directement sur l'URL sans passer par la page, tu vas tomber sur cette page :
Cette fois le produit est affiché en "plein écran" et n'est pas affiché dans la Dialog
comme précédemment. C'est la magie des intercepting routes justement.
Comment avoir la même chose en NextJS ?
Pour ça, on va utiliser le combo de 2 fonctionnalités :
- Intercepting Routes
- Parallel Routes
Les Parallel Routes permettent de définir des "segments" avec notamment @modal
par exemple afin de pouvoir injecter une "page" dans une autre page.
Les Intercepting Routes, elles, vont permettre de venir "intercepter" une requête quand elle est faite dans la navigation interne et d'afficher autre chose à la place, nous, on va justement afficher une Dialog
qui sera dans une "Parallel Route".
Étape 1 : Créer la Parallel Route
Imaginons qu'on veut afficher une Dialog
pour la route /login
au lieu d'afficher la page entière.
Pour ça, on va déjà créer la page standard :
// app/login/page.tsx
export default async function PostPage(props) {
return <div>Login</div>
}
Ensuite, on va pouvoir créer la Parallel Route :
// app/@modal/(.)login/page.tsx
export default async function LoginPage(props) {
return (
<InterceptingDialog>
<div>Login</div>
</InterceptingDialog>
)
}
Tu peux aussi créer le fichier InterceptingDialog.tsx
qui sera un client component qui vient faire router.back()
quand on clique sur le bouton de fermeture de la Dialog
.
// app/@modal/InterceptingDialog.tsx
"use client"
import { useRouter } from "next/navigation";
export default function InterceptingDialog({ children }: { children: React.ReactNode }) {
const router = useRouter();
return (
<Dialog onOpenChange={() => router.back()}>
{children}
</Dialog>
)
}
Et maintenant, il va falloir intégrer cette Parallel Route dans le layout.tsx
de notre application :
// app/layout.tsx
export default function RootLayout({
children,
modal
}: {
children: React.ReactNode,
modal: React.ReactNode
}) {
return (
<html>
<body>
{children}
{modal}
</body>
</html>
)
}
De cette manière, cette modal
va être "injectée" dans notre layout.tsx
si elle affiche quelque chose.
Si ça ne marche pas directement, tu peux relancer le serveur NextJS pour rafraîchir le layout.tsx
. J'ai eu quelques problèmes avec ça.
Étape 2 : Gérer les problèmes
Maintenant, avec le code qu'on a fait jusqu'à maintenant, ça ne va pas fonctionner correctement. Notamment, le fait de fermer la Dialog
ne va pas la fermer, elle va rester là. Aussi, quand on va sur des routes comme :
/login/test
La Dialog va aussi s'afficher alors qu'on ne veut qu'elle s'affiche uniquement sur /login
.
Pour régler ce problème, il faut ajouter 2 choses :
1. default.tsx
On va créer un fichier default.tsx
afin de pouvoir gérer les routes qui ne sont pas gérées par notre Parallel Route.
// app/@modal/default.tsx
export default function DefaultModal() {
return null;
}
2. Catch All
Ensuite, on va faire en sorte de venir "catch" toutes les routes qui ne sont pas gérées par notre Parallel Route avec ce qu'on appelle un "Catch All".
// app/@modal/[...catchAll]/page.tsx
export default function CatchAll() {
return null;
}
Ce petit bout de code vient faire en sorte que quand on change d'URL et qu'on va sur /login/test
, la page se ferme correctement 🎊
Conclusion
En suivant tout ceci, tu devrais avoir le comportement souhaité. Voici un Stackblitz fonctionnel qui suit ce que j'ai présenté :
Si tu veux devenir un pro de NextJS
pour créer des applications performantes et optimisées, tu peux te rendre sur ma formation NextJS gratuite.
Tu es très sûrement intéressé aussi par :
- Comprendre les API Routes en NextJS
- Comment bien utiliser Next-Safe-Action en NextJS
- Comment bien utiliser Next-Zod-Route pour les API Routes
On se retrouve là-bas,