Proyecto - Cómo construí (y reconstruí) mi sitio web personal
jandurkaj.dev es un sitio web personal multilingüe. Lo construí en 2023 con Next.js 13 y su entonces nuevo App Router, y en 2026 lo reconstruí sobre Next.js 16 junto con un asistente de programación con IA.
- Cliente
- Jan Durkaj
- Año
- –
- Servicio
- Desarrollo Next.js, i18n, SEO, modernización asistida por IA

Motivación
Empecé este proyecto para aprender y practicar nuevos conceptos en Next.js
Quizás te preguntes: "¿Por qué Next.js?" para un sitio tan pequeño. Gatsby.js
Mi principal motivo para crear un nuevo sitio de portafolio fue aprender. Además de mostrar los últimos proyectos en los que he trabajado, quería explorar el renderizado del lado del servidor y los Server Components en React.js. También deseaba profundizar mi conocimiento en un marco más versátil para grandes proyectos escalables. Me encantaría volver a usarlo en el futuro.
Especificación del proyecto
Mi objetivo era crear un sitio web personal que reflejara realmente quién soy. En lugar de abrumar a los visitantes con una descripción descarada de mis habilidades técnicas, mi objetivo es brindarles una comprensión completa de mi verdadera identidad.
Desde el principio supe que los factores clave para conseguirlo eran:
- Hacer que el sitio sea multilingüe.
- Tener una UI/UX minimalista y elegante.
- Incluyendo funciones de interfaz de usuario personalizadas.
- Vitrina de mis proyectos más recientes.
- Añadiendo chistes ocultos como una aguja en un pajar.
- Optimización del sitio para SEO y rendimiento.
Para evitar la molestia de la configuración, la configuración inicial y la creación de UX/UI desde cero, y para ahorrarme horas de trabajo, decidí comenzar con una plantilla inicial. Hay muchos ejemplos disponibles en el sitio Next.js GitHubcreate-next-app. Puede encontrar más información sobre cómo funciona en la documentación de Next.js
A pesar de haber disfrutado durante muchos años usando CSS con la convención de nomenclatura BEM (Block Element Modifier)
Otra característica nativa que ofrece Next.js es MDX
Dado que estaba claro que mi nuevo sitio web personal sería creado con React.js, Next.js, MDX y Tailwind CSS, comencé a buscar una buena plantilla inicial. Afortunadamente, no tuve que buscar mucho, ya que los creadores de Tailwind CSS tienen otro proyecto llamado Tailwind UI
Bien. Solo necesitaba configurar Typescript para un proyecto existente
Pila de tecnología que uso
- Next.js
- React.js
- TypeScript
- next-intl
- MDX
- Tailwind CSS
- Motion
- React Email
- Zod
- Vitest
- React Testing Library
- Vercel
- Claude Code
- CI/CD
- Adobe Suite
- SEO
Desafíos
TL;DR: La decisión de utilizar "lo último y lo mejor" del mercado fue una gran fuente de frustración durante todo el proyecto. A continuación se muestran algunos ejemplos:
Internacionalización
Eso no debería ser un gran problema. Al principio, pensé que era solo otro contenido por idioma. Luego, seguí la documentación de Next.js para la internacionalización (i18n)
Se utilizó mucho Framer Motion
Estaba condenado a utilizar un paquete de terceros y, en ese momento, el único que funcionaba mejor con los componentes del servidor/cliente era next-intl
Estaba obligado a usar un paquete de terceros y, en ese momento, el único que funcionaba mejor con los componentes del servidor/cliente era next-intlnext-intl porque era el más adecuado para mis necesidades.
Server Components y App Router
Aunque Next.js 13 viene con soporte bien documentado para los componentes del servidor y el App Router se considera el predeterminado, cuando comencé el proyecto, estas características no estaban pulidas ni probadas en batalla en absoluto.
Uno de muchos ejemplos: generateStaticParams no funcionaba con la función experimental de Next.js Server Actions
MDX y i18n
Debido a cómo funciona el App Router de Next.js y la estructura de mi plantilla inicial, tuve que desarrollar una solución para cargar el contenido MDX correcto según la lengua actual elegida. Esto permite traducir el contenido almacenado localmente en archivos .mdx.
P.D.: A pesar de la versatilidad de next-intl, no se puede utilizar directamente en archivos .mdx. Está diseñado para ser utilizado dentro de los componentes de React.js y en otras áreas específicas de Next.js. Puede encontrar más información sobre los entornos en los que se puede utilizar en la documentación oficial de next-intl
Reconstruido en 2026
En otoño de 2026 el sitio seguía funcionando, pero el código había envejecido como la leche. Next.js 14 con React 18, una internacionalización sostenida a base de parches, Tailwind CSS 3, un Jest que ya no se llevaba bien con nada moderno y un banner de cookies de Google Analytics que nadie quería ver. La pregunta no era si actualizarlo, sino cómo hacerlo sin pasarme todas las tardes de un mes con ello.
Así que probé algo nuevo: hice toda la modernización junto con Claude Code
Cómo trabajamos
Desde el primer mensaje puse una regla: nada de lanzarse directamente a arreglar cosas. Cada paso tenía que pasar por el mismo ciclo:
- Análisis del estado actual, con hallazgos respaldados por pruebas.
- Propuesta de un solo paso, con sus pros y contras explicados.
- Mi visto bueno, y solo entonces el código, en un único commit.
- Revisión del sitio funcionando en una preview de Vercel antes de seguir.
La actualización se hizo en ocho pasos: limpieza, next-intl 4, una nueva arquitectura de los casos de estudio, Next.js 16 con React 19, Tailwind CSS 4, el formulario de contacto, Vitest y, por último, una auditoría del sitio, seguida de unas cuantas rondas de contenido y pulido. Cada paso se verificó construyendo el sitio y comparando cada enlace, traducción y entrada del sitemap antes y después.
El resultado se nota en el móvil: la página de inicio ahora obtiene 96 en Lighthouse en lugar de 77, y su contenido principal aparece en 2,8 segundos en lugar de 6,3.

Lo que encontró y a mí se me había pasado
Lo más valioso no fueron las actualizaciones, sino los errores escondidos a plena vista:
- Los casos de estudio se generaban solo en el navegador. Los buscadores y las vistas previas de enlaces veían el encabezado y nada más. Ahora cada caso de estudio se genera de antemano en el servidor desde una única ruta.
- Las páginas inexistentes respondían "200 OK" en lugar de "404 Not Found", por culpa de una pantalla de carga que nadie necesitaba en un sitio completamente estático.
- Cuatro casos de estudio compartían la meta descripción "Annie Sloan description". Ups.
- La imagen principal de los casos de estudio siempre descargaba su versión de 1920 px, incluso en el móvil.
- El formulario de contacto se fiaba de todo lo que enviaba el navegador. Ahora lo valida todo en el servidor, conserva tu mensaje cuando algo falla y filtra los bots sin captcha.
- La pizarra del pie de página volvía a pintar cada línea encima de sí misma con cada punto nuevo, lo que dejaba las líneas dentadas, y en el móvil cada trazo nuevo empezaba donde había terminado el anterior.
Lo que tuve que detectar yo
Fue una colaboración, no un piloto automático. La IA borró la carpeta de compilación mientras mi servidor de desarrollo estaba en marcha y lo rompió, y durante una prueba en el navegador me envió un correo real desde mi propio formulario de contacto. Ese segundo "error" resultó ser un regalo: reveló que el temporizador antispam fallaba cada vez que la función serverless despertaba de un arranque en frío. Lo arreglamos el mismo día y la solución se probó en un servidor recién desplegado y en frío.
Sus propias correcciones también necesitaban revisión. Durante la auditoría cambió el formato de las fechas a UTC, y eso desplazó en silencio todos los trabajos de mi página "Sobre mí" un mes hacia atrás; nadie lo notó hasta que actualizamos esa página más tarde.
Mi conclusión: la IA es una compañera de programación increíblemente rápida y meticulosa, pero las decisiones, la revisión y el criterio siguen siendo cosa de las personas. Pedir primero una propuesta, en lugar de una solución terminada, marcó toda la diferencia.
Cuánto tiempo llevó
Toda la modernización me llevó unas 4 horas. Mi estimación para el mismo volumen de trabajo sin IA es de unos 5 días laborables: aproximadamente medio día para next-intl, otro medio para la arquitectura de los casos de estudio, otro para Tailwind CSS y otro para el formulario de contacto, un día para Next.js 16 con React 19, otro para la auditoría y sus correcciones, y el resto para limpieza, pruebas, documentación y este texto.
- Con IA
- 4 h
- Estimación sin IA
- 5 días
- Dependencias
- 59 → 39
- Correo accidental
- 1
Y luego tocó jugar
Con la actualización terminada, convertí el espacio creativo del pie de página en una pequeña herramienta de dibujo. La bicicleta ahora se queda como una guía gris que puedes calcar, con ajuste opcional a ella, además de un borrador, colores y descarga en PNG. Baja hasta el final de la página y pruébalo.
Música del futuro.
Este proyecto está lejos de ser perfecto. Podría dedicar innumerables horas a agregar y pulir nuevas funciones. Sin embargo, aquí hay una breve lista de ideas que podría implementar en un futuro cercano:
- Añadir una página de blog con la opción de filtrar por categoría y ordenar según varios parámetros.
- Añadir una Content Security Policy estricta.
- Implementar notificaciones emergentes para los mensajes del formulario de contacto.
- Liquados tomados
- 123🥤
- Experiencia
- 666+
- Más rápido
- 7×
- Más económico
- ∞×