Por qué hice este sitio
La idea era que alguien pudiera conocer la iglesia antes de visitarla. Para eso necesitaba reunir en un solo lugar su historia, los horarios, los ministerios, la ubicación y los mensajes que publican en YouTube.
Me encargué del diseño y del desarrollo completo. Usé Astro (abre en una pestaña nueva) para generar las páginas y Tailwind CSS (abre en una pestaña nueva) para trabajar los estilos. Casi todo el sitio puede servirse como HTML estático; la excepción es la información que viene de YouTube.
La sección de mensajes
Durante el build leo el feed público del canal para dejar un mensaje destacado y varias emisiones recientes dentro del HTML. También mantengo una lista de respaldo por si el feed no responde. Eso evita que la página quede vacía, pero no alcanza para saber si hay una transmisión en vivo.
Para resolver esa parte creé el endpoint /api/youtube-live con Cloudflare Pages Functions (abre en una pestaña nueva) . La consulta a YouTube Data API (abre en una pestaña nueva) ocurre en el servidor, así que la llave no termina expuesta en el navegador. La Function ignora videos normales y Shorts; devuelve el directo activo, si existe, y las transmisiones finalizadas más recientes.
Al entrar a la página no cargo inmediatamente el reproductor de respaldo. Primero muestro un estado neutral mientras se resuelve la consulta y después creo el iframe con el video correcto. La página vuelve a consultar el endpoint cada minuto y guarda la última respuesta durante dos minutos en sessionStorage (abre en una pestaña nueva) . Si regresás a la sección, puede recuperar ese estado sin mostrar primero contenido anterior.
Qué pasa si YouTube tarda o falla
No quería que cada visita dependiera de una llamada nueva a YouTube. El endpoint guarda la respuesta durante un minuto con la Cache API de Cloudflare (abre en una pestaña nueva) y utiliza una clave distinta por canal.
También preparé una migración para guardar el último resultado válido en Cloudflare D1 (abre en una pestaña nueva) . Ese binding es opcional: cuando está conectado, la Function puede responder con el snapshot mientras actualiza YouTube en segundo plano mediante waitUntil (abre en una pestaña nueva) . Si D1 todavía no está configurado, la integración continúa usando la caché de borde y la API directamente.
Tuve que tratar los directos con más cuidado que los videos terminados. Un snapshot viejo todavía puede servir para mostrar mensajes recientes, pero no debería seguir diciendo que la iglesia está en vivo. Por eso los estados de transmisión vencen antes y, ante una respuesta demasiado antigua, el endpoint conserva los videos pero elimina el indicador de directo.
Otros detalles
También preparé cada página para que aparezca con el título y la descripción correctos en buscadores y al compartirla en redes sociales. Además, añadí información que ayuda a los buscadores a reconocer que el sitio pertenece a una iglesia.
También optimicé las imágenes, indiqué sus dimensiones para evitar saltos mientras cargan y agregué carga diferida donde tenía sentido. Para la navegación incluí un enlace para saltar al contenido, estados accesibles y una alternativa con menos movimiento.
El sitio está desplegado en Cloudflare Pages (abre en una pestaña nueva) . Por ahora utiliza el dominio pages.dev ; cuando la iglesia compre su dominio solo tendré que conectarlo al despliegue actual.