Aller au contenu principal

Documentation technique - Generation automatisee des structured data (JSON-LD)

1) Objectif

Cette architecture permet de generer les donnees structurees de facon:

  • centralisee
  • factorisee
  • maintenable
  • extensible
  • sans duplication manuelle dans chaque page

Le principe est simple: chaque page rend ses schemas via des composants SEO communs, au lieu d'ecrire du JSON-LD inline partout.

2) Vue d'ensemble de l'architecture

flowchart TD
A[Page Docusaurus] --> B[Theme Layout swizzle]
B --> C[AutoStructuredData]
C --> D[JsonLd]
D --> E[Head script application/ld+json]

F[Article de blog] --> G[Theme BlogPostItem Header swizzle]
G --> H[BlogPostStructuredData]
H --> D

3) Composants et responsabilites

3.1 Couche de rendu JSON-LD

  • src/components/SEO/JsonLd.tsx

Responsabilites:

  • ajoute @context: https://schema.org
  • nettoie le payload (suppression des valeurs vides)
  • rend le script JSON-LD directement dans le DOM

Ce composant est le point unique de rendu final des scripts structurants.

3.2 Couche de schemas metier

  • src/components/SEO/schemas.ts
  • src/components/SEO/types.ts
  • src/components/SEO/utils.ts

Responsabilites:

  • fabriquer les objets schema.org (Organization, WebPage, Service, FAQPage, Article, HowTo, etc.)
  • normaliser URLs et pathnames
  • nettoyer recursivement le JSON-LD

3.3 Generation automatique sur toutes les pages

  • src/components/SEO/AutoStructuredData.tsx
  • branchement via src/theme/Layout/index.tsx

Responsabilites:

  • detecter la route courante
  • choisir le subtype de page (HomePage, ContactPage, AboutPage, CollectionPage, WebPage)
  • injecter les schemas communs selon des regles
  • extraire dynamiquement FAQ + breadcrumb + image portrait (page a propos)

3.4 Generation automatique sur les articles de blog

  • src/components/SEO/BlogPostStructuredData.tsx
  • branchement via src/theme/BlogPostItem/Header/index.js

Responsabilites:

  • recuperer metadata via useBlogPost()
  • generer Article ou NewsArticle selon la route
  • extraire un HowTo sur les guides quand un ol contient au moins 2 etapes

Important:

  • l'injection blog est faite dans BlogPostItem/Header pour rester dans le contexte BlogPostProvider
  • cela evite les erreurs de type "Hook useBlogPost is called outside the BlogPostProvider"

4) Regles de generation automatiques

4.1 Schemas globaux (pages)

Depuis AutoStructuredData:

  • Organization: toujours
  • WebSite: uniquement sur /
  • WebPage subtype: toujours
  • ProfessionalService: sur /, /contact, pages de service, ou routes "locales"
  • Service: uniquement sur les routes de service definies dans SERVICE_PATHS
  • Person: uniquement sur /qui-suis-je
  • BreadcrumbList: si un breadcrumb est detecte dans le DOM
  • FAQPage: si une FAQ est detectee dans le DOM

4.2 Schemas blog

Depuis BlogPostStructuredData:

  • NewsArticle si route commence par /actualites/ ou /actus/
  • sinon Article
  • HowTo sur /guides/ si un ol contient au moins 2 li

5) Extraction FAQ factorisee via le composant UI

  • src/components/FaqAccordion/FaqAccordion.js

Le composant FAQ expose des attributs de donnees utilises par AutoStructuredData:

  • data-cbg-faq-item="true"
  • data-cbg-faq-question="true"
  • data-cbg-faq-answer="true"

Consequence:

  • le schema FAQPage est synchronise avec le contenu reel visible
  • pas de double maintenance (UI d'un cote, JSON-LD de l'autre)

6) Flux d'execution

6.1 Page standard

  1. Docusaurus rend la page
  2. le Layout swizzle monte AutoStructuredData
  3. AutoStructuredData calcule route, identity, subtype
  4. extraction DOM (FAQ, breadcrumb, image portrait) via useEffect
  5. rendu de plusieurs JsonLd
  6. chaque JsonLd rend son script application/ld+json

6.2 Article de blog

  1. Docusaurus rend le post
  2. le swizzle BlogPostItem/Header monte BlogPostStructuredData
  3. useBlogPost() fournit metadata/front matter
  4. choix Article ou NewsArticle
  5. detection eventuelle d'un HowTo
  6. rendu JSON-LD via JsonLd

7) Comment etendre l'architecture

7.1 Ajouter un nouveau type de page service

Dans src/components/SEO/AutoStructuredData.tsx:

  • ajouter la route dans SERVICE_PATHS

Effet:

  • la page recevra automatiquement ProfessionalService + Service

7.2 Ajouter une regle de subtype WebPage

Dans detectPageSubtype():

  • ajouter une condition de route
  • retourner le subtype schema.org adapte

7.3 Ajouter un nouveau schema custom

  1. creer une factory dans schemas.ts
  2. l'appeler depuis AutoStructuredData ou BlogPostStructuredData
  3. rendre avec JsonLd pour garder le meme pipeline

8) Bonnes pratiques projet

  • ne plus ajouter de script application/ld+json inline dans les pages
  • privilegier les factories schemas.ts
  • garder les IDs stables (#organization, #webpage, #article, etc.)
  • reutiliser toAbsoluteUrl() pour toutes les URLs structurees
  • verifier apres modification avec un build

9) Validation recommandee

Commande build

npm run build

Checklist rapide

  • aucune erreur SSG
  • aucune erreur de liens casses
  • presence des scripts JSON-LD dans le HTML genere
  • pas de duplication evidente des memes schemas sur une meme page

10) Limites actuelles et points d'attention

  • la detection FAQ/Breadcrumb/HowTo repose sur le DOM rendu
  • certains contenus dynamiques peuvent modifier ce resultat
  • si une route blog change (ex: /actualites -> autre), mettre a jour isNewsPath()
  • les warnings de deprecation TypeScript/Docusaurus ne bloquent pas la generation, mais peuvent etre traites a part

11) Fichiers cles

  • src/components/SEO/JsonLd.tsx
  • src/components/SEO/AutoStructuredData.tsx
  • src/components/SEO/BlogPostStructuredData.tsx
  • src/components/SEO/schemas.ts
  • src/components/SEO/utils.ts
  • src/components/SEO/types.ts
  • src/theme/Layout/index.tsx
  • src/theme/BlogPostItem/Header/index.js
  • src/components/FaqAccordion/FaqAccordion.js