Páginas y Layouts
Recomendamos leer las páginas Fundamentos de Enrutamiento y Definiendo Rutas antes de continuar.
Los archivos especiales layout.js, page.js, y template.js te permiten crear UI para una ruta. Esta página te guiará sobre cómo y cuándo usar estos archivos especiales.
Páginas
Una página es una UI única para una ruta. Puedes definir una página exportando por defecto un componente desde un archivo page.js
.
Por ejemplo, para crear tu página index
, añade el archivo page.js
dentro del directorio app
:

// `app/page.tsx` es la UI para la URL `/`
export default function Page() {
return <h1>¡Hola, página de inicio!</h1>
}
// `app/page.js` es la UI para la URL `/`
export default function Page() {
return <h1>¡Hola, página de inicio!</h1>
}
Luego, para crear más páginas, crea una nueva carpeta y añade el archivo page.js
dentro. Por ejemplo, para crear una página para la ruta /dashboard
, crea una carpeta llamada dashboard
, y añade el archivo page.js
dentro:
// `app/dashboard/page.tsx` es la UI para la URL `/dashboard`
export default function Page() {
return <h1>¡Hola, página de Dashboard!</h1>
}
// `app/dashboard/page.js` es la UI para la URL `/dashboard`
export default function Page() {
return <h1>¡Hola, página de Dashboard!</h1>
}
Bueno saber:
- Las extensiones de archivo
.js
,.jsx
, o.tsx
pueden usarse para Páginas.- Una página siempre es la hoja del subárbol de rutas.
- Se requiere un archivo
page.js
para hacer un segmento de ruta accesible públicamente.- Las páginas son Componentes de Servidor por defecto, pero pueden configurarse como Componentes de Cliente.
- Las páginas pueden obtener datos. Consulta la sección Obtención de Datos para más información.
Layouts
Un layout es una UI compartida entre múltiples rutas. En la navegación, los layouts preservan el estado, permanecen interactivos y no se vuelven a renderizar. Los layouts también pueden estar anidados.
Puedes definir un layout exportando por defecto un componente React desde un archivo layout.js
. El componente debe aceptar una prop children
que se llenará con un layout hijo (si existe) o una página durante el renderizado.
Por ejemplo, el layout se compartirá con las páginas /dashboard
y /dashboard/settings
:

export default function DashboardLayout({
children, // será una página o layout anidado
}: {
children: React.ReactNode
}) {
return (
<section>
{/* Incluye UI compartida aquí, como un encabezado o barra lateral */}
<nav></nav>
{children}
</section>
)
}
export default function DashboardLayout({
children, // será una página o layout anidado
}) {
return (
<section>
{/* Incluye UI compartida aquí, como un encabezado o barra lateral */}
<nav></nav>
{children}
</section>
)
}
Root Layout (Obligatorio)
El root layout se define en el nivel superior del directorio app
y se aplica a todas las rutas. Este layout es obligatorio y debe contener etiquetas html
y body
, permitiéndote modificar el HTML inicial devuelto desde el servidor.
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
{/* UI del Layout */}
<main>{children}</main>
</body>
</html>
)
}
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{/* UI del Layout */}
<main>{children}</main>
</body>
</html>
)
}
Anidando Layouts
Por defecto, los layouts en la jerarquía de carpetas están anidados, lo que significa que envuelven layouts hijos a través de su prop children
. Puedes anidar layouts añadiendo layout.js
dentro de segmentos de ruta específicos (carpetas).
Por ejemplo, para crear un layout para la ruta /dashboard
, añade un nuevo archivo layout.js
dentro de la carpeta dashboard
:

export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}
export default function DashboardLayout({ children }) {
return <section>{children}</section>
}
Si combinaras los dos layouts anteriores, el root layout (app/layout.js
) envolvería el layout del dashboard (app/dashboard/layout.js
), que a su vez envolvería los segmentos de ruta dentro de app/dashboard/*
.
Los dos layouts estarían anidados así:

Bueno saber:
- Las extensiones de archivo
.js
,.jsx
, o.tsx
pueden usarse para Layouts.- Solo el root layout puede contener etiquetas
<html>
y<body>
.- Cuando se definen archivos
layout.js
ypage.js
en la misma carpeta, el layout envolverá la página.- Los layouts son Componentes de Servidor por defecto pero pueden configurarse como Componentes de Cliente.
- Los layouts pueden obtener datos. Consulta la sección Obtención de Datos para más información.
- No es posible pasar datos entre un layout padre y sus hijos. Sin embargo, puedes obtener los mismos datos en una ruta más de una vez, y React deduplicará automáticamente las solicitudes sin afectar el rendimiento.
- Los layouts no tienen acceso a los segmentos de ruta debajo de sí mismos. Para acceder a todos los segmentos de ruta, puedes usar
useSelectedLayoutSegment
ouseSelectedLayoutSegments
en un Componente de Cliente.- Puedes usar Grupos de Rutas para incluir o excluir segmentos de ruta específicos de layouts compartidos.
- Puedes usar Grupos de Rutas para crear múltiples root layouts. Consulta un ejemplo aquí.
- Migrando desde el directorio
pages
: El root layout reemplaza los archivos_app.js
y_document.js
. Consulta la guía de migración.
Templates
Los templates son similares a los layouts en que envuelven cada layout hijo o página. A diferencia de los layouts que persisten entre rutas y mantienen el estado, los templates crean una nueva instancia para cada uno de sus hijos en la navegación. Esto significa que cuando un usuario navega entre rutas que comparten un template, se monta una nueva instancia del componente, se recrean los elementos DOM, el estado no se preserva y los efectos se resincronizan.
Puede haber casos donde necesites esos comportamientos específicos, y los templates serían una opción más adecuada que los layouts. Por ejemplo:
- Características que dependen de
useEffect
(ej. registro de visitas de página) yuseState
(ej. un formulario de feedback por página). - Para cambiar el comportamiento predeterminado del framework. Por ejemplo, los Suspense Boundaries dentro de layouts solo muestran el fallback la primera vez que se carga el Layout y no al cambiar páginas. Para templates, el fallback se muestra en cada navegación.
Un template puede definirse exportando por defecto un componente React desde un archivo template.js
. El componente debe aceptar una prop children
.

export default function Template({ children }: { children: React.ReactNode }) {
return <div>{children}</div>
}
export default function Template({ children }) {
return <div>{children}</div>
}
En términos de anidación, template.js
se renderiza entre un layout y sus hijos. Aquí hay una salida simplificada:
<Layout>
{/* Nota que al template se le da una clave única. */}
<Template key={routeParam}>{children}</Template>
</Layout>
Metadata
En el directorio app
, puedes modificar los elementos HTML <head>
como title
y meta
usando las APIs de Metadata.
La metadata puede definirse exportando un objeto metadata
o una función generateMetadata
en un archivo layout.js
o page.js
.
import { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Next.js',
}
export default function Page() {
return '...'
}
export const metadata = {
title: 'Next.js',
}
export default function Page() {
return '...'
}
Bueno saber: No debes añadir manualmente etiquetas
<head>
como<title>
y<meta>
a root layouts. En su lugar, debes usar la API de Metadata que maneja automáticamente requisitos avanzados como streaming y deduplicación de elementos<head>
.
Aprende más sobre las opciones de metadata disponibles en la referencia de API