Enrutamiento, Layouts (Diseños)

¿Qué son los Layouts en Nextjs?

Un layout es una interfaz de usuario que se comparte entre múltiples rutas. Al navegar, los layouts preservan el estado, permanecen interactivos y no se vuelven a renderizar. Los layouts también pueden anidarse.

Puedes definir un layout exportando por defecto un componente de 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, para desplegar un layout compartido entre las páginas /dashboard y /dashboard/settings/.

📁 app
    📁 dashboard
    📄 layout.tsx       Este es el layout
    📄 page.tsx
    📁 settings
        📄page.tsx

Ejemplo de implementación del layout.

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

            {children}
        </section>
    )
}

El valor de children es reutilizado, tanto por dashboard como por settings.

Layout del Root (Ruta principal)

El layout del root se define en el directorio app y se aplica a todas las ruta. Este layout es requerid y debe contener las etiquetas html y body, lo que permite modificar el HTML inicial retornado por el servidor.

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

Layouts anidados

Por default, los layouts son anidados según la jerarquía de los directorios. Por ejemplo, el layout del root, tiene prioridad sobre el del dashboard, y el del dashboard tiene prioridad sobre el de settings.

Para agregar un layout específico para el dashboard, hay que agregar

📁 app
    📄 layout.tsx               Aplica para todos los pages.
    📄 page.tsx
    📁 dashboard
        📄 layout.tsx           Aplica para dashboard y settings.
        📄 page.tsx
        📁 settings
            📄 layout.tsx
            📄 page.tsx         Aplica para settings.
export default function DashboardLayout({
    children,
}: {
    children: React.ReacNode
}) {
    return <section>{children}</section>
}

Templates (Plantillas)

Los templates son similares a los layouts en el sentido de que envuelven a los componentes hijos. A diferencia de los layouts que persisten a través de las rutas y mantienen su estado, los templates crean una nueva instancia para cada una de los children (hijos) durante la navegación. Esto quiere decir que cuando navegas entre las rutas que comparten un template, una nueva instancia del componente es creada cada que el componente es invocado.

Hay algunos casos en los cuales se requieren comportamientos específicos, en los cuales los templates son una mejor alternativa que los layouts. Por ejemplo:

  • Características que dependen de useEffect (por ejemplo vistas de la página) y useState (como un formulario de retroalimentación).

  • Para cambiar el comportamiento predeterminado del framework. Por ejemplo, los límites de Suspense dentro de los layouts solo muestran el fallback la primera vez que se carga el Layout y no al cambiar de página. Para las plantillas, el fallback se muestra en cada navegación.

Una plantilla puede ser definida exportando el componente React default desde template.tsx. El component debe aceptar el prop children.

📁 app
    📄 layout.tsx
    📄 template.tsx  <--
    📄 page.tsx
export default function Template({ children }: { children: React.ReactNode }) {
    return <div>{children}</div>
}

En términos de anidamiento, el template.tsx se despliega entre el layout y sus nodos hijos.

<Layout>
    <Template key={routeParam}>{children}</Template>
</Layout>

Metadata

En el directorio app, es posible modificar los elementos de la etiqueta <head>, como <title> y <meta> utilizando la API de Metadata.

El Metadata puede ser definido exportando el objeto metadata o la función generateMetadata dentro de layout.tsx o page.tsx.

// app/page.tsx
import { Metadata } from 'next'

export const metadata: Metadata = {
    title: 'Next.js',
}

export default function Page() {
    return '...'
}

No se deben agregar manualmente etiquetas como <title> o <meta> al <head> al layout del root. En lugar de eso, utilice la API del Metadata la cual maneja de manera automática los cambios requeridos.

Conclusiones

En resumen, Next.js layouts y templates son herramientas poderosas para crear aplicaciones web organizadas y eficientes. Los layouts permiten compartir interfaces de usuario entre múltiples rutas, preservando el estado y la interactividad, mientras que los templates crean nuevas instancias de componentes para cada navegación, siendo útiles en casos específicos como el manejo de useEffect y useState. Además, la API de Metadata facilita la modificación de elementos en la etiqueta <head>, mejorando la gestión del SEO y la personalización del contenido. Con estas características, Next.js ofrece una estructura robusta y flexible para el desarrollo frontend.

Otros Artículos