layout.js

Un layout est une interface utilisateur partagée entre plusieurs routes.

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return <section>{children}</section>
}
export default function DashboardLayout({ children }) {
  return <section>{children}</section>
}

Un root layout (layout racine) est le layout le plus haut dans le répertoire racine app. Il est utilisé pour définir les balises <html> et <body> ainsi que d'autres éléments d'interface partagés globalement.

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

Props

children (requis)

Les composants de layout doivent accepter et utiliser une prop children. Pendant le rendu, children sera rempli avec les segments de route que le layout englobe. Il s'agira principalement du composant d'un Layout enfant (s'il existe) ou d'une Page, mais peut aussi inclure d'autres fichiers spéciaux comme Loading ou Error le cas échéant.

params (optionnel)

L'objet des paramètres de route dynamiques depuis le segment racine jusqu'à ce layout.

ExempleURLparams
app/dashboard/[team]/layout.js/dashboard/1{ team: '1' }
app/shop/[tag]/[item]/layout.js/shop/1/2{ tag: '1', item: '2' }
app/blog/[...slug]/layout.js/blog/1/2{ slug: ['1', '2'] }

Exemple :

export default function ShopLayout({
  children,
  params,
}: {
  children: React.ReactNode
  params: {
    tag: string
    item: string
  }
}) {
  // URL -> /shop/shoes/nike-air-max-97
  // `params` -> { tag: 'shoes', item: 'nike-air-max-97' }
  return <section>{children}</section>
}
export default function ShopLayout({ children, params }) {
  // URL -> /shop/shoes/nike-air-max-97
  // `params` -> { tag: 'shoes', item: 'nike-air-max-97' }
  return <section>{children}</section>
}

Bon à savoir

Les layouts ne reçoivent pas searchParams

Contrairement aux Pages, les composants Layout ne reçoivent pas la prop searchParams. Cela est dû au fait qu'un layout partagé n'est pas re-rendu pendant la navigation, ce qui pourrait entraîner des searchParams obsolètes entre les navigations.

Lors de l'utilisation de la navigation côté client, Next.js ne rend automatiquement que la partie de la page située sous le layout commun entre deux routes.

Par exemple, dans la structure de répertoire suivante, dashboard/layout.tsx est le layout commun pour /dashboard/settings et /dashboard/analytics :

app
└── dashboard
    ├── layout.tsx
    ├── settings
    │   └── page.tsx
    └── analytics
        └── page.js

Lors de la navigation de /dashboard/settings vers /dashboard/analytics, page.tsx dans /dashboard/analytics sera rendu côté serveur car c'est l'interface qui a changé, tandis que dashboard/layout.tsx ne sera pas re-rendu car c'est une interface commune aux deux routes.

Cette optimisation de performance permet une navigation plus rapide entre les pages partageant un layout, car seules les opérations de récupération de données et de rendu pour la page doivent être exécutées, au lieu de l'ensemble de la route qui pourrait inclure des layouts partagés avec leurs propres données.

Comme dashboard/layout.tsx ne se re-rend pas, la prop searchParams dans le composant serveur du layout peut devenir obsolète après la navigation.

  • Utilisez plutôt la prop searchParams de la Page ou le hook useSearchParams dans un composant client, qui est re-rendu côté client avec les derniers searchParams.

Root Layouts (Layouts racines)

  • Le répertoire app doit inclure un app/layout.js racine.
  • Le layout racine doit définir les balises <html> et <body>.
    • Vous ne devriez pas ajouter manuellement des balises <head> comme <title> et <meta> aux layouts racines. Utilisez plutôt l'API Metadata qui gère automatiquement les besoins avancés comme le streaming et la déduplication des éléments <head>.
  • Vous pouvez utiliser des groupes de routes pour créer plusieurs layouts racines.
    • Naviguer entre plusieurs layouts racines entraînera un rechargement complet de la page (par opposition à une navigation côté client). Par exemple, naviguer de /cart qui utilise app/(shop)/layout.js vers /blog qui utilise app/(marketing)/layout.js entraînera un rechargement complet. Cela s'applique uniquement aux multiples layouts racines.

Historique des versions

VersionChangements
v13.0.0Introduction de layout.