
🔍 ¿Qué es un Router en Next.js?
Un router es el sistema que determina cómo se manejan las URLs de tu aplicación y qué componentes se renderizan cuando el usuario accede a una ruta específica. En Next.js, cada archivo dentro de las carpetas de routing corresponde automáticamente a una ruta en tu aplicación. Por ejemplo, si creas un archivo about.js dentro de /pages, este será accesible en /about.
El router es fundamental porque define la estructura de navegación, los layouts (diseños compartidos), la gestión de estados de carga y la optimización del rendimiento de tu aplicación. Elegir el router adecuado desde el inicio de un proyecto te ahorrará refactorizaciones costosas más adelante.
📂 Pages Router: El Enfoque Tradicional
El Pages Router ha sido el sistema de enrutamiento de Next.js desde sus inicios. Utiliza el directorio /pages donde cada archivo representa una ruta. Este enfoque es intuitivo y fácil de entender: simplemente creas archivos y obtienes rutas automáticamente.
Características principales del Pages Router:
- Enrutamiento basado en archivos: Cada archivo
.js,.jsx,.tso.tsxen/pagesse convierte en una ruta. - Renderizado del lado del cliente por defecto: Usa React hooks como
useEffectyuseStatedirectamente. - API Routes integrada: Puedes crear endpoints de API en
/pages/api. - getServerSideProps: Para renderizado del lado del servidor por solicitud.
- getStaticProps: Para generación estática en tiempo de compilación.
- getStaticPaths: Para generación de rutas estáticas dinámicas.
// pages/index.js
export default function Home() {
return (
Bienvenido a mi sitio
Usando Pages Router
);
}
// pages/about.js
export default function About() {
return (
Acerca de nosotros
Página estática con Pages Router
);
}
// pages/blog/[slug].js - Ruta dinámica
export default function BlogPost({ post }) {
return (
{post.title}
{post.content}
);
}
export async function getStaticPaths() {
const posts = await fetchPosts();
return {
paths: posts.map((post) => ({
params: { slug: post.slug },
})),
fallback: false,
};
}
export async function getStaticProps({ params }) {
const post = await fetchPostBySlug(params.slug);
return { props: { post } };
}
🆕 App Router: La Nueva Era del Enrutamiento
El App Router (introducido en Next.js 13 como beta y estabilizado en Next.js 14) revoluciona la forma de construir aplicaciones. Utiliza el directorio /app y aprovecha los React Server Components (RSC), permitiendo renderizado híbrido y optimizado.
Características principales del App Router:
- React Server Components: Los componentes se renderizan en el servidor por defecto, reduciendo el JavaScript enviado al cliente.
- Nested Layouts: Permite crear diseños anidados que persisten entre navegaciones sin recargar la página.
- Streaming: Soporte nativo para Suspense y streaming de HTML.
- Server Actions: Funciones que se ejecutan en el servidor y pueden ser llamadas desde el cliente.
- Loading.js y Error.js: Archivos especiales para estados de carga y errores por ruta.
- Mejor manejo de datos: Patrones más limpios para obtener ymutar datos.
// app/layout.js - Layout raíz
export default function RootLayout({ children }) {
return (
Inicio
Acerca de
{children}
);
}
// app/page.js - Página de inicio
export default function Home() {
return (
Bienvenido a mi sitio
Usando App Router con React Server Components
);
}
// app/blog/[slug]/page.js - Ruta dinámica
export default async function BlogPost({ params }) {
const post = await fetchPostBySlug(params.slug);
return (
{post.title}
{post.content}
);
}
// app/blog/[slug]/loading.js - Estado de carga
export default function Loading() {
return Cargando artículo...;
}
// app/blog/[slug]/error.js - Manejo de errores
export default function Error({ error }) {
return Error: {error.message};
}
// app/api/posts/route.js - API Route (opcional en App Router)
export async function GET() {
const posts = await fetchPosts();
return Response.json(posts);
}
// app/actions.js - Server Actions
export async function createPost(formData) {
'use server';
const title = formData.get('title');
await savePost({ title });
revalidatePath('/blog');
}
/pages y /app coexistiendo, aunque esto no es recomendado para nuevos proyectos. La carpeta /app tiene prioridad sobre /pages.⚡ Comparación Detallada: Pages Router vs App Router
| Característica | Pages Router | App Router |
|---|---|---|
| Directorio | /pages |
/app |
| Renderizado por defecto | Cliente (CSR) | Servidor (RSC) |
| Componentes de servidor | No disponibles | Soportados nativamente |
| Obtención de datos | getStaticProps, getServerSideProps | async/await directo en componentes |
| Layouts anidados | Limitado (usando _app.js) | Native y flexibles |
| Manejo de estados de carga | Componentes Loading convencionales | loading.js por ruta |
| Server Actions | No disponibles | Soportadas |
| Tamaño del bundle | Mayor (más JavaScript al cliente) | Menor (server components no se envían) |
| Caché de datos | Configuración manual | Configuración simple con fetch |
| Middleware | Requiere configuración adicional | Integrado con matcher |
| SEO | Bueno para páginas estáticas | Mejorado con server components |
| Curva de aprendizaje | Baja | Moderada (nuevos conceptos) |
🎯 ¿Cuándo Usar Cada Router?
Usa el Pages Router cuando:
- Proyecto existente: Ya tienes una aplicación funcionando con Pages Router y migrar sería costoso.
- Simplicidad requerida: Tu equipo está más familiarizado con React tradicional y hooks.
- Prototipado rápido: Necesitas crear un prototipo funcional rápidamente sin aprender nuevos patrones.
- Recursos educativos limitados: Documentación o tutoriales específicos para Pages Router son más abundantes.
- Requisitos de middleware complejos: Ya tienes middleware configurado que迁移 sería problemático.
Usa el App Router cuando:
- Nuevo proyecto: Estás iniciando una aplicación desde cero.
- Rendimiento óptimo: Necesitas el menor tamaño de bundle posible.
- Acceso a base de datos directo: Quieres consultar APIs o bases de datos directamente en componentes.
- Experiencia de usuario fluida: Necesitas layouts persistentes y transiciones suaves.
- Server Actions: Quieresmutaciones de datos sin crear endpoints API separados.
- Preparación para el futuro: Quieres usar las últimas características de React y Next.js.
Si decides migrar tu proyecto existente, aquí te explico el proceso general:
- Crea el directorio /app: Añade
/appjunto a tu/pagesexistente. - Mueve tus componentes: Copia cada página de
/pagesa/appcon el mismo nombre. - Convierte getServerSideProps: Convierte a async/await directo en el componente.
- Convierte getStaticProps: Usa fetch con opciones de cache o async/await directo.
- Refactoriza _app.js: Crea
/app/layout.jscon el contenido del layout raíz. - Mueve _document.js: Usa
/app/layout.jscon el HTML completo. - Actualiza API routes: Mueve a
/app/api/[ruta]/route.jscon handlers GET, POST, etc. - Añade archivos especiales: Crea
loading.js,error.jsdonde sea necesario. - Prueba exhaustivamente: Verifica cada ruta y funcionalidad.
- Elimina /pages: Una vez todo funcione, elimina el directorio
/pages.
Durante la migración, puedes ejecutar ambos routers simultáneamente para validar funcionalidades incrementalmente.
Los React Server Components (RSC) son una de las características más revolucionarias del App Router. Aquí algunos puntos clave:
- Ejecución en servidor: Los Server Components se ejecutan solo en el servidor, enviando HTML al cliente.
- Acceso directo a datos: Pueden hacerfetch a bases de datos o APIs internamente sin exponer credenciales.
- Tamaño de bundle cero: El código del servidor no se incluye en el JavaScript del cliente.
- No pueden usar hooks: No pueden usar useState, useEffect, etc.
- Composición flexible: Puedes usar Client Components dentro de Server Components.
Para convertir un Server Component a Client Component, simplemente añade 'use client' al inicio del archivo. Sin embargo, hazlo solo cuando sea necesario, ya que esto incluye el componente en el bundle del cliente.
🛠️ Ejemplo Práctico: Obtención de Datos
Veamos cómo difiere la obtención de datos entre ambos routers con un ejemplo real de una lista de productos:
Con Pages Router:
// pages/products/index.js
import useSWR from 'swr';
function ProductsPage() {
const { data, error } = useSWR('/api/products', fetcher);
if (error) return Error al cargar productos;
if (!data) return Cargando...;
return (
{data.map(product => (
- {product.name}
))}
);
}
// pages/api/products.js
export default async function handler(req, res) {
const products = await db.getProducts();
res.status(200).json(products);
}
Con App Router:
// app/products/page.js
async function ProductsPage() {
// Obtención directa de datos - sin API route necesario
const products = await db.getProducts();
return (
{products.map(product => (
- {product.name}
))}
);
}
// Si necesitasmutaciones, usa Server Actions:
// app/actions.js
export async function createProduct(formData) {
'use server';
const name = formData.get('name');
await db.createProduct({ name });
revalidatePath('/products');
}
📊 Impacto en el Rendimiento
El App Router puede proporcionar mejoras significativas en varias métricas:
- Tamaño del bundle JavaScript: Hasta un 30-40% menos de JavaScript enviado al cliente gracias a Server Components.
- Tiempo de carga inicial: Menos JavaScript significa parseo más rápido y menor TTI (Time to Interactive).
- Caché más eficiente: El sistema de caché del App Router es más granular y predecible.
- SEO mejorado: El contenido llega pre-renderizado desde el servidor.
- Streaming efectivo: Puedes enviar partes de la página según estén listas.
"La elección del router no es solo una decisión técnica, es una declaración de cómo quieres construir y escalar tu aplicación."
🔮 El Futuro de Next.js
Next.js está evolucionando rápidamente y el App Router es el centro de esta evolución. Las próximas características incluyen:
- Partial Prerendering (PPR): Combina contenido estático y dinámico automáticamente.
- Mejoras en Server Actions: Más controles y mejor integración con formularios.
- Cache invalidation más granular: Control preciso sobre qué se cachea y cuándo.
- Mejoras en streaming: Mejor experiencia de carga progresiva.
📝 Resumen y Recomendación Final
Ambas opciones son válidas y capaces de construir aplicaciones web modernas. Sin embargo, para la mayoría de los casos de uso modernos, el App Router es la elección recomendada porque:
- Ofrece mejor rendimiento por defecto con React Server Components.
- Proporciona una experiencia de desarrollo más moderna y simplificada.
- Recibe todas las nuevas características y optimizaciones.
- Reduce la cantidad de código necesario para funcionalidades comunes.
- Se alinea mejor con la dirección futura de React.
La única razón válida para usar Pages Router es mantener un proyecto existente donde la migración no justifique el costo-beneficio. Para proyectos nuevos, App Router es el camino a seguir.
Pregunta 1: ¿Cuál es la principal ventaja de los React Server Components en el App Router?
- a) Permiten usar más hooks de React
- b) Reducen el tamaño del bundle JavaScript enviado al cliente
- c) Requieren menos código boilerplate
- d) Son más fáciles de aprender
Pregunta 2: ¿Puedes usar ambos routers (Pages y App) en el mismo proyecto?
- a) No, es obligatorio elegir uno desde el inicio
- b) Sí, pero no simultáneamente
- c) Sí, Next.js los procesa en paralelo
- d) Sí, pero App Router tiene prioridad sobre Pages Router
/pages y /app) en el mismo proyecto. Cuando coexisten, el App Router tiene prioridad sobre el Pages Router. Esta característica es útil durante migraciones graduales.