Parallel Routes en React/Next.js

March 12, 2024

En el mundo del desarrollo web, Next.js sigue evolucionando para ofrecer soluciones avanzadas que mejoran la experiencia de los desarrolladores y usuarios. Una de estas innovaciones son las Parallel Routes, una característica que permite renderizar múltiples páginas simultáneamente en la misma vista. En este post, exploraremos qué son las Parallel Routes, por qué son útiles y cómo implementarlas en tus aplicaciones Next.js.

¿Qué son las Parallel Routes?

Las Parallel Routes permiten renderizar de manera simultánea o condicional varias páginas dentro de un mismo layout. Son especialmente útiles para secciones altamente dinámicas de una aplicación, como dashboards y feeds en redes sociales.

Imagina un dashboard donde quieres mostrar simultáneamente las páginas de equipo y analíticas. Las Parallel Routes permiten gestionar esto de forma efectiva, manteniendo un diseño cohesivo y dinámico.

Creación de Parallel Routes

Definición de Slots

Las Parallel Routes se crean utilizando slots nombrados, definidos con la convención @folder. A continuación, un ejemplo de estructura de archivos que define dos slots: @analytics y @team:

app/
  ├── layout.tsx
  ├── page.tsx
  ├── @analytics/
     └── page.tsx
  └── @team/
      └── page.tsx

El archivo layout.tsx del directorio app acepta estos slots como props y los renderiza en paralelo junto con el prop children.

Ejemplo Práctico

app/layout.tsx

export default function Layout({
  children,
  team,
  analytics,
}: {
  children: React.ReactNode
  analytics: React.ReactNode
  team: React.ReactNode
}) {
  return (
    <>
      {children}
      {team}
      {analytics}
    </>
  )
}

En este ejemplo, children, team y analytics son renderizados en paralelo, pero no afectan la estructura de la URL.

Next.js mantiene el estado activo de cada slot. Dependiendo del tipo de navegación (suave o dura), el contenido dentro de un slot puede cambiar mientras mantiene el estado activo de otros slots.

Soft Navigation

Durante la navegación del lado del cliente, Next.js realiza un renderizado parcial, cambiando la subpágina dentro del slot, manteniendo el estado activo de los otros slots.

Hard Navigation

Después de una carga completa de página (refresco del navegador), Next.js no puede determinar el estado activo de los slots que no coinciden con la URL actual. En su lugar, renderiza un archivo default.js para los slots no coincidentes, o un 404 si default.js no existe.

Ejemplo con Estado Activo

app/@team/page.tsx

export default function Team() {
  return <div>Team Page</div>
}

app/@analytics/page.tsx

export default function Analytics() {
  return <div>Analytics Page</div>
}

Con esta estructura, al navegar a /settings, el slot @team renderiza la página de configuración mientras mantiene la página activa actual para el slot @analytics.

Slots como Props

Los slots son pasados como props al layout compartido. En el ejemplo anterior, el componente en app/layout.tsx ahora acepta los props @analytics y @team, y puede renderizarlos en paralelo junto con el prop children.

Este enfoque es útil para dividir y organizar el contenido de una aplicación de manera modular, permitiendo que diferentes secciones de la página se actualicen y rendericen independientemente.

Implementación de Slots

Para implementar slots en un proyecto Next.js, sigue estos pasos:

  1. Definir la Estructura de Archivos:
mkdir -p app/@team app/@analytics
touch app/@team/page.tsx app/@analytics/page.tsx app/layout.tsx
  1. Configurar el Layout:
// app/layout.tsx
export default function Layout({
  children,
  team,
  analytics,
}: {
  children: React.ReactNode
  analytics: React.ReactNode
  team: React.ReactNode
}) {
  return (
    <>
      {children}
      {team}
      {analytics}
    </>
  )
}
  1. Crear las Páginas para los Slots:
// app/@team/page.tsx
export default function Team() {
  return <div>Team Page</div>
}

// app/@analytics/page.tsx
export default function Analytics() {
  return <div>Analytics Page</div>
}

Active State y Navegación

Por defecto, Next.js realiza un seguimiento del estado activo (o subpágina) para cada slot. El contenido renderizado dentro de un slot dependerá del tipo de navegación:

Soft Navigation

Durante la navegación del lado del cliente, Next.js realiza un renderizado parcial, cambiando la subpágina dentro del slot, mientras mantiene las subpáginas activas de otros slots, incluso si no coinciden con la URL actual.

Hard Navigation

Después de una carga completa de página (refresco del navegador), Next.js no puede determinar el estado activo de los slots que no coinciden con la URL actual. En su lugar, renderiza un archivo default.js para los slots no coincidentes, o un 404 si default.js no existe.

Ejemplo con Navegación

Considera la siguiente estructura de archivos:

app/
  ├── layout.tsx
  ├── page.tsx
  ├── @team/
     ├── page.tsx
     └── default.tsx
  └── @analytics/
      ├── page.tsx
      └── default.tsx

app/@team/default.tsx

export default function Default() {
  return <div>Default Team Content</div>
}

app/@analytics/default.tsx

export default function Default() {
  return <div>Default Analytics Content</div>
}

Cuando navegues a /dashboard, Next.js renderizará las páginas por defecto para los slots @team y @analytics si no puede determinar su estado activo.

Ejemplos Avanzados

Rutas Condicionales

Puedes usar Parallel Routes para renderizar rutas condicionalmente basadas en ciertos criterios, como el rol de un usuario. Por ejemplo, para renderizar una página de dashboard diferente para los roles admin o user:

// app/dashboard/layout.tsx
import { checkUserRole } from '@/lib/auth'

export default function Layout({
  user,
  admin,
}: {
  user: React.ReactNode
  admin: React.ReactNode
}) {
  const role = checkUserRole()
  return <>{role === 'admin' ? admin : user}</>
}

Grupos de Pestañas

Puedes añadir un layout dentro de un slot para permitir que los usuarios naveguen de manera independiente dentro del slot. Esto es útil para crear pestañas.

Por ejemplo, el slot @analytics tiene dos subpáginas: /page-views y /visitors.

// app/@analytics/layout.tsx
import Link from 'next/link'

export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <nav>
        <Link href="/page-views">Page Views</Link>
        <Link href="/visitors">Visitors</Link>
      </nav>
      <div>{children}</div>
    </>
  )
}

Modales

Las Parallel Routes pueden usarse junto con Intercepting Routes para crear modales. Esto permite resolver desafíos comunes al construir modales, como:

  • Hacer que el contenido del modal sea compartible a través de una URL.
  • Preservar el contexto cuando la página se refresca, en lugar de cerrar el modal.
  • Cerrar el modal en la navegación hacia atrás en lugar de ir a la ruta anterior.
  • Reabrir el modal en la navegación hacia adelante.
// app/login/page.tsx
import { Login } from '@/app/ui/login'

export default function Page() {
  return <Login />
}

// app/@auth/default.tsx
export default function Default() {
  return null
}

// app/@auth/(.)login/page.tsx
import { Modal } from '@/app/ui/modal'
import { Login } from '@/app/ui/login'

export default function Page() {
  return (
    <Modal>
      <Login />
    </Modal>
  )
}

// app/layout.tsx
import Link from 'next/link'

export default function Layout({
  auth,
  children,
}: {
  auth: React.ReactNode
  children: React.ReactNode
}) {
  return (
    <>
      <nav>
        <Link href="/login">Open modal</Link>
      </nav>
      <div>{auth}</div>
      <div>{children}</div>
    </>
  )
}

// app/ui/modal.tsx
'use client'

import { useRouter } from 'next/navigation'

export function Modal({ children }: { children: React.ReactNode }) {
  const router= useRouter()

  return (


 <>
      <button
        onClick={()=> {
          router.back()
        }}
      >
        Close modal
      </button>
      <div>{children}</div>
    </>
  )
}

Conclusión

Las Parallel Routes en Next.js ofrecen una forma poderosa de gestionar secciones dinámicas en aplicaciones complejas, mejorando la experiencia del usuario y la eficiencia del desarrollo. Al permitir la renderización simultánea de múltiples componentes, proporcionan una solución elegante para dashboards y otras interfaces de usuario altamente interactivas.

Implementar Parallel Routes puede parecer complicado al principio, pero con práctica, se convertirá en una herramienta invaluable en tu arsenal de desarrollo Next.js. ¡Explora esta funcionalidad y lleva tus aplicaciones al siguiente nivel!

Espero que este post te sea útil para entender y aplicar las Parallel Routes en tus proyectos con React y Next.js.