diff --git a/.planning/phases/07-seo-blog/07-03-SUMMARY.md b/.planning/phases/07-seo-blog/07-03-SUMMARY.md new file mode 100644 index 0000000..5423f77 --- /dev/null +++ b/.planning/phases/07-seo-blog/07-03-SUMMARY.md @@ -0,0 +1,98 @@ +--- +phase: 07-seo-blog +plan: 03 +subsystem: blog-listing-seo +tags: [seo, json-ld, schema-org, og-image, i18n, collection-page] +requires: + - "app/pages/blog/index.vue existant (Phase 6-03)" + - "i18n keys blog.* (FR+EN) + blog.breadcrumb.home / blog.breadcrumb.blog" +provides: + - "Listing /blog : useSeoMeta D-16 complet (og:image, og:locale + alternate, twitter)" + - "JSON-LD CollectionPage + BreadcrumbList sur /fr/blog et /en/blog" +affects: + - "Partage social /blog (card OG branded)" + - "Breadcrumb cohérent avec [slug].vue (Phase 7-02)" +tech_stack: + added: [] + patterns: + - "useSeoMeta D-16 pattern (ogImage absolu hardcodé, locale/alternate via arrow fns SSR-safe)" + - "useSchemaOrg([defineWebPage({ '@type': 'CollectionPage' }), defineBreadcrumb])" + - "inLanguage résolu à setup (pas ComputedRef — type schema-org attend literal string)" +key_files: + created: [] + modified: + - "app/pages/blog/index.vue" +decisions: + - "D-16 respectée : og:image fallback absolute https://killiandalcin.fr/og-blog-default.jpg" + - "D-03 respectée : Breadcrumb Accueil → Blog via defineBreadcrumb" + - "resolveOgImage helper (07-02) pas encore créé au moment d'exécution → fallback hardcodé OG_FALLBACK (autorisé par plan §interfaces note)" + - "inLanguage en valeur littérale (isFr.value ? 'fr-FR' : 'en-US') au setup, pas ComputedRef — contrainte type defineWebPage" +metrics: + duration_min: 5 + tasks_completed: 1 + files_touched: 1 + completed_date: 2026-04-22 +--- + +# Phase 07 Plan 03 : Blog Listing SEO Enrichment Summary + +**One-liner** : `/blog` listing enrichi avec useSeoMeta D-16 (og:image absolu, og:locale+alternate, twitter summary_large_image) + JSON-LD CollectionPage via `defineWebPage({'@type':'CollectionPage'})` et BreadcrumbList Accueil → Blog. + +## Ce qui a été fait + +### Task 1 : Enrichir `app/pages/blog/index.vue` + +**Imports/constantes ajoutées** : +- `SITE_URL = 'https://killiandalcin.fr'` +- `OG_FALLBACK = 'https://killiandalcin.fr/og-blog-default.jpg'` (fallback hardcodé ; helper `resolveOgImage` pas encore créé par 07-02 parallèle, autorisé par plan §interfaces) +- `canonicalUrl = computed(() => ${SITE_URL}${localePath('/blog')})` + +**useSeoMeta étendu** (D-16) : +- `title`, `description`, `ogTitle`, `ogDescription` (inchangés, via `() => t(...)`) +- `ogType: 'website'` +- `ogImage: OG_FALLBACK` (absolu, D-13/SEO-13) +- `ogUrl: canonicalUrl` +- `ogLocale: () => (isFr.value ? 'fr_FR' : 'en_US')` +- `ogLocaleAlternate: () => [isFr.value ? 'en_US' : 'fr_FR']` +- `twitterCard: 'summary_large_image'` +- `twitterImage: OG_FALLBACK` + +**useSchemaOrg ajouté** : +- `defineWebPage({ '@type': 'CollectionPage', name, description, inLanguage, url })` +- `defineBreadcrumb({ itemListElement: [Accueil → Blog] })` + +**Commit** : `47c2839` — `feat(07-03): enrich blog listing with D-16 useSeoMeta + CollectionPage/Breadcrumb JSON-LD` + +## Déviations du plan + +### Rule 1 — Bug : contrainte type `inLanguage` de `defineWebPage` + +- **Trouvé pendant** : Task 1, `pnpm typecheck` +- **Issue** : Le plan proposait `inLanguage: () => (isFr.value ? 'fr-FR' : 'en-US')`, mais le type schema-org pour `defineWebPage` n'accepte qu'une literal union `'fr-FR' | 'en-US' | ...` (pas une arrow fn, pas un ComputedRef — TS2322). +- **Fix** : Résolu à setup via valeur littérale `inLanguage: isFr.value ? 'fr-FR' : 'en-US'`. Acceptable car locale évaluée au render SSR (pas de switch mid-render côté serveur — re-mount si locale change côté client). +- **Files modified** : `app/pages/blog/index.vue` (ligne 62) +- **Commit** : `47c2839` (même commit) + +## Deferred Issues (hors scope 07-03) + +- `app/pages/blog/[slug].vue(126,3)` TS2322 et `(136,17)` TS2322 : erreurs de typage Schema/useSeoMeta — fichier owned par 07-02. À corriger dans 07-02 ou plan follow-up. +- `server/api/__sitemap__/urls.ts(20,28) (25,28)` TS2554 : sitemap endpoint — owned par 07-02. + +Ces erreurs sont pré-existantes/parallèles et n'affectent pas les must-haves de 07-03. + +## Must-haves vérifiés + +| Must-have | Statut | Preuve | +|-----------|--------|--------| +| og:image absolu /og-blog-default.jpg | ✅ | `ogImage: OG_FALLBACK` littéral absolu dans useSeoMeta | +| og:locale fr_FR ↔ en_US + alternate | ✅ | `ogLocale` + `ogLocaleAlternate` arrow fns SSR-safe | +| JSON-LD CollectionPage | ✅ | `defineWebPage({ '@type': 'CollectionPage' })` dans useSchemaOrg | +| JSON-LD BreadcrumbList Accueil → Blog | ✅ | `defineBreadcrumb({ itemListElement: [home, blog] })` | + +Typecheck vert sur `app/pages/blog/index.vue` (erreurs résiduelles dans d'autres fichiers out-of-scope). + +## Self-Check: PASSED + +- ✅ `app/pages/blog/index.vue` contient `defineWebPage`, `defineBreadcrumb`, `ogLocaleAlternate`, `og-blog-default.jpg` +- ✅ Commit `47c2839` existe dans git log +- ✅ Requirements SEO-10, SEO-13, SEO-15 couverts par frontmatter