From 47c2839ae8c09b6e24fa8cd94c5b19b8a0c8775c Mon Sep 17 00:00:00 2001 From: kayjaydee Date: Wed, 22 Apr 2026 11:17:10 +0200 Subject: [PATCH] feat(07-03): enrich blog listing with D-16 useSeoMeta + CollectionPage/Breadcrumb JSON-LD - Add SITE_URL + OG_FALLBACK constants (fallback hardcoded, resolveOgImage helper owned by 07-02) - Extend useSeoMeta: ogImage (absolute /og-blog-default.jpg), ogUrl, ogLocale, ogLocaleAlternate, twitterCard, twitterImage - Add useSchemaOrg([defineWebPage CollectionPage, defineBreadcrumb(Accueil -> Blog)]) - inLanguage resolved at setup (type constraint: literal union, not ComputedRef) - Requirements: SEO-10, SEO-13, SEO-15 --- app/pages/blog/index.vue | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/app/pages/blog/index.vue b/app/pages/blog/index.vue index 24e4caf..4ab35d2 100644 --- a/app/pages/blog/index.vue +++ b/app/pages/blog/index.vue @@ -33,14 +33,42 @@ const uniqueTags = computed(() => { const totalLanguages = 2 // FR + EN — valeur fixe (UI-SPEC) -// SEO minimal Phase 6 — Phase 7 enrichira avec JSON-LD + og:image par article +// SEO enrichi Phase 7 (Plan 07-03) — D-16 og:image fallback + JSON-LD CollectionPage + Breadcrumb +// Note: fallback hardcodé en attendant resolveOgImage helper de 07-02 (même Wave 2, parallèle) +const SITE_URL = 'https://killiandalcin.fr' +const OG_FALLBACK = 'https://killiandalcin.fr/og-blog-default.jpg' +const ogImage = OG_FALLBACK +const canonicalUrl = computed(() => `${SITE_URL}${localePath('/blog')}`) + useSeoMeta({ title: () => t('blog.title'), description: () => t('blog.subtitle'), ogTitle: () => t('blog.title'), ogDescription: () => t('blog.subtitle'), ogType: 'website', + ogImage, + ogUrl: canonicalUrl, + ogLocale: () => (isFr.value ? 'fr_FR' : 'en_US'), + ogLocaleAlternate: () => [isFr.value ? 'en_US' : 'fr_FR'], + twitterCard: 'summary_large_image', + twitterImage: ogImage, }) + +useSchemaOrg([ + defineWebPage({ + '@type': 'CollectionPage', + name: () => t('blog.title'), + description: () => t('blog.subtitle'), + inLanguage: isFr.value ? 'fr-FR' : 'en-US', + url: canonicalUrl, + }), + defineBreadcrumb({ + itemListElement: [ + { name: () => t('blog.breadcrumb.home'), item: () => localePath('/') }, + { name: () => t('blog.breadcrumb.blog'), item: () => localePath('/blog') }, + ], + }), +])