Las aplicaciones de una sola página (Single Page Applications, SPA) clásicas basadas en React puro (Vite / Create React App) entregan al navegador un contenedor HTML vacío (<div id="root"></div>) y un paquete JavaScript masivo. El navegador se ve obligado a descargar megabytes de scripts, analizarlos, ejecutarlos y solo entonces enviar solicitudes de red a la API para obtener contenido. Esto conduce a una pantalla blanca prolongada (alto Time to Interactive, mal Largest Contentful Paint) y problemas catastróficos con la indexación de búsqueda (SEO).
Next.js 16 App Router realiza un cambio arquitectónico fundamental: el framework traslada la generación primaria de la interfaz al lado del servidor (Node.js 24+). El navegador recibe instantáneamente un documento HTML completo y semánticamente enriquecido, estilizado con Tailwind CSS v4, que es inmediatamente visible para el usuario y los motores de búsqueda.
El acuerdo clave de Next.js es el enrutamiento basado en el sistema de archivos (File-system Based Routing) dentro de la carpeta app/. Las carpetas en el sistema de archivos definen las rutas en la barra de direcciones URL, y los nombres de archivo especiales reservados (page.tsx, layout.tsx, loading.tsx, error.tsx, not-found.tsx) forman la jerarquía de componentes de la página.
Veamos la diferencia en la arquitectura de entrega de contenido:
+-------------------------------------------------------------------------+
| CAMBIO ARQUITECTÓNICO: SPA vs NEXT.JS 16 |
+-------------------------------------------------------------------------+
| REACT SPA PURO (Renderizado del lado del cliente): |
| Servidor entrega: <div id="root"></div> + 2.5 MB app.js |
| Navegador: Pantalla blanca -> descarga JS -> parsing -> solicitud a API|
| Resultado: TTFB rápido, ¡pero contenido real en 2.8 segundos! |
+-------------------------------------------------------------------------+
| NEXT.JS 16 APP ROUTER (Server Components): |
| Servidor entrega: HTML completo con texto e imágenes listos |
| Navegador: Visualización instantánea del primer fotograma (FCP menos de 500 ms)|
| Paquete JS: Solo islas interactivas ('use client') |
| Resultado: First Contentful Paint instantáneo, 100% accesibilidad SEO|
+-------------------------------------------------------------------------+Next.js analiza la URL (por ejemplo, /catalog) y encuentra el archivo app/catalog/page.tsx correspondiente.
En el servidor Node.js se ejecutan los Server Components asíncronos, leyendo directamente la base de datos o llamando a microservicios.
El navegador comienza a recibir fragmentos HTML listos a través del protocolo HTTP/2 sin esperar a que se completen todas las solicitudes largas.
El navegador descarga un paquete JS compacto solo para botones e inputs interactivos con la directiva 'use client'.
¿Qué URL corresponderá al archivo de componente ubicado en la ruta `app/dashboard/analytics/page.tsx`?
app/ y convenciones de nombres#En Next.js 16, se reservan nombres de archivo especiales:
page.tsx: UI único de la ruta. Sin page.tsx, la carpeta se considera inaccesible para la visita directa.layout.tsx: interfaz compartida (Header, Sidebar, Footer) que envuelve las páginas hijas y conserva el estado durante las transiciones.loading.tsx: un esqueleto de Suspense integrado, que se muestra instantáneamente mientras la página del servidor carga datos.error.tsx: un límite de error (Error Boundary) para la captura aislada de fallos.not-found.tsx: UI personalizado para el estado HTTP 404.app/
├── layout.tsx # Layout raíz (<html>, <body>, Nav)
├── page.tsx # Página principal (/)
├── not-found.tsx # Página global 404
├── catalog/
│ ├── layout.tsx # Sub-layout del catálogo (filtros)
│ ├── page.tsx # Página del catálogo (/catalog)
│ └── [slug]/ # Ruta dinámica (/catalog/macbook-pro)
│ └── page.tsx
└── api/
└── health/
└── route.ts # Endpoint de API HTTP (/api/health)app/page.tsx#Por defecto, todos los componentes dentro de app/ son React Server Components (componentes de servidor):
// ¡Este es un Server Component: se ejecuta en el servidor Node.js!
export default function HomePage() {
const serverTime = new Date().toLocaleTimeString();
return (
<main className="max-w-4xl mx-auto py-12 px-4 space-y-6">
<div className="inline-block px-3 py-1 text-xs font-semibold rounded-full bg-accent-violet/10 text-accent-violet border border-accent-violet/20">
Next.js 16 + React 19
</div>
<h1 className="text-4xl font-extrabold text-text-primary tracking-tight">
Bienvenido a WPSKILLS
</h1>
<p className="text-text-muted leading-relaxed">
Hora de generación de la página en el servidor: <strong className="text-text-primary">{serverTime}</strong>.
Este HTML fue generado por el motor de Next.js sin demoras de JS del cliente.
</p>
<div className="pt-4">
<a
href="/catalog"
className="inline-flex items-center px-5 py-2.5 rounded-xl bg-accent-cyan text-bg-base font-semibold hover:opacity-90 transition-opacity"
>
Ir al catálogo →
</a>
</div>
</main>
);
}En Next.js 16, Turbopack está habilitado por defecto para el desarrollo local, proporcionando una aceleración de la compilación de 5 a 10 veces en comparación con el antiguo Webpack:
# Inicio a través de pnpm con el compilador Turbopack:
pnpm run dev
# Servidor local disponible en:
# Ready in 450ms on http://localhost:3000¿Se puede usar el hook `useState` o el manejador `onClick` directamente dentro del archivo `app/page.tsx` sin directivas adicionales?
Intentar llamar a useState en un componente de servidor provocará un error de compilación fatal de Next.js:
// ERROR:
export default function Page() {
const [count, setCount] = useState(0); // FALLO: ¡Server Component no soporta estado!
return <button onClick={() => setCount(1)}>Клик</button>;
}
// CORRECTO: ¡mueva el botón interactivo a un archivo separado con 'use client'!Una etiqueta <a> normal como <a href="/about"> provoca una recarga completa de la página en el navegador, restableciendo el estado de la aplicación y obligando al navegador a descargar todos los recursos de nuevo. Siempre use el componente <Link href="/about"> para una navegación fluida sin recargas (transiciones SPA).