diff --git a/apps/landing/public/og-default.png b/apps/landing/public/og-default.png new file mode 100644 index 0000000..8962500 Binary files /dev/null and b/apps/landing/public/og-default.png differ diff --git a/apps/landing/src/layouts/Layout.astro b/apps/landing/src/layouts/Layout.astro index 35c008a..398e612 100644 --- a/apps/landing/src/layouts/Layout.astro +++ b/apps/landing/src/layouts/Layout.astro @@ -16,12 +16,20 @@ import { SiteFooter } from "../components/SiteFooter"; const SITE_URL = "https://rubis.pro"; +/** + * OG image par défaut (1200×630) servie depuis apps/landing/public/. + * Utilisée pour les partages sociaux quand aucune image n'est fournie + * par la page (cas de la home + pages légales). Les articles de blog + * ont leur propre hero qui prend précédence. + */ +const DEFAULT_OG_IMAGE = `${SITE_URL}/og-default.png`; + interface Props { title: string; description: string; /** Path absolu de la page courante (ex. "/blog/foo"). Default = location actuelle. */ pathname?: string; - /** OG image absolue (1200×630 idéal). */ + /** OG image absolue (1200×630 idéal). Fallback sur og-default.png si non fournie. */ ogImage?: string; /** OG type. Default "website". Mettre "article" sur les pages de blog. */ ogType?: "website" | "article"; @@ -44,7 +52,20 @@ const { jsonLd, } = Astro.props; -const fullTitle = title.includes("Rubis") ? title : `${title} — Rubis sur l'ongle`; +/** + * Suffixe brand intelligent : + * - Si le titre est court (<45 chars) ET ne contient pas "Rubis", on ajoute + * " — Rubis" pour la cohérence brand dans les SERP. + * - Sinon (titre long ou déjà brandé), on laisse tel quel : Google tronque + * à ~60 chars dans le snippet, autant garder le message-clé en entier. + * + * Le branding reste assuré par og:site_name + JSON-LD publisher + le hostname + * rubis.pro visible dans la SERP — pas besoin de le marteler dans le title. + */ +const fullTitle = + title.length < 45 && !title.includes("Rubis") ? `${title} — Rubis` : title; + +const resolvedOgImage = ogImage ?? DEFAULT_OG_IMAGE; const url = `${SITE_URL}${pathname ?? Astro.url.pathname}`; const robots = noindex ? "noindex,nofollow" : "index,follow,max-image-preview:large"; const jsonLdArray = jsonLd ? (Array.isArray(jsonLd) ? jsonLd : [jsonLd]) : []; @@ -72,22 +93,17 @@ const jsonLdArray = jsonLd ? (Array.isArray(jsonLd) ? jsonLd : [jsonLd]) : []; - { - ogImage && ( - <> - - - - - - ) - } + + + + - {/* Twitter Card */} - + {/* Twitter Card — toujours summary_large_image puisqu'on a maintenant + un og-default.png 1200×630 servi par défaut sur les pages sans hero. */} + - {ogImage && } + {/* Favicons */} diff --git a/docs/marketing/assets/og-default.html b/docs/marketing/assets/og-default.html new file mode 100644 index 0000000..efd19d1 --- /dev/null +++ b/docs/marketing/assets/og-default.html @@ -0,0 +1,425 @@ + + + + + + OG image par défaut — Rubis sur l'ongle + + + + + + + +
+

OG image — 1200 × 630

+ + Pose ensuite dans apps/landing/public/og-default.png +
+ +
+ +
+
+ + + + + + + + Rubissur l'ongle +
+ +

+ Vos factures relancées toutes seules. +

+ +

+ Le SaaS de relance pour TPE-PME françaises. 5 heures par semaine + récupérées, automatiquement. +

+ +
rubis.pro
+
+ + +
+
+
+ + + + + + + +
+
124 rubis
+
24 h 48 libérées ce mois
+
+
+ +
+
+
Encaissé
+
14 320 €
+
+ 2 800 € vs avril
+
+
+
DSO
+
38 j
+
↘ −6 j depuis Rubis
+
+
+ +
+ ✓ Facture F-2024-035 encaissée + +
+
+
+
+ + + + + +