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 layout 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. Principalmente será el componente de un Layout hijo (si existe) o una Página, 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 Páginas, 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.

Cuando se usa 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 para /dashboard/settings y /dashboard/analytics:

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

Al navegar de /dashboard/settings a /dashboard/analytics, page.tsx en /dashboard/analytics se renderizará en el servidor porque es la interfaz que cambió, mientras que dashboard/layout.tsx no se volverá a renderizar porque es una interfaz común 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 debe ejecutarse 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.

Como 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 la Página o el hook useSearchParams en un componente de cliente, que se vuelve a renderizar en el cliente con los searchParams más recientes.

Layouts raíz

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

Historial de versiones

VersiónCambios
v13.0.0Se introdujo layout.