
🔍 ¿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 (
{children}
Falar no WhatsApp
);
}
// 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 migrar 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.
Expandir: Migración paso a paso de Pages Router a App Router
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.
Expandir: Profundizando en React Server Components
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.