LOG 04 · FRAMEWORK

Next.js y Exportación Estática

Next.js App Router compilado a un sitio totalmente estático — output: 'export' — sin proceso de servidor, sin arranques en frío y sin nada que parchear a las 2 de la madrugada.

Publicado · Actualizado

Un build, no un servidor

Este sitio — y la mayoría de los sitios que entrego — se compilan con `output: 'export'`: cada ruta se genera como HTML/CSS/JS estático en tiempo de build, sin nada ejecutándose en el servidor después. Eso descarta las server actions y el renderizado bajo demanda, pero un sitio de portfolio o marketing rara vez los necesita, y a cambio se obtiene algo mejor — no hay proceso de servidor que pueda caerse, saturarse o necesitar un parche de seguridad.

Las rutas de apariencia dinámica siguen funcionando bajo exportación estática mediante `generateStaticParams` — cada ruta posible se enumera y se pre-renderiza en tiempo de build en lugar de calcularse por petición, que es exactamente cómo se generan las entradas individuales de este diario.

Metadatos como código, no como un añadido de última hora

Las APIs de metadatos tipadas de Next.js — el export `Metadata`, `generateMetadata`, `sitemap.ts`, `robots.ts` — hacen que la configuración de SEO viva en los mismos archivos TypeScript que la propia página, comprobada por el compilador, en lugar de un campo de CMS separado que silenciosamente se desincroniza de lo que la página realmente dice.

App Router, TypeScript de principio a fin

Cada componente de este sitio es un componente React tipado bajo el App Router — componentes de servidor por defecto, componentes de cliente solo donde la interactividad (un canvas WebGL, un efecto guiado por GSAP, una pieza de estado compartido suscrita) realmente lo requiere. Esa distinción es deliberada: menos JavaScript enviado al navegador para las partes de la página que nunca necesitaron hidratarse.

La trampa de lo que solo existe en el cliente

La exportación estática hace muy fácil pasar por alto un fallo concreto: todo lo que un componente monta desde un efecto no aparece en el HTML exportado. Las secciones de la home de este sitio se montan mediante portales en una escena CSS3D en cuanto se inicializa el escenario 3D, lo cual funciona perfectamente en un navegador — y significaba que el <h1> de la página solo existía tras la hidratación. Cualquier rastreador que leyera el archivo estático veía una home sin ningún encabezado.

La solución no es ingeniosa, solo deliberada: todo lo que debe estar en el HTML — encabezados, textos, enlaces, datos estructurados — se renderiza fuera del árbol que solo vive en el cliente, y se deja a la capa interactiva la parte para la que realmente está. Conviene abrir la salida compilada y leerla en lugar de fiarse del servidor de desarrollo, porque no son el mismo documento.

Servicios que lo usan