Sitio estático Vanilla en Cloudflare Pages
Sin paso de compilación. Edita archivos → haz push a main → Cloudflare Pages despliega automáticamente. Rápido,
barato y nunca peleas con un toolchain.
Por qué vanilla (decisión fundamentada)
- Cero churn de compilación/CI; corregir una línea de copia es un despliegue de 30 segundos.
- Sin lock-in de framework ni impuesto de reescritura. "Añade, no reescribas" es la regla.
- Todo el sitio es greppable, debuggeable y obvio.
- Compromiso aceptado: más código DOM manual. Vale la pena a escala pequeña/mediana.
Repo + despliegue
- Un repositorio GitHub → proyecto de Cloudflare Pages, despliegue automático al hacer push a
main. - Pages sirve la raíz del repo. URLs bonitas:
/mi-cuenta.htmlse sirve en/mi-cuenta. - Las funciones (serverless) viven en
/functions(versupabase-backend).
El ritual de despliegue (haz esto en CADA despliegue)
- Edita los archivos.
- Verifica que el JS compila — nunca subas JS inline roto. Extrae los bloques
<script>inline y ejecutavm.compileFunctionen cada uno;node --checkpara.js/.cjs. Verreference/verify-inline.cjs. - Haz cache-bust de los assets:
node .claude/cache-bust.cjs— estampa cada referencia aassets/**/*.css|jsen el HTML con?v=<git-short-hash>y escribeversion.json. Verreference/cache-bust.cjs. - Actualiza la marca de versión (fuente única de verdad en un archivo JS, mostrada sutilmente
en el pie de página) y regístrala. Ver
project-continuitypara el esquema de versionado. - Haz commit (descriptivo, en el idioma del proyecto) con el trailer de coautor,
haz push a
main. - Verifica en vivo: con
curlal asset desplegado y confirma la nueva marca de versión + queversion.jsoncoincida con?v=del asset (deben coincidir o el auto-recargador se cicla). La protección anti-bots de Cloudflare bloquea crawlers simples → usa un User-Agent de navegador.
.claude/normalmente está en.gitignore, así que los scripts de cache-bust/verificación se quedan locales (se ejecutan en tiempo de compilación en tu máquina, no en el repo).
Cache-busting + recarga automática (mata el juego del teléfono del "no se ve")
Dos capas, ambas en reference/:
cache-bust.cjs— re-estampa?v=<git hash>en todas las referencias a assets en cada despliegue para que los navegadores vuelvan a obtener los CSS/JS cambiados, Y escribeversion.json = {"v":"<hash>"}.- Auto-recargador (
reference/auto-reload.js) — un script minúsculo incluido en cada página que lee su propia?v=cargada, consulta/version.json(servido conno-store), y cuando detecta un nuevo despliegue: recarga al volver a la pestaña (momento seguro), muestra un banner de un toque "Actualizar" mientras estás mirando, y nunca interrumpe mientras escribes (window.__noAutoReloadpara opt-out en flujos de examen/checkout). Advertencia de bootstrap: la primera vez, los usuarios hacen un hard-refresh una vez para cargar el recargador; a partir de ahí es automático.
Sirve el marcador fresco mediante _headers:
/version.json
Cache-Control: no-store, max-age=0
Cabeceras de seguridad (_headers en la raíz del repo)
Siempre establece: Content-Security-Policy (bloquea script-src/frame-src/connect-src
a los CDNs exactos + tu URL de Supabase + wss para tiempo real), X-Frame-Options: DENY,
X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin,
Permissions-Policy, Strict-Transport-Security. Lección aprendida: incrustar un iframe de video
necesita el dominio del reproductor en frame-src o el navegador lo bloquea silenciosamente.
Convenciones CSS reutilizables
- Theming basado en tokens con variables CSS; un remapeo
data-theme="dark"+ una clave compartida delocalStoragepara que el tema se sincronice entre páginas/pestañas. - Modo oscuro: pasar el contraste no es suficiente — también necesitas una jerarquía de capas visible (bg < surface < card) con pasos de luz + sombra, o se lee plano.
- Nunca uses valores fijos de
white/colores; usa tokens para que el tema responda. - No rompas los
.btn/.btn-primaryglobales; sobrescribe en ámbito.
Archivos en este skill
reference/cache-bust.cjs— el estampador de assets + escritor de version.json.reference/auto-reload.js— el auto-recargador de despliegue (inclúyelo en un archivo JS cargado globalmente).reference/verify-inline.cjs— verifica la compilación de bloques<script>inline antes del despliegue.reference/headers-example— un_headersde inicio.