Lección 11. Layouts.

Los layouts en Next.js funcionan como cajas de envoltorio, donde podemos ingresar el page.tsx de nuestra ruta.

Recordemos que hasta el momento, únicamente hemos manejado un solo layout.tsx para toda nuestra aplicación, el cual es:

src/app/layout.tsx

Pero, Next.js permite colocar a cualquier ruta y page.tsx agregarle su propio layout.tsx.

Pruebas con layout.tsx._

Para comenzara entender como funcionan los layouts, veamos nuestro layout.tsx principal, es decir el src/app/layout.tsx:

Copiar código
// Importamos el tipo Metadata para definir los metadatos del sitio
import type { Metadata } from "next";

// Importamos dos fuentes desde Google Fonts usando el sistema de fuentes de Next.js
import { Geist, Geist_Mono } from "next/font/google";

// Importamos el archivo de estilos globales CSS
import "./globals.css";

// Cargamos la fuente Geist (sans serif) y le asignamos una variable CSS
const geistSans = Geist({
  variable: "--font-geist-sans", // Nombre de la variable CSS
  subsets: ["latin"],            // Subconjuntos de caracteres usados
});

// Cargamos la fuente Geist_Mono (monoespaciada) con su variable
const geistMono = Geist_Mono({
  variable: "--font-geist-mono",
  subsets: ["latin"],
});

// Definimos los metadatos del sitio (SEO, pestaña del navegador, etc.)
export const metadata: Metadata = {
  title: "Create Next App",                       // Título de la página
  description: "Generated by create next app",    // Descripción de la página
};

// Layout raíz de toda la aplicación (envuelve todas las páginas)
export default function RootLayout({
  children, // Recibe los componentes hijos (las páginas)
}: Readonly<{
  children: React.ReactNode; // Tipado estricto en TypeScript
}>) {
  return (
    // Define el idioma del documento HTML
    <html lang="en">
      <body
        // Aplicamos las variables de fuente como clases y usamos antialiasing para texto más suave
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        {children} {/* Renderizamos el contenido de cada página aquí */}
      </body>
    </html>
  );
}

O bien, podríamos tener, algo mas simple como:

Copiar código
// Exporta un objeto metadata que define metadatos para la página (título y descripción).
import type { Metadata } from "next";

// Estos metadatos se usan por Next.js para mejorar SEO y proporcionar información en el <head>.
export const metadata = {
  title: 'Next.js',                  // Título de la página
  description: 'Generated by Next.js' // Descripción de la página
}

// Componente raíz del layout. Next.js usa este componente para envolver todas las páginas.
// Aquí se define la estructura HTML base del sitio.
export default function RootLayout({
  children, // children representa el contenido específico de cada página
}: {
  children: React.ReactNode // Se indica que children debe ser un nodo válido de React (JSX, texto, otro componente, etc.)
}) {
  return (
    <html lang="en"> {/* Define el idioma principal del documento HTML */}
      <body>
        {children} {/* Renderiza aquí el contenido dinámico de cada página */}
      </body>
    </html>
  )
}

Nota: El children es el nodo del elemento a renderizar, como tal, los page.tsx definidos en el proyecto.

Modifiquemos el return a:

Copiar código
return (
  <html lang="en">
    <body>
      <header>
        Cabecera principal
      </header>
      {children}
      <footer>
        Pie de página principal
      </footer>
    </body>
  </html>
)

Ahora, intentemos navegar entre las rutas existentes.

El header y footer se mantienen entre paginas.

Nota: De este modo, los layout.tsx, son plantillas, a las cuales podemos ingresar estructuras generales, que mantendrán las paginas de las rutas de nuestra aplicación.

Anidación de layouts._

Sin embargo, no solo podemos tener un solo layout.tsx, bien podríamos colocarle a una pagina secundaria su propio layout.

Teniendo una estructura similar a:

Copiar código
|-.next/
|-node-modules/
|-public/
|-src/
  |-app/
    |-layout.tsx
    |-page.tsx
    |-login/
      |-page.tsx
    |-register/
      |-page.tsx
|- ...Otros archivos...

Crearemos dentro de login/ un layout.tsx para su propio page.tsx.

Colocándole el texto:

Copiar código
export default function LayoutLogin (
  {children} : {
    children: React.ReactNode
  }
) {
  return (
    <>
      <header>
        Cabecera de login
      </header>
      {children}
      <footer>
        Pie de página de login
      </footer>
    </>
  );
}

Si visitamos el /login/:

Si visitamos /register/:

Entonces, podemos decir que: