@@ -28,83 +28,84 @@ Le site LyonJS tourne sur Next.js 16 (App Router, React 19, standalone output) d
2828
2929### Pages et routes
3030
31- | Next.js (App Router) | Astro | Effort |
32- | ---| ---| ---|
33- | ` app/page.tsx ` | ` src/pages/index.astro ` | Faible |
34- | ` app/a-propos/page.tsx ` | ` src/pages/a-propos.astro ` | Faible |
35- | ` app/code-de-conduite/page.tsx ` | ` src/pages/code-de-conduite.astro ` | Faible |
36- | ` app/devenir-sponsor/page.tsx ` | ` src/pages/devenir-sponsor.astro ` | Faible |
37- | ` app/budget-et-financement/page.tsx ` | ` src/pages/budget-et-financement.astro ` | Faible |
38- | ` app/evenements-precedents/page.tsx ` | ` src/pages/evenements-precedents/index.astro ` | Faible |
39- | ` app/evenements-precedents/[year]/page.tsx ` | ` src/pages/evenements-precedents/[year].astro ` avec ` getStaticPaths() ` | Moyen |
40- | ` app/evenement/[slug]/page.tsx ` | ` src/pages/evenement/[slug].astro ` avec ` getStaticPaths() ` | Moyen |
41- | ` app/lyonjs-100/page.tsx ` | ` src/pages/lyonjs-100.astro ` | Faible |
42- | ` app/not-found.tsx ` | ` src/pages/404.astro ` | Faible |
43- | ` app/layout.tsx ` | ` src/layouts/Layout.astro ` | Moyen |
44- | ` app/robots.ts ` | ` src/pages/robots.txt.ts ` | Faible |
45- | ` app/sitemap.ts ` | ` @astrojs/sitemap ` integration | Faible |
31+ | Next.js (App Router) | Astro | Effort |
32+ | ------------------------------------------- | ---------------------------------------------------------------------- | ------ |
33+ | ` app/page.tsx ` | ` src/pages/index.astro ` | Faible |
34+ | ` app/a-propos/page.tsx ` | ` src/pages/a-propos.astro ` | Faible |
35+ | ` app/code-de-conduite/page.tsx ` | ` src/pages/code-de-conduite.astro ` | Faible |
36+ | ` app/devenir-sponsor/page.tsx ` | ` src/pages/devenir-sponsor.astro ` | Faible |
37+ | ` app/budget-et-financement/page.tsx ` | ` src/pages/budget-et-financement.astro ` | Faible |
38+ | ` app/evenements-precedents/page.tsx ` | ` src/pages/evenements-precedents/index.astro ` | Faible |
39+ | ` app/evenements-precedents/[year]/page.tsx ` | ` src/pages/evenements-precedents/[year].astro ` avec ` getStaticPaths() ` | Moyen |
40+ | ` app/evenement/[slug]/page.tsx ` | ` src/pages/evenement/[slug].astro ` avec ` getStaticPaths() ` | Moyen |
41+ | ` app/lyonjs-100/page.tsx ` | ` src/pages/lyonjs-100.astro ` | Faible |
42+ | ` app/not-found.tsx ` | ` src/pages/404.astro ` | Faible |
43+ | ` app/layout.tsx ` | ` src/layouts/Layout.astro ` | Moyen |
44+ | ` app/robots.ts ` | ` src/pages/robots.txt.ts ` | Faible |
45+ | ` app/sitemap.ts ` | ` @astrojs/sitemap ` integration | Faible |
4646
4747### Data fetching
4848
49- | Pattern Next.js | Equivalent Astro | Notes |
50- | ---| ---| ---|
51- | ` generateStaticParams() ` | ` getStaticPaths() ` | Meme concept, syntaxe differente |
52- | ` revalidate = 3600 ` (ISR) | Rebuild CI ou SSR mode | Pas d'ISR en SSG, voir section dediee |
53- | ` React cache() ` | Appel direct dans le frontmatter | Pas de deduplication automatique, mais les appels sont dans le frontmatter donc executes une seule fois |
54- | Server components async | Composants Astro (async par defaut) | Transition naturelle |
49+ | Pattern Next.js | Equivalent Astro | Notes |
50+ | ------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------- |
51+ | ` generateStaticParams() ` | ` getStaticPaths() ` | Meme concept, syntaxe differente |
52+ | ` revalidate = 3600 ` (ISR) | Rebuild CI ou SSR mode | Pas d'ISR en SSG, voir section dediee |
53+ | ` React cache() ` | Appel direct dans le frontmatter | Pas de deduplication automatique, mais les appels sont dans le frontmatter donc executes une seule fois |
54+ | Server components async | Composants Astro (async par defaut) | Transition naturelle |
5555
5656### Composants interactifs (React islands)
5757
5858Ces 7 composants necessitent du JS client et deviendraient des islands React dans Astro :
5959
60- | Composant | Utilise | Directive Astro |
61- | ---| ---| ---|
62- | ` HomeHero.tsx ` | motion (animations) | ` client:load ` |
63- | ` Number.tsx ` | motion, next/font | ` client:visible ` |
64- | ` Collapsible.tsx ` | useState | ` client:visible ` |
65- | ` NavLink.tsx ` | next/navigation (usePathname) | ` client:load ` |
66- | ` MobileNavigation.tsx ` | useState, usePathname, useEffect | ` client:load ` |
67- | ` PhotoAlbum.tsx ` | useState, dynamic import lightbox | ` client:visible ` |
68- | ` EventCard.tsx ` | dynamic import react-markdown | ` client:visible ` |
60+ | Composant | Utilise | Directive Astro |
61+ | ---------------------- | --------------------------------- | ---------------- |
62+ | ` HomeHero.tsx ` | motion (animations) | ` client:load ` |
63+ | ` Number.tsx ` | motion, next/font | ` client:visible ` |
64+ | ` Collapsible.tsx ` | useState | ` client:visible ` |
65+ | ` NavLink.tsx ` | next/navigation (usePathname) | ` client:load ` |
66+ | ` MobileNavigation.tsx ` | useState, usePathname, useEffect | ` client:load ` |
67+ | ` PhotoAlbum.tsx ` | useState, dynamic import lightbox | ` client:visible ` |
68+ | ` EventCard.tsx ` | dynamic import react-markdown | ` client:visible ` |
6969
7070** Note** : ` NavLink ` et ` MobileNavigation ` utilisent ` usePathname() ` de ` next/navigation ` . A remplacer par ` window.location.pathname ` ou ` Astro.url.pathname ` (partie serveur) + event listeners cote client.
7171
7272### Images
7373
74- | Next.js | Astro |
75- | ---| ---|
76- | ` next/image ` (8 fichiers) | ` astro:assets ` ` <Image> ` component |
77- | ` remotePatterns ` dans next.config | ` image.domains ` dans astro.config |
78- | Optimisation automatique (sharp) | Optimisation automatique (sharp) |
74+ | Next.js | Astro |
75+ | --------------------------------- | ---------------------------------- |
76+ | ` next/image ` (8 fichiers) | ` astro:assets ` ` <Image> ` component |
77+ | ` remotePatterns ` dans next.config | ` image.domains ` dans astro.config |
78+ | Optimisation automatique (sharp) | Optimisation automatique (sharp) |
7979
8080Le composant ` <Image> ` d'Astro offre les memes fonctionnalites (lazy loading, format moderne, responsive). Migration directe.
8181
8282### MDX
8383
84- | Next.js | Astro |
85- | ---| ---|
86- | ` @next/mdx ` + ` mdx-components.tsx ` | ` @astrojs/mdx ` integration |
87- | 5 fichiers ` .mdx ` | Meme fichiers, syntaxe compatible |
88- | Custom components mapping | Components passees via props dans le layout |
84+ | Next.js | Astro |
85+ | ---------------------------------- | ------------------------------------------- |
86+ | ` @next/mdx ` + ` mdx-components.tsx ` | ` @astrojs/mdx ` integration |
87+ | 5 fichiers ` .mdx ` | Meme fichiers, syntaxe compatible |
88+ | Custom components mapping | Components passees via props dans le layout |
8989
9090Astro a un excellent support MDX natif. Les composants React embarques dans le MDX (` <Orgas /> ` , ` <Socials /> ` ) peuvent rester en React via les islands ou etre convertis en composants Astro.
9191
9292### Metadata / SEO
9393
94- | Next.js | Astro |
95- | ---| ---|
96- | ` export const metadata: Metadata ` | ` <head> ` dans le layout + props |
97- | ` generateMetadata() ` | Props dynamiques dans le layout |
98- | ` opengraph-image.tsx ` (6 fichiers) | ` satori ` + ` sharp ` au build (voir ci-dessous) |
99- | ` robots.ts ` | ` src/pages/robots.txt.ts ` |
100- | ` sitemap.ts ` | ` @astrojs/sitemap ` |
101- | JSON-LD structured data | ` <script type="application/ld+json"> ` dans le layout |
94+ | Next.js | Astro |
95+ | ---------------------------------- | ---------------------------------------------------- |
96+ | ` export const metadata: Metadata ` | ` <head> ` dans le layout + props |
97+ | ` generateMetadata() ` | Props dynamiques dans le layout |
98+ | ` opengraph-image.tsx ` (6 fichiers) | ` satori ` + ` sharp ` au build (voir ci-dessous) |
99+ | ` robots.ts ` | ` src/pages/robots.txt.ts ` |
100+ | ` sitemap.ts ` | ` @astrojs/sitemap ` |
101+ | JSON-LD structured data | ` <script type="application/ld+json"> ` dans le layout |
102102
103103### OG Images dynamiques
104104
105105C'est le point le plus complexe. Actuellement 6 routes generent des images OG via ` next/og ` (basee sur ` satori ` ).
106106
107107** Options avec Astro** :
108+
1081091 . ** ` astro-og-canvas ` ** : Librairie communautaire pour generer des OG images au build
1091102 . ** ` satori ` + ` sharp ` directement** : Meme moteur que ` next/og ` , utilisable dans ` getStaticPaths() ` pour generer les images au build
1101113 . ** Service externe** : Generer via un endpoint API separe
@@ -114,10 +115,12 @@ Recommandation : option 2, generer les images au build avec `satori` directement
114115### Middleware / Headers de securite
115116
116117Le ` middleware.ts ` actuel gere :
118+
117119- Nonce CSP pour les scripts inline
118120- Headers de securite (X-Frame-Options, etc.)
119121
120122** Avec Astro** :
123+
121124- Les headers statiques (X-Frame-Options, etc.) → configures dans le Dockerfile / reverse proxy / ` astro.config.mjs ` en mode SSR
122125- Le nonce CSP → plus necessaire si pas de scripts inline. Sinon, middleware Astro en mode SSR.
123126- Alternative : configurer les headers directement dans Scaleway Serverless Containers
@@ -128,12 +131,12 @@ Une seule redirection (`/lyonjs-100/programme` → `/lyonjs-100`) → `redirects
128131
129132### Styles
130133
131- | Next.js | Astro |
132- | ---| ---|
134+ | Next.js | Astro |
135+ | -------------------------- | -------------------------------- |
133136| CSS Modules (20+ fichiers) | CSS Modules supportes nativement |
134- | ` globals.css ` | Import global dans le layout |
135- | ` normalize.css ` | Import dans le layout |
136- | ` classnames ` | Continue a fonctionner |
137+ | ` globals.css ` | Import global dans le layout |
138+ | ` normalize.css ` | Import dans le layout |
139+ | ` classnames ` | Continue a fonctionner |
137140
138141Migration transparente, rien a changer.
139142
@@ -143,11 +146,11 @@ Le site utilise `revalidate = 3600` sur plusieurs pages pour actualiser les donn
143146
144147** Options avec Astro** :
145148
146- | Option | Description | Impact |
147- | ---| ---| ---|
148- | ** SSG + rebuild cron** | Workflow CI schedule qui rebuild et redeploy toutes les heures | Simple, pas de serveur Node, image Docker minimale (nginx) |
149- | ** SSR mode** | Astro en mode ` output: 'server' ` avec cache headers | Garde le comportement ISR, mais necessite Node.js runtime |
150- | ** Hybride** | ` output: 'hybrid' ` — pages statiques par defaut, quelques routes SSR | Meilleur compromis |
149+ | Option | Description | Impact |
150+ | ---------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------- |
151+ | ** SSG + rebuild cron** | Workflow CI schedule qui rebuild et redeploy toutes les heures | Simple, pas de serveur Node, image Docker minimale (nginx) |
152+ | ** SSR mode** | Astro en mode ` output: 'server' ` avec cache headers | Garde le comportement ISR, mais necessite Node.js runtime |
153+ | ** Hybride** | ` output: 'hybrid' ` — pages statiques par defaut, quelques routes SSR | Meilleur compromis |
151154
152155** Recommandation** : SSG + rebuild cron. Le contenu change rarement (quelques meetups par mois). Un rebuild horaire ou quotidien suffit largement. Cela permet de deployer une image Docker statique (nginx) au lieu d'un runtime Node.js.
153156
@@ -200,19 +203,19 @@ Le site utilise `revalidate = 3600` sur plusieurs pages pour actualiser les donn
200203
201204## Estimation de la complexite
202205
203- | Element | Fichiers | Complexite |
204- | ---| ---| ---|
205- | Pages statiques (MDX) | 5 | Faible |
206- | Layout + Header + Footer | 3 | Faible |
207- | Navigation (mobile, links) | 3 | Moyenne |
208- | Homepage (hero, numbers, replays) | 5 | Moyenne |
209- | Pages dynamiques (events, years) | 4 | Moyenne |
210- | Module Meetup API | 5 | Faible (reutilisable) |
211- | Data files | 9 | Aucune (reutilisable) |
212- | OG images | 6 | Elevee |
213- | Middleware → headers | 1 | Faible |
214- | Tests Playwright | 3 | Faible (memes URLs) |
215- | CI/CD + Docker | 3 | Faible |
206+ | Element | Fichiers | Complexite |
207+ | --------------------------------- | -------- | --------------------- |
208+ | Pages statiques (MDX) | 5 | Faible |
209+ | Layout + Header + Footer | 3 | Faible |
210+ | Navigation (mobile, links) | 3 | Moyenne |
211+ | Homepage (hero, numbers, replays) | 5 | Moyenne |
212+ | Pages dynamiques (events, years) | 4 | Moyenne |
213+ | Module Meetup API | 5 | Faible (reutilisable) |
214+ | Data files | 9 | Aucune (reutilisable) |
215+ | OG images | 6 | Elevee |
216+ | Middleware → headers | 1 | Faible |
217+ | Tests Playwright | 3 | Faible (memes URLs) |
218+ | CI/CD + Docker | 3 | Faible |
216219
217220** Code reutilisable sans modification** : tout le dossier ` data/ ` , le module ` meetup/ ` (queries, API), les utilitaires (` dateUtils ` , ` slugify ` , ` overrideEvent ` ), les types, ` classnames ` , CSS Modules.
218221
0 commit comments