layout.js

Un layout es una interfaz de usuario compartida entre rutas.

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

Un root layout (diseño raíz) es el layout superior en el directorio raíz app. Se utiliza para definir las etiquetas <html> y <body> y otros elementos de interfaz compartidos globalmente.

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 (requerido)

Los componentes de layout deben aceptar y usar una prop children. Durante el renderizado, children se llenará con los segmentos de ruta que el layout está envolviendo. Estos serán principalmente el componente de un Layout hijo (si existe) o Page, pero también podrían ser otros archivos especiales como Loading o Error cuando corresponda.

params (opcional)

El objeto de parámetros de ruta dinámica desde el segmento raíz hasta ese layout.

EjemploURLparams
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'] }

Por ejemplo:

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>
}

Bueno saber

Los layouts no reciben searchParams

A diferencia de las Pages, los componentes Layout no reciben la prop searchParams. Esto se debe a que un layout compartido no se vuelve a renderizar durante la navegación, lo que podría generar searchParams obsoletos entre navegaciones.

Al usar navegación del lado del cliente, Next.js automáticamente solo renderiza la parte de la página debajo del layout común entre dos rutas.

Por ejemplo, en la siguiente estructura de directorios, dashboard/layout.tsx es el layout común tanto para /dashboard/settings como para /dashboard/analytics:

Estructura de archivos mostrando una carpeta dashboard que contiene un archivo layout.tsx, y carpetas settings y analytics con sus propias páginas

Al navegar de /dashboard/settings a /dashboard/analytics, page.tsx en /dashboard/analytics se volverá a renderizar en el servidor, mientras que dashboard/layout.tsx no se volverá a renderizar porque es una interfaz compartida entre ambas rutas.

Esta optimización de rendimiento permite que la navegación entre páginas que comparten un layout sea más rápida, ya que solo se debe ejecutar la obtención de datos y el renderizado de la página, en lugar de toda la ruta que podría incluir layouts compartidos que obtienen sus propios datos.

Debido a que dashboard/layout.tsx no se vuelve a renderizar, la prop searchParams en el componente de servidor del layout podría volverse obsoleta después de la navegación.

  • En su lugar, use la prop searchParams de Page o el hook useSearchParams en un componente del cliente, que se vuelve a renderizar en el cliente con los últimos searchParams.

Root Layouts (Diseños raíz)

  • El directorio app debe incluir un app/layout.js raíz.
  • El root layout debe definir las etiquetas <html> y <body>.
    • No debe agregar manualmente etiquetas <head> como <title> y <meta> a los root layouts. En su lugar, debe usar la API de Metadata que maneja automáticamente requisitos avanzados como streaming y desduplicación de elementos <head>.
  • Puede usar route groups para crear múltiples root layouts.
    • Navegar entre múltiples root layouts causará una recarga completa de página (en lugar de una navegación del lado del cliente). Por ejemplo, navegar desde /cart que usa app/(shop)/layout.js a /blog que usa app/(marketing)/layout.js causará una recarga completa de página. Esto solo aplica para múltiples root layouts.

Historial de versiones

VersiónCambios
v13.0.0Se introdujo layout.