Aller au contenu principal

Bref. J'ai geeké.

Mis à jour le 10 min de lecture

Architecture

Ce blog est simple en apparence. Mais sous le capot, il repose sur une architecture que j’ai voulue à la fois légère, économique et extensible. Voici les choix qui l’ont façonnée.

Un monorepo pnpm (workspaces)

Le projet est organisé en monorepo avec deux packages distincts :

  • apps/blog : le site Astro, compilé en HTML/CSS/JS statique
  • apps/api : un Cloudflare Worker TypeScript qui expose les endpoints dynamiques

Cette séparation n’est pas cosmétique. Elle reflète une réalité technique : le blog n’a pas besoin de serveur. Chaque page est générée à la compilation. Seule la recherche sémantique nécessite un runtime et c’est précisément le rôle du Worker.

Cloudflare Workers Assets

Le modèle de déploiement repose sur les Cloudflare Workers Assets. Un Worker unique fait deux choses :

  1. Il sert les fichiers statiques générés par Astro (via le binding ASSETS)
  2. Il route /api/* vers les handlers TypeScript de l’API
wrangler.jsonc (root)
├── main: apps/api/src/index.ts   ← le Worker
└── assets: apps/blog/dist/       ← le site statique

C’est fondamentalement différent de Cloudflare Pages : ici, le Worker contrôle tout. Il n’y a pas de plateforme intermédiaire, pas de magie cachée. Le fetch handler reçoit chaque requête et décide quoi faire.

Astro 100% statique

apps/blog utilise Astro en mode output: 'static' sans adapter. Zéro runtime côté blog. Le résultat du build est un dossier dist/ de fichiers HTML, CSS, JS et assets, servi directement par le Worker.

Les images Open Graph (les previews partagées sur les réseaux) sont également générées statiquement à la compilation via getStaticPaths(), aucun rendu à la volée.

Recherche sémantique

La barre de recherche combine deux approches :

Pagefind gère la recherche textuelle classique. L’index est généré au build et embarqué dans les assets statiques. Zéro requête réseau pour la recherche par mots-clés.

La recherche sémantique entre en jeu pour les requêtes longues (plus de 3 mots). Elle fonctionne en deux temps :

  1. À la compilation, les titres, descriptions et tags de chaque article sont transformés en vecteurs par Cloudflare Workers AI (modèle @cf/baai/bge-small-en-v1.5) et stockés dans Cloudflare Vectorize
  2. À la requête, le terme de recherche est lui aussi vectorisé, puis comparé aux articles via une recherche de similarité cosinus

Le résultat : une recherche qui comprend le sens, pas seulement les mots. Chercher “impact de l’IA sur les développeurs” remonte l’article sur les artisans du web, même sans correspondance de mots-clés exacte.

Cloudflare R2 & archivage des révisions

Le système de révisions repose sur Cloudflare R2, le stockage objet compatible S3 de Cloudflare.

À chaque build, une intégration Astro (revisionArchiver) se déclenche sur le hook astro:build:start. Elle lit les frontmatters de tous les articles, identifie la révision la plus récente, et archive le contenu MDX correspondant dans R2 selon la convention :

articles/{slug}/revisions/{YYYY-MM-DD}/{fichier}.mdx

Les révisions antérieures, déjà présentes dans R2 depuis les builds précédents, alimentent getStaticPaths() pendant la génération : chaque chapitre de chaque révision archivée devient une page HTML statique. Zéro runtime, zéro reconstruction à la volée.

L’intégration est isolée dans l’hook de build pour éviter de passer par le module runner de Vite, qui ne supporte pas les modules CommonJS comme le SDK AWS au moment de l’évaluation de la config.

CI natif Cloudflare Workers

Le déploiement est entièrement géré par le Cloudflare Workers CI (GitHub → Cloudflare pipeline). À chaque push sur main :

  1. pnpm --filter blog build génère le site statique
  2. wrangler deploy déploie le Worker avec les assets

Pas de GitHub Actions, pas de configuration YAML. Le pipeline est configuré directement dans le dashboard Cloudflare.

Le résultat

Un site qui se charge en quelques dizaines de millisecondes, déployé sur le réseau edge de Cloudflare, avec une recherche sémantique gratuite. L’essentiel du coût est le temps de développement, l’infrastructure, elle, est quasi gratuite à cette échelle.

Révisions

  1. initial

Articles similaires

Écoconception

Empreinte environnementale estimée · Modèle SWD v4 · 442 g CO₂eq/kWh

Poids de la page
Énergie par requête
Budget carbone du build