Costruire un sito di directory sembra banale finché non ti ritrovi a collegare database, livelli di caching e framework front-end reattivi solo per visualizzare ciò che è, essenzialmente, un indice curato. Recentemente ho creato Social Tools List, un sito per confrontare software per i social media. Il mio obiettivo era metterlo online rapidamente, mantenerlo veloce ed evitare di gestire un'infrastruttura per contenuti che cambiano solo quando aggiungo o aggiorno uno strumento. Ho scelto uno stack static-first: Astro per la generazione del sito, TypeScript per i dati strutturati e Cloudflare Workers per il deployment. Il risultato è un sito che si carica istantaneamente, costa quasi zero in termini di hosting e non richiede l'amministrazione di un database.

Perché l'approccio static-first ha senso per una directory

Molte applicazioni web scelgono di default il rendering lato server o architetture single-page perché sembrano scelte sicure e moderne. Ma non tutti i siti ricevono input dinamici dagli utenti a ogni richiesta. Social Tools List è una risorsa ad alta intensità di lettura (read-heavy). I dati di confronto cambiano quando pubblico un aggiornamento, non quando un visitatore ricarica la pagina. Il rendering dell'HTML in anticipo elimina la necessità di query al database all'edge, della compilazione dei template al volo o dell'overhead di idratazione nel browser. Genero il sito al momento della build, distribuisco i file statici e lascio che un worker leggero gestisca il wrapper. Questo mantiene bassi i tempi di risposta ed elimina un'intera categoria di errori di runtime.

Memorizzare i dati in TypeScript, non in un database

Non uso un database. Ogni strumento nella directory è definito come un oggetto TypeScript con uno slug, un nome, un dominio e un array di workflow supportati. Una voce tipica appare così:

{
  slug: 'buffer',
  name: 'Buffer',
  domain: 'buffer.com',
  workflows: ['scheduling', 'analytics']
}

Memorizzare i dati nello stesso linguaggio utilizzato per costruire il sito offre due vantaggi immediati. Primo, le pull request diventano revisioni di contenuti. Quando aggiungo uno strumento, il diff mostra i campi e i valori esatti, e un collega può individuare un refuso o un dominio errato senza dover imparare a usare l'interfaccia di un CMS. Secondo, il compilatore TypeScript impone la struttura di ogni record. Se dimentico di includere uno slug o sbaglio a scrivere una chiave di un workflow, la build fallisce prima che i dati errati raggiungano una pagina.

Un database introdurrebbe migrazioni, stringhe di connessione, strategie di caching e routine di backup. Per una directory con poche centinaia di voci che gestisco manualmente, tale overhead è un puro rallentamento. I dati statici nei moduli TypeScript sono la scelta più economica e corretta per questo modello. La parte "corretta" è fondamentale. Non si tratta solo di risparmiare denaro; si tratta di rimuovere strati di astrazione che risolvono problemi che non ho.

Lasciare che Astro gestisca routing e rendering

Astro genera una pagina HTML per ogni strumento partendo da un'unica rotta dinamica. Definisco un singolo componente layout e Astro genera automaticamente metadati, intestazioni e dati strutturati per ogni voce. Poiché lo stesso set di dati alimenta l'indice principale, i hub delle categorie di workflow e le singole pagine di dettaglio, non c'è rischio che una card nella home page mostri una descrizione diversa rispetto alla pagina di dettaglio stessa. Nelle configurazioni CMS tradizionali, si nota spesso una divergenza: l'API restituisce una versione, la cache un'altra e il rendering lato client una terza. La generazione statica da un'unica fonte di verità (single source of truth) previene questo problema.

L'architettura a isole (island architecture) di Astro rende inoltre facile aggiungere piccoli elementi interattivi senza "inquinare" l'intera pagina con JavaScript. Il sito viene distribuito come HTML statico e solo lo script di filtraggio idrata la sua specifica porzione di DOM. Non c'è un runtime di un framework che avvolge l'intero documento. Astro tratta inoltre i metadati della pagina come una priorità assoluta. Ogni pagina dello strumento riceve il proprio tag title e la propria meta descrizione derivati direttamente dal record TypeScript, quindi non ho bisogno di un plugin separato o di una libreria per la gestione dell'head.

Filtraggio senza un framework

La ricerca e il filtraggio spesso spingono gli sviluppatori a installare React, Vue o una pesante libreria di gestione dello stato. Io ho resistito. Astro renderizza l'elenco completo come semplice HTML sul server. Un piccolo script in vanilla JavaScript, meno di un kilobyte, viene eseguito nel browser e alterna la proprietà display degli elementi della lista in base a un tag di workflow o a una corrispondenza testuale.

Servire l'intero markup può sembrare inefficiente se si proviene da un background basato sulle API. Ma considera il sovraccarico di un tipico approccio dinamico. Il browser scarica un bundle JavaScript, idrata un albero di componenti, chiama un endpoint, attende il JSON e poi renderizza le righe. Per una directory che elenca meno di cento strumenti, quel rituale è più lento e meno affidabile che nascondere dei div già presenti nel documento. Il mio script attacca gli event listener ai pulsanti di filtro, legge un attributo data-workflow su ogni riga e imposta come hidden gli elementi non corrispondenti. L'operazione richiede millisecondi.

Poiché l'elenco è presente nell'HTML iniziale, il sito è utilizzabile senza JavaScript. I crawler dei motori di ricerca vedono ogni link e ogni descrizione. Gli utenti con connessioni lente o con script blocker ricevono comunque la directory completa. Il filtraggio è un potenziamento, non un vincolo.

Sitemaps e Robots come codice

Sitemaps e robots.txt non sono aggiunte postume scritte a mano. Sono rotte Astro che consumano lo stesso dataset e gli stessi helper URL di