Routes parallèles
Le routage parallèle vous permet d'afficher simultanément ou conditionnellement une ou plusieurs pages dans la même mise en page. Pour les sections hautement dynamiques d'une application, comme les tableaux de bord et les flux sur les réseaux sociaux, le routage parallèle peut être utilisé pour implémenter des modèles de routage complexes.
Par exemple, vous pouvez afficher simultanément les pages d'équipe et d'analytique.

Le routage parallèle vous permet de définir des états d'erreur et de chargement indépendants pour chaque route, car elles sont diffusées indépendamment.

Le routage parallèle vous permet également d'afficher conditionnellement un emplacement (slot) en fonction de certaines conditions, comme l'état d'authentification. Cela permet d'avoir un code entièrement séparé sur la même URL.

Convention
Les routes parallèles sont créées à l'aide d'emplacements nommés (named slots). Les emplacements sont définis avec la convention @dossier
et sont passés à la mise en page de même niveau en tant que props.
Les emplacements ne sont pas des segments de route et n'affectent pas la structure de l'URL. Le chemin de fichier
/@team/members
serait accessible via/members
.
Par exemple, la structure de fichiers suivante définit deux emplacements explicites : @analytics
et @team
.

La structure de dossiers ci-dessus signifie que le composant dans app/layout.js
accepte maintenant les props d'emplacement @analytics
et @team
, et peut les afficher en parallèle avec la prop children
:
export default function Layout(props: {
children: React.ReactNode
analytics: React.ReactNode
team: React.ReactNode
}) {
return (
<>
{props.children}
{props.team}
{props.analytics}
</>
)
}
export default function Layout(props) {
return (
<>
{props.children}
{props.team}
{props.analytics}
</>
)
}
Bon à savoir : La prop
children
est un emplacement implicite qui n'a pas besoin d'être mappé à un dossier. Cela signifie queapp/page.js
est équivalent àapp/@children/page.js
.
Routes non correspondantes
Par défaut, le contenu affiché dans un emplacement correspond à l'URL actuelle.
Dans le cas d'un emplacement non correspondant, le contenu affiché par Next.js diffère selon la technique de routage et la structure des dossiers.
default.js
Vous pouvez définir un fichier default.js
à afficher comme solution de repli lorsque Next.js ne peut pas récupérer l'état actif d'un emplacement en fonction de l'URL actuelle.
Considérez la structure de dossiers suivante. L'emplacement @team
a un répertoire settings
, mais pas @analytics
.

Navigation
Lors de la navigation, Next.js affichera l'état actif précédent de l'emplacement, même s'il ne correspond pas à l'URL actuelle.
Rechargement
Lors d'un rechargement, Next.js essaiera d'abord d'afficher le fichier default.js
de l'emplacement non correspondant. Si celui-ci n'est pas disponible, une 404 est affichée.
La 404 pour les routes non correspondantes permet de s'assurer que vous n'affichez pas accidentellement une route qui ne devrait pas être affichée en parallèle.
useSelectedLayoutSegment(s)
Les fonctions useSelectedLayoutSegment
et useSelectedLayoutSegments
acceptent une parallelRoutesKey
, qui vous permet de lire le segment de route actif dans cet emplacement.
'use client'
import { useSelectedLayoutSegment } from 'next/navigation'
export default async function Layout(props: {
//...
auth: React.ReactNode
}) {
const loginSegments = useSelectedLayoutSegment('auth')
// ...
}
'use client'
import { useSelectedLayoutSegment } from 'next/navigation'
export default async function Layout(props) {
const loginSegments = useSelectedLayoutSegment('auth')
// ...
}
Lorsqu'un utilisateur navigue vers @auth/login
, ou /login
dans la barre d'URL, loginSegments
sera égal à la chaîne "login"
.
Exemples
Modales
Le routage parallèle peut être utilisé pour afficher des modales.

L'emplacement @auth
affiche un composant <Modal>
qui peut être montré en naviguant vers une route correspondante, par exemple /login
.
export default async function Layout(props: {
// ...
auth: React.ReactNode
}) {
return (
<>
{/* ... */}
{props.auth}
</>
)
}
export default async function Layout(props) {
return (
<>
{/* ... */}
{props.auth}
</>
)
}
import { Modal } from 'components/modal'
export default function Login() {
return (
<Modal>
<h1>Connexion</h1>
{/* ... */}
</Modal>
)
}
import { Modal } from 'components/modal'
export default function Login() {
return (
<Modal>
<h1>Connexion</h1>
{/* ... */}
</Modal>
)
}
Pour vous assurer que le contenu de la modale ne s'affiche pas lorsqu'elle n'est pas active, vous pouvez créer un fichier default.js
qui retourne null
.
export default function Default() {
return null
}
export default function Default() {
return null
}
Fermer une modale
Si une modale a été initiée via une navigation côté client, par exemple en utilisant <Link href="/login">
, vous pouvez fermer la modale en appelant router.back()
ou en utilisant un composant Link
.
'use client'
import { useRouter } from 'next/navigation'
import { Modal } from 'components/modal'
export default async function Login() {
const router = useRouter()
return (
<Modal>
<span onClick={() => router.back()}>Fermer la modale</span>
<h1>Connexion</h1>
...
</Modal>
)
}
'use client'
import { useRouter } from 'next/navigation'
import { Modal } from 'components/modal'
export default async function Login() {
const router = useRouter()
return (
<Modal>
<span onClick={() => router.back()}>Fermer la modale</span>
<h1>Connexion</h1>
...
</Modal>
)
}
Plus d'informations sur les modales sont couvertes dans la section Interception de routes.
Si vous souhaitez naviguer ailleurs et fermer une modale, vous pouvez également utiliser une route attrape-tout (catch-all).

export default function CatchAll() {
return null
}
export default function CatchAll() {
return null
}
Les routes attrape-tout ont priorité sur
default.js
.
Routes conditionnelles
Les routes parallèles peuvent être utilisées pour implémenter un routage conditionnel. Par exemple, vous pouvez afficher une route @dashboard
ou @login
en fonction de l'état d'authentification.
import { getUser } from '@/lib/auth'
export default function Layout({
dashboard,
login,
}: {
dashboard: React.ReactNode
login: React.ReactNode
}) {
const isLoggedIn = getUser()
return isLoggedIn ? dashboard : login
}
import { getUser } from '@/lib/auth'
export default function Layout({ dashboard, login }) {
const isLoggedIn = getUser()
return isLoggedIn ? dashboard : login
}

Gestion des erreurs
Gérez les erreurs d'exécution en englobant automatiquement les segments de route et leurs enfants dans une limite d'erreur (Error Boundary) React.
Routes d'interception
Utilisez les routes d'interception pour charger une nouvelle route dans la mise en page actuelle tout en masquant l'URL du navigateur, utile pour des motifs de routage avancés comme les modales.