Construir un sitio de directorio parece algo trivial hasta que te encuentras conectando bases de datos, capas de caché y frameworks de front-end reactivos solo para mostrar lo que es, esencialmente, una tabla de contenidos curada. Hace poco construí Social Tools List, un sitio para comparar software de redes sociales. Mi objetivo era ponerlo en línea rápidamente, mantenerlo veloz y evitar el mantenimiento de infraestructura para un contenido que solo cambia cuando añado o actualizo una herramienta. Me decidí por un stack de enfoque "static-first": Astro para la generación del sitio, TypeScript para los datos estructurados y Cloudflare Workers para el despliegue. El resultado es un sitio que carga instantáneamente, cuesta casi nada de alojamiento y no requiere administración de bases de datos.
Por qué el enfoque "static-first" tiene sentido para un directorio
Muchas aplicaciones web optan por defecto por el renderizado en el servidor o arquitecturas de página única (SPA) porque parecen opciones seguras y modernas. Pero no todos los sitios reciben entradas dinámicas de usuarios en cada solicitud. Social Tools List es un recurso con una carga de lectura intensiva. Los datos de comparación cambian cuando subo una actualización, no cuando un visitante refresca la página. Renderizar el HTML de antemano elimina la necesidad de realizar consultas a la base de datos en el edge, la compilación de plantillas sobre la marcha o la sobrecarga de hidratación en el navegador. Genero el sitio en el momento de la construcción (build time), despliego los archivos estáticos y dejo que un worker ligero se encargue del envoltorio (wrapper). Esto mantiene bajos los tiempos de respuesta y elimina toda una clase de fallos en tiempo de ejecución.
Almacena los datos en TypeScript, no en una base de datos
No utilizo una base de datos. Cada herramienta en el directorio se define como un objeto TypeScript con un slug, nombre, dominio y un array de workflows compatibles. Una entrada típica se ve así:
{
slug: 'buffer',
name: 'Buffer',
domain: 'buffer.com',
workflows: ['scheduling', 'analytics']
}
Almacenar los datos en el mismo lenguaje con el que se construye el sitio tiene dos beneficios inmediatos. Primero, los pull requests se convierten en revisiones de contenido. Cuando añado una herramienta, el diff muestra los campos y valores exactos, y un compañero puede detectar una errata o un dominio incorrecto sin tener que aprender a usar una interfaz de CMS. Segundo, el compilador de TypeScript impone la estructura de cada registro. Si olvido incluir un slug o escribo mal una clave de workflow, la construcción falla antes de que los datos erróneos lleguen a una página.
Una base de datos introduciría migraciones, cadenas de conexión, estrategias de caché y rutinas de respaldo. Para un directorio con unos pocos cientos de entradas que mantengo manualmente, esa sobrecarga es un lastre puro. Los datos estáticos en módulos de TypeScript son la opción correcta y más económica para este modelo. La parte de "correcta" es importante. No se trata solo de ahorrar dinero; se trata de eliminar capas de abstracción que resuelven problemas que no tengo.
Deja que Astro se encargue del enrutamiento y el renderizado
Astro genera una página HTML por cada herramienta a partir de una única ruta dinámica. Defino un componente de diseño (layout) y Astro genera automáticamente los metadatos, encabezados y datos estructurados para cada entrada. Debido a que el mismo conjunto de datos impulsa el índice principal, los centros de categorías de workflow y las páginas de detalles individuales, no hay posibilidad de que una tarjeta en la página de inicio muestre una descripción diferente a la de la propia página de detalles. En las configuraciones de CMS tradicionales, a menudo se observa una discrepancia: la API devuelve una versión, la caché otra y el renderizado en el cliente una tercera. La generación estática desde una única fuente de verdad evita eso.
La arquitectura de islas (islands architecture) de Astro también facilita la adición de pequeñas piezas interactivas sin contaminar toda la página con JavaScript. El sitio se entrega como HTML estático, y solo el script de filtrado hidrata su rincón específico del DOM. No hay un entorno de ejecución (runtime) de framework envolviendo todo el documento. Astro también trata los metadatos de la página como una prioridad de primer nivel. Cada página de herramienta obtiene su propia etiqueta de título y meta descripción derivadas directamente del registro de TypeScript, por lo que no necesito un plugin aparte o una librería de gestión de head.
Filtrado sin un framework
La búsqueda y el filtrado a menudo incitan a los desarrolladores a instalar React, Vue o una librería pesada de gestión de estado. Yo me resistí a eso. Astro renderiza la lista completa como HTML puro en el servidor. Un pequeño script de JavaScript vanilla, de menos de un kilobyte, se ejecuta en el navegador y alterna la propiedad display de los elementos de la lista basándose en una etiqueta de workflow o en una coincidencia de texto.
Servir el marcado completo puede parecer ineficiente si vienes de un entorno basado en APIs. Pero considera la sobrecarga de un enfoque dinámico típico. El navegador descarga un bundle de JavaScript, hidrata un árbol de componentes, llama a un endpoint, espera el JSON y luego renderiza las filas. Para un directorio que enumera menos de cien herramientas, ese ritual es más lento y menos fiable que ocultar divs que ya están en el documento. Mi script añade escuchadores de eventos a los botones de filtrado, lee un atributo data-workflow en cada fila y establece los elementos que no coinciden como ocultos. La operación tarda milisegundos.
Debido a que la lista está presente en el HTML inicial, el sitio es utilizable sin JavaScript. Los rastreadores de los motores de búsqueda ven cada enlace y cada descripción. Los usuarios con redes lentas o con bloqueadores de scripts siguen teniendo acceso al directorio completo. El filtrado es una mejora, no una barrera.
Sitemaps y Robots como Código
Los sitemaps y el robots.txt no son añadidos escritos a mano. Son rutas de Astro que consumen el mismo conjunto de datos y los mismos helpers de URL que
