codelynx.dev
🇫🇷🇬🇧

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.

Démonstration de l'intercepting route sur ProductHunt

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 :

Démonstration de l'intercepting route après un refresh

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 :

  1. Intercepting Routes
  2. 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 :

TSX
// app/login/page.tsx

export default async function PostPage(props) {
  return <div>Login</div>
}

Ensuite, on va pouvoir créer la Parallel Route :

TSX
// 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.

TSX
// 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 :

TSX
// 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.

TSX
// 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".

TSX
// 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 :

On se retrouve là-bas,

NextReact

Cours NextJS gratuit

Accède à des exercices, des vidéos et bien plus sur NextJS dans la formation "NextReact" 👇