feat(ROADMAP): mark Phase 5 as completed and update project state; prepare for Phase 6 planning
This commit is contained in:
@@ -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
|
||||
|
||||
+15
-12
@@ -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
|
||||
|
||||
@@ -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 <Anonymous> is missing template or render function at <RouteProvider key=\"/fr/blog/test-kotlin-syntax\">. <main> SSR renders empty: `<main class=\"flex-1\"><!--[--><!----><!--]--></main>`. 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 <main>."
|
||||
|
||||
### 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 `<main>`."
|
||||
status: failed
|
||||
status: resolved
|
||||
reason: "User reported: both empty page, nav and footer there but no content. Vue warn in SSR log: Component <Anonymous> is missing template or render function at <RouteProvider key=\"/fr/blog/test-kotlin-syntax\">. <main class=\"flex-1\"> 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/<slug>` sans prefix de langue doit rediriger (302) vers `/fr/blog/<slug>` ou `/en/blog/<slug>` 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/<slug>, Accept-Language: en → 302 /en/blog/<slug>, slug preserved, cookie persisted."
|
||||
artifacts:
|
||||
- path: "nuxt.config.ts"
|
||||
issue: "i18n.detectBrowserLanguage + baseUrl; removed route rules"
|
||||
missing: []
|
||||
|
||||
Reference in New Issue
Block a user