Active Astro i18n avec `defaultLocale: fr` et `prefixDefaultLocale: false`
— les URLs FR restent canoniques à la racine, l'EN vit sous `/en/*` pour
ne pas casser le SEO existant.
Architecture :
- `src/i18n/{types,fr,en,index}.ts` — dico FR fait foi (Dict inféré),
EN doit matcher la shape ; helpers `getTranslations(locale)` et
`getAlternateUrl()` pour le language switcher.
- `Layout.astro` lit `Astro.currentLocale`, propage `locale` aux
composants React, set `<html lang>`, og:locale + alt, hreflang.
- `SiteHeader` expose un lien switcher FR↔EN qui préserve la page.
- Toutes les sections (Hero, Stats, Promise, HowItWorks, Gamification,
AutoBanking, Legal, Pricing, FAQ, FinalCTA, Footnotes, SiteFooter)
acceptent une prop `locale` et tirent leurs chaînes du dico.
Pages EN créées :
- `/en/` — home complète
- `/en/blog`, `/en/changelog` — chrome traduit, contenu reste dans la
langue de rédaction (les .md changelog + posts API sont FR)
- `/en/cgv`, `/en/mentions-legales`, `/en/confidentialite` — résumés
courts ; la version juridiquement contraignante reste la FR (droit
français, conformité GDPR/LCEN/LME).
Sitemap mis à jour avec entrées FR/EN + `xhtml:link rel="alternate"`.
Pas de détection auto via Accept-Language pour l'instant — le switcher
header suffit en V1.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
66 lines
2.3 KiB
JavaScript
66 lines
2.3 KiB
JavaScript
// @ts-check
|
|
import { defineConfig } from "astro/config";
|
|
import react from "@astrojs/react";
|
|
import node from "@astrojs/node";
|
|
import tailwindcss from "@tailwindcss/vite";
|
|
|
|
/**
|
|
* Astro 6 — landing publique + blog rubis.pro.
|
|
*
|
|
* Stratégie de rendu (cf. /docs/tech/architecture.md §3) :
|
|
* - `output: "server"` → SSR par défaut, on opt-out par page avec
|
|
* `export const prerender = true;` pour les pages statiques.
|
|
* - Landing + pages légales : `prerender = true` (HTML figé au build, ultra-rapide).
|
|
* - Blog (/blog, /blog/:slug) : SSR pur, fetch Adonis API à la requête, cache
|
|
* HTTP côté Traefik / nginx pour absorber les pics — publish admin = immédiat.
|
|
*
|
|
* Adapter Node standalone : produit un serveur autonome dans `dist/server/`,
|
|
* démarré par `node ./dist/server/entry.mjs` dans le container K3s.
|
|
*/
|
|
export default defineConfig({
|
|
site: "https://rubis.pro",
|
|
output: "server",
|
|
adapter: node({
|
|
mode: "standalone",
|
|
}),
|
|
i18n: {
|
|
// FR par défaut, EN sous /en/* — `prefixDefaultLocale: false` garde
|
|
// les URLs FR canoniques à la racine pour ne pas casser le SEO existant.
|
|
defaultLocale: "fr",
|
|
locales: ["fr", "en"],
|
|
routing: {
|
|
prefixDefaultLocale: false,
|
|
},
|
|
},
|
|
integrations: [
|
|
react(),
|
|
],
|
|
build: {
|
|
/**
|
|
* Inline TOUS les <link rel="stylesheet"> dans le HTML. Élimine 80 ms
|
|
* de render-blocking sur le critical path LCP en faisant disparaître
|
|
* la requête `/_astro/Layout.<hash>.css` (~42 KiB) du chemin critique
|
|
* — cf. audit Lighthouse render-blocking-resources.
|
|
*
|
|
* Tradeoff assumé : le HTML pèse +42 KiB par page (mais ~10 KiB
|
|
* gzippé) au lieu d'avoir une feuille séparée cacheable. Pour une
|
|
* landing à 5 pages prerendered c'est négligeable, et sur SSR le
|
|
* gain LCP est plus important que la mutualisation cross-page (le
|
|
* cache HTTP côté Traefik garde déjà les pages prêtes).
|
|
*
|
|
* `"auto"` aurait été plus conservateur mais le seuil par défaut
|
|
* (`vite.build.assetsInlineLimit` = 4 KiB) est inférieur à la taille
|
|
* de Layout.css → la feuille restait externe et le render-blocking
|
|
* persistait.
|
|
*/
|
|
inlineStylesheets: "always",
|
|
},
|
|
vite: {
|
|
plugins: [tailwindcss()],
|
|
},
|
|
server: {
|
|
host: "0.0.0.0",
|
|
port: 5174,
|
|
},
|
|
});
|