Frontend — site Astro (portfolio + blog)
Application Astro 6 : pages localisées /fr/... et /en/..., projets dans src/content/work/, articles de blog issus de blog_content/ (collection blog), thème clair / sombre, formulaire de contact vers l’API FastAPI.
Prérequis
- Node.js 22+ (voir
package.json→engines) - Fichier
.envà la racine du dépôt (copie de.env.example) pourPUBLIC_API_BASE_URL,PUBLIC_SITE_URL, etc.
Commandes
| Commande | Action |
|---|---|
npm install |
Dépendances |
npm run dev |
Serveur de dev http://localhost:3000 (predev : sync CV + sync blog) |
npm run build |
Build production → dist/ (prebuild : sync + validation i18n) |
npm run preview |
Prévisualisation du build (port 3000) |
npm run check |
astro check (typage / diagnostics) — alias npm run lint |
npm run i18n:validate |
Cohérence des clés FR/EN (blueprints/ui.keys.json) |
npm run sync:blog-content |
Copie des médias blog_content/ → public/blog-assets/ et public/posts/<année>/ |
npm run sync:cv-data |
Synchronise les données CV vers public/json/ |
Le placeholder {{EXP_YEARS}} est calculé automatiquement : année courante − 2022
(src/lib/experience-years.ts · constante EXPERIENCE_START_YEAR).
En 2026 → 4 ans ; en 2027 → 5 ans, sans modifier les textes.
Appliqué via pickCvInterpolated / pickCvListInterpolated (cv-i18n.ts) ou tWithExperience (i18n/t.ts) :
résumé CV, About, métriques accueil, chapô profil (home.profile.lead).
Côté API : apps/backend/app/core/experience_years.py (même formule).
Documentation Astro : https://docs.astro.build
Blog et contenu
Architecture hybride : Git (édition) → Astro (SSG) · Neon (API) · GCS (médias prod).
- Markdown source :
blog_content/<année>/posts/<catégorie>/à la racine du monorepo. - Médias locaux :
npm run sync:blog-content/make blog-sync→public/posts/,public/blog-assets/. - Médias prod :
PUBLIC_GCS_MEDIA_BASE(build Docker) —blogCoverSrcpréfixe les chemins relatifs. - Schéma et loader :
src/content.config.ts. - Helpers (slug, langue, dates, covers) :
src/lib/blog.ts. - Guide : docs/prompts/_PostForBlog.md · blog_content/README.md.
Démos en ligne (plateformes)
- Données :
src/data/platform-demos.ts(URL*.senlab-ai.org, tags, GIF optionnel sous/assets/platforms/…). - Textes des cartes : clés
home.platforms.*danstranslations/fr.jsoneten.json(titres sobres, sans pictogrammes dans l’UI). - Composants :
PlatformsShowcase.astro(accueil),HomeHeroStage.astro,HomeLabsBand.astro.
Analytics (GA4, GTM, Clarity, PostHog EU)
- Modules :
src/lib/analytics/· composantssrc/components/analytics/ - Variables (
.envracine monorepo,vite.envDir) :PUBLIC_GA_MEASUREMENT_ID,PUBLIC_GTM_CONTAINER_IDPUBLIC_GOOGLE_SITE_VERIFICATION(Search Console)PUBLIC_CLARITY_PROJECT_ID,PUBLIC_POSTHOG_KEY,PUBLIC_POSTHOG_HOSTPUBLIC_ENABLE_ANALYTICS
- RGPD : bannière cookies + Consent Mode v2 — voir docs/analytics/cookies.md
- PostHog : docs/analytics/posthog.md
- GTM : docs/analytics/gtm.md
API contact
Le formulaire envoie en général vers POST /api/contact sur le backend. En développement, Astro proxy souvent /api vers http://localhost:8080 (voir astro.config.mjs). Variable optionnelle : PUBLIC_API_BASE_URL pour forcer l’URL du navigateur en build / prod.
Origine du template
Ce dépôt est issu du template portfolio Astro (npm create astro@latest -- --template portfolio) ; la structure a été étendue (i18n, blog, Docker, FastAPI). Les badges « Open in StackBlitz » du template d’origine ne s’appliquent plus forcément à ce monorepo — voir le README.md racine.