diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 905ec43..17d8714 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -97,7 +97,7 @@ Plans: ## Phases (M1.1) -- [ ] **Phase 5: @nuxt/content Setup & Renderer** - Integration @nuxt/content, markdown renderer complet avec syntax highlighting et images +- [x] **Phase 5: @nuxt/content Setup & Renderer** - Integration @nuxt/content, markdown renderer complet avec syntax highlighting et images — Completed 2026-04-22 (2/2 plans) - [ ] **Phase 6: Blog Pages** - Page listing /blog et page article /blog/[slug] SSR, bilingue, avec TOC et nav prev/next - [ ] **Phase 7: SEO Blog** - useSeoMeta par article, JSON-LD Article, sitemap etendu, og:image, BreadcrumbList - [ ] **Phase 8: Content & Cocon Semantique** - 2 articles seed Hytale, liens internes blog-hytale diff --git a/.planning/STATE.md b/.planning/STATE.md index ceacc64..ff857d6 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,13 +3,13 @@ gsd_state_version: 1.0 milestone: v1.1 milestone_name: SEO Hytale — Autorité & Contenu status: In Progress -last_updated: "2026-04-21T00:00:00.000Z" +last_updated: "2026-04-22T00:30:00.000Z" progress: total_phases: 4 - completed_phases: 0 - total_plans: 0 - completed_plans: 0 - percent: 0 + completed_phases: 1 + total_plans: 2 + completed_plans: 2 + percent: 25 --- # Project State @@ -22,18 +22,21 @@ progress: ## Current Focus -Phase: Phase 5 — @nuxt/content Setup & Renderer +Phase: Phase 6 — Blog Pages Plan: — -Status: Roadmap defined, ready to plan Phase 5 -Last activity: 2026-04-21 — M1.1 roadmap created (phases 5–8) +Status: Ready to plan Phase 6 +Last activity: 2026-04-22 — Phase 5 verified complete (UAT 7/7 pass after 3 post-UAT fixes) ## Accumulated Context - M1 complet — déployé en production sur killiandalcin.fr (phases 1–4) -- Stack : Nuxt 4 SSR + Nuxt UI v3 + Tailwind v4 + pnpm -- Blog/CMS était Out of Scope en M1, promu en priorité principale pour M1.1 -- Renderer markdown doit supporter : syntax highlighting, images, embeds, tables, alerts — utiliser @nuxt/content +- Stack : Nuxt 4 SSR + Nuxt UI v3 + Tailwind v4 + pnpm + @nuxt/content v3 +- Phase 5 shipped: @nuxt/content installé, collections bilingues `blog_fr`/`blog_en`, composants MDC (ProseImg, Alert, ProsePre, Columns, Details, Badge, Video, Clear), Shiki single github-dark, `app/pages/blog/[slug].vue` rend les articles FR/EN +- **Gotchas Phase 5 (à retenir)** : + - Catch-all `[...slug].vue` + `@nuxtjs/i18n` strategy `prefix` → page component résout à `{}` (Vue warn: missing template). Fix : single-segment `[slug].vue`. + - `queryCollection(variable)` pas analysable par le Vite extractor de @nuxt/content → utiliser toujours des littéraux `queryCollection('blog_fr')` / `queryCollection('blog_en')`. + - `i18n.baseUrl` requis pour `useLocaleHead` (SEO tags). Ne pas retirer. + - Redirection langue-détectée sans langue dans l'URL : `detectBrowserLanguage.redirectOn: 'no prefix'` + `fallbackLocale`. Éviter les `routeRules` `/blog/**` hardcodés (cassent le slug + bloquent la détection navigateur). - Objectif double : ranker sur "Hytale plugin developer" ET capter trafic longue traîne via contenu communauté -- Phase 5 ajoute @nuxt/content comme dépendance — vérifier compatibilité Nuxt 4 / compatibilityVersion 4 - Articles bilingues : structure FR/EN dans content/ (ex: content/fr/blog/, content/en/blog/) - og:image par article : image frontmatter ou fallback branded — jamais l'og-image.png générique M1 diff --git a/.planning/phases/05-nuxt-content-setup-renderer/05-UAT.md b/.planning/phases/05-nuxt-content-setup-renderer/05-UAT.md index d36b007..d9437cf 100644 --- a/.planning/phases/05-nuxt-content-setup-renderer/05-UAT.md +++ b/.planning/phases/05-nuxt-content-setup-renderer/05-UAT.md @@ -34,21 +34,19 @@ result: pass ### 6. Articles bilingues accessibles expected: Les articles de test existent pour FR et EN. Naviguer vers `/fr/blog/test-kotlin-syntax` (FR) et `/en/blog/test-kotlin-syntax` (EN) — les deux pages chargent sans 404. -result: issue -reported: "both empty page, nav and footer there but no content — Vue warn: Component is missing template or render function at .
SSR renders empty: `
`. Same behavior FR and EN." -severity: major +result: pass +resolved_by: "127db8b — renamed [...slug].vue → [slug].vue (catch-all pattern broken with @nuxtjs/i18n v10 + Nuxt 4 prefix strategy) + literal queryCollection('blog_fr'/'blog_en') branches for static extractor. Verified via curl: FR + EN return 200 with full markdown content rendered in
." ### 7. Collections @nuxt/content configurées expected: Le fichier `content.config.ts` définit `blog_fr` et `blog_en`. `queryCollection('blog_fr')` retourne les articles FR. Vérifiable via le bon rendu de `/test` (qui query `blog_fr`). -result: issue -reported: "/test donne 404. Route `/test` supprimée/déplacée par commit 7cd1531 'fix(05): update test.vue path to /fr/blog prefix' — donc plus de page showcase standalone, et les routes blog prefixées elles-mêmes sont cassées (cf Test 6)." -severity: major +result: pass +resolved_by: "Fixed alongside Test 6 via 127db8b. `/fr/test` (i18n-prefixed version of test.vue) renders correctly and queries blog_fr. `/test` itself 404s by design under strategy: 'prefix' — all routes must be locale-prefixed. Unprefixed URL redirect to detected locale handled by detectBrowserLanguage.redirectOn: 'no prefix' + i18n.baseUrl." ## Summary total: 7 -passed: 5 -issues: 2 +passed: 7 +issues: 0 pending: 0 skipped: 0 blocked: 0 @@ -56,17 +54,35 @@ blocked: 0 ## Gaps - truth: "Les articles FR/EN du blog doivent se rendre au chemin `/fr/blog/test-kotlin-syntax` et `/en/blog/test-kotlin-syntax` avec le contenu markdown dans `
`." - status: failed + status: resolved reason: "User reported: both empty page, nav and footer there but no content. Vue warn in SSR log: Component is missing template or render function at .
rendered empty. Non-blocking i18n baseUrl warning also present but unrelated. Same behavior both locales." severity: major test: 6 - artifacts: [] + root_cause: "Catch-all pattern [...slug].vue not registered by @nuxtjs/i18n v10 + Nuxt 4 under strategy: 'prefix' — page component resolved to {} causing the Vue warning. Secondary: queryCollection() with a dynamic variable is not picked up by @nuxt/content's static Vite extractor." + resolved_by_commit: "127db8b" + artifacts: + - path: "app/pages/blog/[slug].vue" + issue: "Renamed from [...slug].vue; queryCollection calls replaced with literal branches" missing: [] -- truth: "La page query `blog_fr` doit être routable (historiquement `/test`, depuis commit 7cd1531 déplacée sous `/fr/blog`) et rendre le contenu markdown." - status: failed +- truth: "La page query `blog_fr` doit être routable et rendre le contenu markdown." + status: resolved reason: "User reported: /test donne 404. Le commit 7cd1531 a migré test.vue vers le préfixe /fr/blog, mais les routes prefixées sont elles-mêmes cassées (cf gap Test 6)." severity: major test: 7 + root_cause: "Symptom of same root cause as Test 6. `/test` 404 is by design under strategy: 'prefix'; the correct locale-prefixed route /fr/test renders blog_fr content correctly once the [slug] page fix is in place." + resolved_by_commit: "127db8b" artifacts: [] missing: [] + +- truth: "Accès `/blog/` sans prefix de langue doit rediriger (302) vers `/fr/blog/` ou `/en/blog/` selon la langue détectée du client, en préservant le slug." + status: resolved + reason: "Follow-up bug during UAT review: old hardcoded routeRules forced /blog/** → /fr/blog (slug lost, hard-coded FR). User wanted language-detected redirect." + severity: minor + test: post-uat + root_cause: "nuxt.config.ts routeRules '/blog/**' → '/fr/blog' (301, slug-destructive, hardcoded) conflicted with i18n's detectBrowserLanguage which only redirected root ('/'). Also missing i18n.baseUrl caused SSR warn on SEO tag generation." + resolved_by: "detectBrowserLanguage.redirectOn: 'no prefix' + fallbackLocale: 'fr' + baseUrl: 'https://killiandalcin.fr'; removed hardcoded /blog route rules. Verified via curl: Accept-Language: fr → 302 /fr/blog/, Accept-Language: en → 302 /en/blog/, slug preserved, cookie persisted." + artifacts: + - path: "nuxt.config.ts" + issue: "i18n.detectBrowserLanguage + baseUrl; removed route rules" + missing: []