Un moteur de réponse lit votre page comme un humain pressé : il en tire du sens, avec une marge d'erreur. Il lit votre JSON-LD comme une base de données : sans marge d'erreur. C'est toute la valeur des données structurées à l'ère des assistants — non pas un bonus de classement, mais un moyen d'affirmer vos faits dans une forme qui ne peut pas être mal comprise.
Un seul graphe, des identifiants stables
L'erreur la plus répandue n'est pas d'oublier le JSON-LD : c'est d'en avoir trois, posés par le thème, par une extension SEO et par un module d'avis, qui se contredisent. Un moteur qui rencontre deux noms d'entreprise différents sur la même page ne choisit pas : il se méfie.
Le patron qui règle ce problème s'appelle le graphe. Un seul bloc <script type="application/ld+json">, une clé @graph, et à l'intérieur chaque nœud porte un @id stable — une URL avec un fragment — auquel les autres nœuds font référence au lieu de dupliquer l'information.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{ "@type": "Organization",
"@id": "https://exemple.ma/#organization",
"name": "Atlas Cargo SARL",
"url": "https://exemple.ma/" },
{ "@type": "WebSite",
"@id": "https://exemple.ma/#website",
"url": "https://exemple.ma/",
"publisher": { "@id": "https://exemple.ma/#organization" },
"inLanguage": "fr" },
{ "@type": "WebPage",
"@id": "https://exemple.ma/tarifs#webpage",
"url": "https://exemple.ma/tarifs",
"isPartOf": { "@id": "https://exemple.ma/#website" },
"about": { "@id": "https://exemple.ma/#organization" } },
{ "@type": "BreadcrumbList",
"@id": "https://exemple.ma/tarifs#breadcrumb",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "Accueil", "item": "https://exemple.ma/" },
{ "@type": "ListItem", "position": 2, "name": "Tarifs" }
] }
]
}
</script>Trois propriétés de ce patron méritent d'être comprises plutôt que copiées. Les @id doivent être stables dans le temps : c'est ce qui permet de reconnaître la même entité d'une page à l'autre et d'une visite à la suivante. Les références remplacent la duplication : le nom de l'entreprise n'est écrit qu'une fois, donc il ne peut pas diverger. Et le dernier ListItem d'un fil d'Ariane n'a pas d'item : la page courante ne se lie pas à elle-même.
Les types qui comptent vraiment
| Type | À quoi il sert | Propriétés à ne pas manquer |
|---|---|---|
| Organization | Identifier l'entité | name, url, logo, sameAs, contactPoint |
| LocalBusiness | Commerce avec adresse physique | address, geo, openingHoursSpecification, telephone, areaServed, priceRange |
| Service / Product | Ce que vous vendez | name, description, provider, offers, areaServed |
| Offer | Le prix et sa validité | price, priceCurrency, availability, validThrough |
| FAQPage | Questions et réponses réelles | mainEntity, acceptedAnswer |
| Article / BlogPosting | Contenu éditorial | headline, datePublished, dateModified, author |
| BreadcrumbList | Position dans le site | itemListElement, position |
Une note sur FAQPage. Les résultats enrichis correspondants ont été fortement restreints par Google et ne s'affichent plus pour la plupart des sites. Le balisage reste néanmoins utile ici, pour une raison différente : il présente vos questions-réponses sous une forme déjà découpée, exactement le format qu'un moteur de réponse réutilise. Le rich result a disparu ; l'extractibilité, elle, est restée.
La règle de cohérence — celle que presque tout le monde viole
Le balisage doit décrire ce que la page montre. Un prix affiché à 4 500 MAD et un Offer à 3 900, une adresse à Casablanca dans le pied de page et à Rabat dans le JSON-LD, des horaires d'ouverture qui ne correspondent à aucun texte visible : chacun de ces écarts transforme une aide en signal négatif. Google refuse les résultats enrichis pour du balisage non représentatif du contenu, et un modèle qui détecte une contradiction cesse simplement de vous traiter comme une source fiable.
Appliquez la même règle chez vous. sameAs ne doit contenir que des profils que vous contrôlez réellement et qui répondent : votre page LinkedIn, votre fiche d'entreprise, votre compte Instagram. Un profil inventé ou abandonné est pire qu'un tableau vide.
Un exemple complet : commerce local marocain
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"@id": "https://exemple.ma/#business",
"name": "Atlas Cargo SARL",
"description": "Transport et dédouanement entre Casablanca, Tanger Med et l'Europe.",
"url": "https://exemple.ma/",
"telephone": "+212522000000",
"email": "contact@exemple.ma",
"priceRange": "$$",
"address": {
"@type": "PostalAddress",
"streetAddress": "45 boulevard Zerktouni",
"addressLocality": "Casablanca",
"postalCode": "20250",
"addressCountry": "MA"
},
"geo": { "@type": "GeoCoordinates", "latitude": 33.589886, "longitude": -7.633076 },
"areaServed": [
{ "@type": "City", "name": "Casablanca" },
{ "@type": "City", "name": "Tanger" },
{ "@type": "Country", "name": "Maroc" }
],
"openingHoursSpecification": [
{ "@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
"opens": "08:30", "closes": "18:00" },
{ "@type": "OpeningHoursSpecification",
"dayOfWeek": "Saturday", "opens": "09:00", "closes": "13:00" }
],
"availableLanguage": ["ar", "fr", "en"],
"sameAs": ["https://www.linkedin.com/company/exemple-ma"]
}Quatre points qui font la différence dans un contexte marocain. Le téléphone s'écrit au format international, sans espaces : c'est ainsi qu'il est comparable d'une source à l'autre. addressCountry prend le code MA, pas le mot « Maroc ». areaServed mérite d'être explicite quand vous intervenez au-delà de votre ville — c'est la propriété qui répond à « qui fait ça à Tanger ? ». Et availableLanguage compte réellement ici : la question peut arriver en arabe, en français ou en anglais, et vous venez d'indiquer que vous répondez dans les trois.
Le cas WordPress : trois sources, une seule vérité
Sur un site WordPress typique, le balisage vient de trois endroits à la fois : le thème en pose une partie, l'extension de référencement une autre, et un module d'avis ou de réservation ajoute la sienne. Personne ne l'a décidé, et personne ne le voit — jusqu'à l'audit. La marche à suivre est toujours la même : afficher la source de la page, chercher chaque occurrence de application/ld+json, et compter.
curl -sS https://votre-domaine.com/ | grep -c 'application/ld+json'
# Plus de 1 : identifiez qui pose quoi, gardez une seule source, désactivez les autres.Ensuite, choisissez la source qui restera — le plus souvent l'extension de référencement, parce qu'elle survit au changement de thème — et coupez les autres dans leurs réglages. Si un module refuse de se taire, un filtre dans le thème enfant reste préférable à trois graphes contradictoires. Le but n'est pas d'avoir le balisage le plus riche : c'est d'avoir un seul balisage, exact.
Ce qui invalide tout le bloc
- Un JSON invalide. Une virgule finale, un guillemet typographique collé par un traitement de texte, et le bloc entier est ignoré — silencieusement.
- Des notes et avis inventés. Un
aggregateRatingsans avis réels et visibles sur la page est une violation directe des règles, et l'infraction la plus facile à détecter automatiquement. - Des images qui répondent 404. Un
logoou uneimagemort disqualifie le nœud qui les porte. - Des
@idinstables. S'ils changent à chaque déploiement, l'entité est recréée à chaque visite et n'accumule jamais rien. - Plusieurs blocs concurrents. Thème + extension SEO + module d'avis : trois sources, trois vérités. Consolidez en un seul graphe.
- Du balisage sur du contenu absent de la page. Une FAQ en JSON-LD dont les questions n'apparaissent nulle part visuellement est du balisage non représentatif.
Valider, puis vérifier
Deux outils gratuits, deux fonctions différentes. validator.schema.org contrôle la conformité au vocabulaire : types, propriétés, structure. Le test des résultats enrichis répond à une autre question — Google peut-il en tirer un affichage particulier. Un balisage parfaitement valide peut n'ouvrir droit à aucun résultat enrichi ; ce n'est pas une erreur, les deux objectifs sont distincts.
Aucun des deux ne vérifie ce qui compte le plus : que vos affirmations soient vraies et cohérentes avec la page. Cette vérification-là reste humaine — ou automatisée avec une règle explicite, comme la nôtre : chaque URL publiée est récupérée avant publication, et une réponse autre que 200 empêche la publication du fichier.