Cómo Construí Este Portfolio con Astro
Cómo Construí Este Portfolio con Astro
Cuando decidí crear mi nuevo portfolio, tenía claros mis objetivos: rendimiento extremo, animaciones fluidas y facilidad de mantenimiento. Después de evaluar varias opciones, elegí Astro 5 como base.
¿Por Qué Astro?
Astro tiene una filosofía que me encanta: enviar el mínimo JavaScript posible al cliente. Para un portfolio, esto es perfecto porque la mayoría del contenido es estático.
Islands Architecture
Astro usa un concepto llamado “Islands Architecture”. Significa que puedes tener componentes interactivos (React, Vue, Svelte) embebidos en páginas mayormente estáticas.
---
// Esta parte se ejecuta en el servidor
import { Hero } from '@/components/Hero';
import { Projects } from '@/components/Projects';
---
<!-- Hero se carga inmediatamente -->
<Hero client:load />
<!-- Projects solo se hidrata cuando es visible -->
<Projects client:visible />
El Stack Completo
UnoCSS vs Tailwind
Elegí UnoCSS sobre Tailwind por varias razones:
- Velocidad: UnoCSS es significativamente más rápido
- Tamaño: El CSS final es ~6KB vs ~15KB de Tailwind
- Flexibilidad: Puedo crear shortcuts personalizados fácilmente
// uno.config.ts
shortcuts: {
'btn-primary': 'px-4 py-2 bg-neon-cyan text-black rounded-lg',
'card-glass': 'backdrop-blur-md bg-white/10 border border-white/20'
}
Framer Motion para Animaciones
Las animaciones son sutiles pero importantes. Uso Framer Motion para:
- Transiciones de entrada al scroll
- Efectos hover en cards
- Animaciones de la navegación móvil
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
>
{children}
</motion.div>
Content Collections para el Blog
Astro tiene un sistema built-in para gestionar contenido llamado Content Collections. Es type-safe y funciona perfecto con MDX.
// src/content/config.ts
const postsCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
date: z.date(),
tags: z.array(z.string()),
}),
});
Deploy en Docker + Traefik
Para el deploy, uso un setup que tengo en un servidor Hetzner:
- Dockerfile multi-stage para build optimizado
- Traefik como reverse proxy con SSL automático
- GitHub Actions para CI/CD
# docker-compose.prod.yml
services:
portfolio:
labels:
- traefik.enable=true
- traefik.http.routers.portfolio.rule=Host(`antonio.romerolabs.dev`)
- traefik.http.routers.portfolio.tls.certresolver=letsencrypt
Resultado
El resultado es un portfolio que:
- Carga en menos de 2 segundos
- Consigue Lighthouse 100 en Performance
- Es fácil de mantener y actualizar
¿Te interesa crear algo similar? ¡No dudes en contactarme!