← Volver al blog

Cómo creé mi sitio web personal con Astro + Cloudflare Pages gratis

Todo desarrollador debería tener un sitio web personal. No porque garantice ofertas de trabajo, sino porque es tuyo — un rincón de internet que representa quién eres y qué construyes.

Hace poco lancé gueroverde.com y el costo total fue $10.46 USD al año (solo el dominio). Todo lo demás fue gratis. Aquí te cuento exactamente cómo lo hice.

El Stack

  • Astro — Generador de sitios estáticos, perfecto para blogs y sitios personales
  • Cloudflare Pages — Hosting gratuito con CDN global, deploy automático con cada push via Wrangler
  • Cloudflare — Registro de dominio a precio de costo (~$10.46/año por un .com)
  • MDX — Posts del blog en Markdown con soporte para componentes

¿Por qué Astro?

Consideré varias opciones: HTML puro, Next.js o Gatsby. Astro ganó porque:

  1. Cero JS por defecto — No envía JavaScript a menos que lo necesites. Rapidísimo.
  2. Soporte de i18n integrado — Quería versiones en español e inglés.
  3. Content Collections — Posts del blog como archivos MDX, con tipado y estructura.
  4. Deploy en cualquier lugar — Cloudflare Pages, Vercel, Netlify, GitHub Pages.

Si ya conoces React o Vue, Astro se siente familiar de inmediato. Componentes, layouts, props — mismos conceptos.

Paso 1: Crear el proyecto Astro

npm create astro@latest mi-sitio
cd mi-sitio
npm install
npm run dev

El wizard de Astro te preguntará sobre templates y TypeScript. Yo elegí el template mínimo y activé TypeScript.

Paso 2: Estructura para i18n

Organicé mis páginas así:

src/
  pages/
    index.astro          # redirige a /en/
    en/
      index.astro
      blog/
        index.astro
        [slug].astro
    es/
      index.astro
      blog/
        index.astro
        [slug].astro
  content/
    blog/
      en/
        mi-primer-post-en.mdx
      es/
        mi-primer-post-es.mdx

Un archivo src/i18n/utils.ts maneja las traducciones:

export const languages = {
  en: 'English',
  es: 'Español',
};

export const defaultLang = 'en';

export const ui = {
  en: {
    'nav.home': 'Home',
    'nav.blog': 'Blog',
    'nav.about': 'About',
  },
  es: {
    'nav.home': 'Inicio',
    'nav.blog': 'Blog',
    'nav.about': 'Sobre mí',
  },
} as const;

Paso 3: SEO básico

Esto se suele omitir y es un error. Agrega esto a tu BaseLayout.astro:

---
const { title, description, canonicalURL } = Astro.props;
---
<head>
  <title>{title}</title>
  <meta name="description" content={description} />
  <link rel="canonical" href={canonicalURL} />

  <!-- Open Graph -->
  <meta property="og:title" content={title} />
  <meta property="og:description" content={description} />
  <meta property="og:url" content={canonicalURL} />
  <meta property="og:type" content="website" />

  <!-- Twitter Card -->
  <meta name="twitter:card" content="summary_large_image" />
  <meta name="twitter:title" content={title} />
  <meta name="twitter:description" content={description} />
</head>

También instala la integración de sitemap:

npx astro add sitemap

Y agrega la URL de tu sitio en astro.config.mjs:

export default defineConfig({
  site: 'https://tudominio.com',
  integrations: [sitemap()],
});

Paso 4: Deploy en Cloudflare Pages

Primero, instala el adaptador de Cloudflare:

npm install @astrojs/cloudflare

Configura astro.config.mjs para usar el adaptador:

import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://tudominio.com',
  output: 'static',
  adapter: cloudflare(),
  integrations: [sitemap()],
});

Crea un archivo wrangler.jsonc en la raíz del proyecto:

{
  "name": "gueroverde-site",
  "compatibility_date": "2024-01-01",
  "pages_build_output_dir": "dist"
}

Ahora conecta tu repositorio en el dashboard de Cloudflare Pages:

  1. Ve a dash.cloudflare.comWorkers & PagesCreate
  2. Selecciona Connect to Git y autoriza tu repositorio de GitHub
  3. Configura el build: comando npm run build, directorio de salida dist
  4. Haz click en Save and Deploy

Listo — cada push a main se despliega automáticamente. Sin GitHub Actions, sin archivos YAML. Cloudflare detecta los cambios y reconstruye tu sitio.

Paso 5: Comprar un dominio personalizado (opcional pero vale la pena)

Usé Cloudflare Registrar. Razones:

  • Vende dominios a precio mayorista — sin markup
  • gueroverde.com costó $10.46 USD/año
  • Renovaciones al mismo precio para siempre (sin bait-and-switch)
  • DNSSEC y privacidad WHOIS incluidos gratis

Alternativa: Namecheap también es excelente e incluye privacidad WHOIS gratuita.

Una vez comprado el dominio, agrégalo como dominio personalizado en tu proyecto de Cloudflare Pages y el DNS se configura automáticamente.

Paso 6: Dar de alta en Google Search Console

No te saltes este paso. Ve a search.google.com/search-console, agrega tu dominio, verifica vía DNS (Cloudflare lo hace en 2 clicks) y envía tu sitemap:

https://tudominio.com/sitemap-index.xml

Así es como Google descubre tu sitio. Sin esto, podrías esperar meses para que te indexen.

El resultado

Un sitio personal completamente personalizado con:

  • ✅ Versiones en inglés y español
  • ✅ Blog con soporte MDX
  • ✅ Auto-deploy en cada push
  • ✅ SEO listo (sitemap, meta tags, OG, robots.txt, RSS)
  • ✅ Dominio personalizado con SSL
  • ✅ CDN global de Cloudflare — tu sitio carga rápido en cualquier parte del mundo
  • Costo total: $10.46 USD/año

Cloudflare Pages es completamente gratis: requests ilimitados, 500 builds al mes, y ancho de banda ilimitado. Solo pagas el dominio.

Qué sigue

Planeo agregar:

  • Una sección de “Servicios/Contrátame” para consultoría freelance
  • Más posts técnicos (arquitectura AWS, patrones Laravel)
  • Affiliate links de herramientas que uso y recomiendo

Si eres desarrollador y no tienes sitio personal, ya no hay excusa. El stack es gratuito, las herramientas son excelentes, y todo puede estar en vivo en una tarde.


¿Tienes preguntas sobre alguno de estos pasos? Déjame un comentario o escríbeme — con gusto ayudo.