Personal Portfolio Website
Portfolio personal production-ready con pipeline de contenido MDX tipado, Core Web Vitals verificados y CI/CD con Lighthouse CI integrado.
Overview
Portfolio personal diseñado y desarrollado desde cero con Next.js 16 App Router. El foco no es solo la presentación — es demostrar capacidad de ingeniería full-stack aplicada a un producto real en producción: pipeline de contenido tipado, accesibilidad WCAG AA, métricas Core Web Vitals verificadas en CI y rate limiting con Redis.
Arquitectura
- Contenido: Velite compila los archivos MDX en
src/content/a TypeScript tipado en build time. Cero imports directos del output de Velite — todo accede mediante helpers ensrc/lib/content.ts. - Routing: App Router con React Server Components por defecto.
"use client"solo donde hay event handlers, hooks o browser APIs. - SEO:
generateMetadata()por ruta, JSON-LD schemas (Person, Article, SoftwareSourceCode, BreadcrumbList), sitemap y robots dinámicos. OG image generada en runtime connext/og. - Formulario de contacto: validación client-side con react-hook-form + Zod; re-validación server-side en la API route; envío con Resend; rate limiting con Upstash Redis (sliding window 5 req/h) con fallback in-memory.
- Estilos: Tailwind CSS v4 configurado exclusivamente via
@themeenglobals.css— sintailwind.config.js. Design system "Tech Artisan" con CSS custom properties para dark/light mode.
Stack técnico
Frontend: Next.js 16 · TypeScript estricto · Tailwind CSS v4 · shadcn/ui
Contenido: Velite · MDX · schemas tipados (Post, Project)
Backend / API: Next.js API Routes · Zod · Resend · Upstash Redis
Calidad: Vitest · axe-core (a11y) · ESLint · Prettier · TypeScript strict
Deploy: Vercel · GitHub Actions CI (lint → typecheck → tests → build → Lighthouse CI)
Aspectos destacados
- Core Web Vitals en producción: FCP 0.9s · LCP 1.8s · TBT 10ms · CLS 0.
- Lighthouse CI con thresholds estrictos: accessibility ≥ 0.9, SEO ≥ 0.9.
- Tests de accesibilidad automatizados con axe-core en cada PR.
- Rate limiting distribuido con Upstash Redis (sliding window) y fallback in-memory para entorno local.
- OG image dinámica generada en runtime con
next/og— sin assets estáticos adicionales. - Dark/light mode con CSS custom properties y persistencia en localStorage.