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.
Navegación y Estado Activo
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:
- Definir la Estructura de Archivos:
mkdir -p app/@team app/@analytics
touch app/@team/page.tsx app/@analytics/page.tsx app/layout.tsx
- 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}
</>
)
}
- 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.