Hasta este punto del curso, hemos estado trabajando con React como lo que es originalmente: una librería.
Hemos utilizado Vite para empaquetar, react-router para navegar, zustand para el estado y axios para las peticiones. Hemos tenido que tomar decisiones arquitectónicas constantes y ensamblar piezas sueltas para construir nuestra aplicación.
Esto es genial para aprender, pero cuando el proyecto crece necesitamos más estructura, convenciones y buen rendimiento desde el principio.
Next.js es un framework de React para crear aplicaciones web completas, con routing, renderizado en servidor, optimización de recursos y despliegue preparados desde el inicio.
Si React es el motor, Next.js es el coche completo: trae el chasis, las ruedas, el volante y el sistema de navegación integrados de fábrica.
En esta nueva sección del curso, vamos a cambiar nuestra mentalidad de Single Page Application (SPA) a una arquitectura moderna Full Stack.
Librería vs Framework
La diferencia técnica fundamental entre usar React con Vite y usar Next.js es el concepto de Inversión de Control.
- Librería (React): Tú tienes el control. Tú decides dónde montar la app, qué router usar y cómo configurar el build. Tu código llama a la librería.
- Framework (Next.js): El framework tiene el control. Él decide la estructura de carpetas, el sistema de enrutado y el ciclo de vida. El framework llama a tu código.
El problema de la SPA (Vite)
Para entender por qué Next.js es el estándar hoy en día, debemos recordar cómo funciona una aplicación creada con Vite.
Cuando un usuario entra a tu web hecha con Vite, el servidor le envía un archivo index.html prácticamente vacío, que solo contiene un <div id="root"></div> y una etiqueta <script>.
El navegador tiene que descargar todo el JavaScript, ejecutarlo y, solo entonces, React “pinta” la interfaz. Esto genera dos problemas:
El problema de la SPA
- SEO Deficiente: Los robots de Google (crawlers) a veces ven la página en blanco antes de que React arranque.
- Waterfalls (Cascadas): El usuario ve una pantalla blanca, luego un spinner, y luego el contenido.
Next.js soluciona esto generando HTML real en el servidor. Cuando el navegador recibe la respuesta, el usuario ya ve el contenido, incluso si JavaScript no ha terminado de cargar. A este proceso de “dar vida” al HTML estático con interactividad se le llama Hidratación.
Instalación y setup
Vamos a crear nuestro primer proyecto. Next.js tiene su propio CLI (Command Line Interface).
Abrid vuestra terminal y ejecutad:
npx create-next-app@latest mi-web-next
El asistente os hará varias preguntas. Vamos a seleccionar la configuración más robusta:
| Configuración | ¿Usar? | Nota |
|---|---|---|
| TypeScript | ✅ Yes | Tipado estático y mejor DX |
| ESLint | ✅ Yes | Calidad y consistencia de código |
| Tailwind CSS | ✅ Yes | Estándar de estilos del proyecto |
src/ directory | ✅ Yes | Mantiene la raíz del proyecto limpia |
| App Router | ✅ Yes | CRÍTICO: arquitectura moderna a aprender |
| Customize import alias | ❌ No / ✅ Yes | Opcional (@/components si os gusta) |
Análisis de la Estructura
Una vez instalado, abrid el proyecto en VS Code. Veréis que han desaparecido archivos familiares como index.html o main.jsx.
La estructura del App Router es la siguiente:
mi-web-next/
├── public/ # Assets estáticos (imágenes, favicons)
├── src/
│ └── app/ # EL CORAZÓN DE NEXT.JS
│ ├── layout.tsx
│ ├── page.tsx
│ └── globals.css
├── next.config.mjs # Configuración del servidor
├── package.json
└── ...
layout.tsx
Este archivo reemplaza al antiguo index.html. Es el componente raíz que envuelve a toda nuestra aplicación. Aquí es donde definimos las etiquetas <html> y <body>.
// src/app/layout.tsx
import type { Metadata } from "next";
import "./globals.css";
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
Fijaos en la prop children. Todo lo que rendericemos en nuestras páginas se inyectará ahí dentro automáticamente.
page.tsx
Este archivo representa la ruta / (la Home). En Next.js, solo los archivos llamados page.tsx (o .js) son accesibles públicamente. Si creáis un componente llamado Boton.tsx en esta carpeta, no será una ruta, será solo un componente.
Limpieza inicial
El proyecto de ejemplo trae mucho código “basura” (estilos de demostración, logos de Vercel, etc.). Vamos a dejarlo listo para trabajar.
Borrad todo el contenido de src/app/globals.css pero dejad las directivas de Tailwind (si lo elegisteis):
@tailwind base;
@tailwind components;
@tailwind utilities;
Limpiad src/app/page.tsx para dejar un componente básico:
export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center p-24">
<h1 className="text-4xl font-bold">Hola Next.js</h1>
</main>
);
}
Ejecutad el servidor de desarrollo:
npm run dev
Abrid http://localhost:3000. Si veis vuestro título, felicidades. Ya tenéis un entorno Next.js corriendo.
Next.js utiliza Fast Refresh. A diferencia de Vite, es capaz de preservar el estado de los componentes (como el texto de un input) incluso cuando editas el código y guardas.
Ahora que tenemos el entorno listo, debemos aprender cómo movernos por la aplicación. En Next.js no definimos las rutas con react-router; las carpetas son las rutas.
