Apprenez à implémenter les données structurées Product et Offer sur Shopify pour améliorer votre visibilité dans Google Shopping et les rich snippets.
Les données structurées Product et Offer sont des balises JSON-LD qui décrivent un produit et son offre (prix, disponibilité, devise) pour les moteurs de recherche, permettant l'affichage de rich snippets dans les résultats.
Pour Shopify, l'implémentation des données structurées Product/Offer nécessite soit l'utilisation d'une app dédiée (Schema Plus, JSON‑LD for SEO), soit la modification du fichier theme.liquid via un snippet personnalisé. L'objectif est de fournir à Google des informations précises sur chaque variante (prix, stock, devise) pour activer les badges « en stock », le prix barré et le micro‑format Shopping. Une validation régulière avec l'outil de test des données structurées de Google est indispensable pour éviter les erreurs de balisage. Enfin, il est conseillé de synchroniser les données avec le flux Merchant Center pour maximiser la pertinence des annonces Shopping.
Cas fréquent observé : de nombreux marchands Shopify installent une app de données structurées sans vérifier la cohérence entre le balisage et les données réelles du catalogue. En accompagnement, on constate que les erreurs les plus courantes sont l'absence de balisage pour les variantes multiples, l'utilisation d'un prix sans devise explicite, ou encore l'oubli du champ 'availability' pour les produits en rupture de stock. Ces erreurs entraînent une absence de rich snippets malgré un travail SEO important.
Les données structurées Product et Offer permettent aux moteurs de recherche de comprendre précisément ce que vous vendez : le nom du produit, son prix, sa disponibilité, sa devise et son identifiant unique (SKU, GTIN). Sans ce balisage, Google doit interpréter le contenu de votre page, ce qui peut générer des erreurs d'affichage dans les résultats de recherche.
L'enjeu principal est l'obtention des rich snippets : le prix affiché directement dans le SERP, le badge « en stock », l'étoile de notation (si vous utilisez les avis produits) et le micro‑format pour Google Shopping. Ces éléments augmentent le taux de clic (CTR) de 20 à 30 % en moyenne, selon les études sectorielles.
De plus, un balisage correct est indispensable pour être éligible aux fiches gratuites sur Google Shopping (anciennement « free listings »). Google utilise ces données structurées pour enrichir son index shopping, même sans flux Merchant Center. En résumé, c'est un levier SEO technique à fort retour sur investissement.
Le vocabulaire Schema.org définit deux types principaux pour le e‑commerce : Product et Offer. Le type Product décrit l'article lui‑même (nom, description, image, marque, GTIN), tandis que le type Offer décrit les conditions de vente (prix, devise, disponibilité, vendeur).
Dans la pratique, un même produit peut avoir plusieurs offres (par exemple, différentes tailles ou couleurs). Chaque variante doit posséder sa propre propriété 'offers' avec un prix et une disponibilité distincts. Il est impératif de ne pas mélanger les offres dans un seul bloc, sous peine de générer une erreur de validation.
Voici les propriétés obligatoires pour Product : name, description, image (au moins une URL valide), sku ou gtin (selon le produit). Pour Offer : price, priceCurrency (code ISO 4217, ex : EUR), availability (http://schema.org/InStock ou OutOfStock), url (lien direct vers la page produit).
La méthode la plus fiable et performante consiste à ajouter un snippet JSON‑LD directement dans le fichier theme.liquid de votre thème Shopify. Voici les étapes :
{% render 'product-jsonld' %} à l'intérieur de la boucle produit.Le code JSON‑LD doit être dynamique : utilisez les variables Liquid {{ product.title }}, {{ product.selected_variant.price | money_without_currency }}, {{ product.selected_variant.inventory_quantity }} pour injecter les données réelles. Attention à bien gérer les guillemets et l'échappement des caractères spéciaux.
Exemple de structure simplifiée :
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "{{ product.title | escape }}",
"description": "{{ product.description | strip_html | escape }}",
"image": "{{ product.featured_image | img_url: 'master' }}",
"offers": {
"@type": "Offer",
"price": "{{ product.selected_variant.price | money_without_currency | remove: ',' }}",
"priceCurrency": "{{ shop.currency }}",
"availability": "{% if product.available %}http://schema.org/InStock{% else %}http://schema.org/OutOfStock{% endif %}",
"url": "{{ shop.url }}{{ product.url }}"
}
}La plupart des boutiques Shopify vendent des produits avec plusieurs variantes (taille, couleur, matière). Dans ce cas, le balisage doit refléter chaque variante comme une offre distincte. La solution consiste à itérer sur toutes les variantes du produit et à générer un tableau d'offres.
Dans votre snippet, utilisez une boucle {% for variant in product.variants %} pour créer un bloc Offer par variante. Chaque bloc doit contenir les propriétés price, priceCurrency, availability, sku et url (avec l'identifiant de variante dans l'URL, ex : {{ shop.url }}{{ product.url }}?variant={{ variant.id }}).
Attention : ne pas inclure les variantes épuisées avec le statut 'InStock'. Vérifiez la condition {% if variant.available %} avant d'ajouter l'offre. Pour les produits sans variante, une seule offre suffit.
Exemple de code pour les variantes :
"offers": [
{% for variant in product.variants %}
{
"@type": "Offer",
"price": "{{ variant.price | money_without_currency | remove: ',' }}",
"priceCurrency": "{{ shop.currency }}",
"availability": "{% if variant.available %}http://schema.org/InStock{% else %}http://schema.org/OutOfStock{% endif %}",
"sku": "{{ variant.sku }}",
"url": "{{ shop.url }}{{ product.url }}?variant={{ variant.id }}"
}{% unless forloop.last %},{% endunless %}
{% endfor %}
]Le champ price doit contenir uniquement le montant numérique, sans symbole monétaire ni espace. Par exemple, pour un produit à un montant selon le prestataire, écrivez "price": "29.99" (avec un point comme séparateur décimal). Si votre boutique utilise une virgule comme séparateur décimal, convertissez‑la en point dans le code Liquid : | remove: ',' ou | replace: ',', '.'.
Le champ priceCurrency doit utiliser le code ISO 4217 en majuscules : EUR, USD, GBP, etc. Shopify expose la devise via {{ shop.currency }}, ce qui est fiable. Pour les boutiques multi‑devises, assurez‑vous que le balisage corresponde à la devise affichée sur la page (par défaut, celle du visiteur).
Si vous proposez des réductions, utilisez la propriété priceValidUntil pour indiquer la date de fin de l'offre. Cela permet à Google d'afficher le prix barré dans les résultats. Exemple : "priceValidUntil": "2025-12-31". Pour les produits en précommande, utilisez availability = http://schema.org/PreOrder.
Après avoir implémenté le balisage, la validation est une étape critique. Utilisez l'outil de test des données structurées de Google (search.google.com/test/rich-results) pour vérifier l'absence d'erreurs et d'avertissements. Saisissez l'URL de votre page produit ou collez le code HTML.
Les erreurs fréquentes détectées :
Pour les boutiques avec un grand catalogue, utilisez le rapport d'indexation dans Google Search Console, rubrique « Améliorations » > « Produits ». Vous y verrez le nombre de pages valides et les erreurs groupées. Corrigez les erreurs par lot en ajustant votre snippet.
Enfin, testez également l'affichage sur mobile avec l'outil de test d'optimisation mobile de Google, car les rich snippets peuvent s'afficher différemment.
Les données structurées Product/Offer ne remplacent pas un flux Merchant Center, mais elles le complètent. Google utilise les données structurées pour valider et enrichir les informations de votre flux. Si les deux sources sont cohérentes, vos fiches gratuites et vos annonces Shopping bénéficient d'une meilleure qualité de données.
Pour une synchronisation optimale :
Si vous utilisez une app de flux (ex : Google Shopping Feed by Simprosys), elle peut automatiquement générer les données structurées. Dans ce cas, désactivez le snippet manuel pour éviter les doublons. L'outil de test vous indiquera si plusieurs balisages sont présents sur la même page.
Voici les pièges les plus fréquents lors de l'implémentation :
{{ product.featured_image | img_url: 'master' }} qui génère une URL complète avec le domaine.Pour éviter ces erreurs, effectuez une validation après chaque modification du thème ou de la structure des variantes. Tenez un registre des modifications dans un fichier de documentation interne.
Si votre boutique Shopify utilise une application multi‑devises (ex : Bold Multi‑Currency), le balisage doit refléter la devise affichée sur la page. Dans ce cas, utilisez la variable Liquid de l'application pour le prix et la devise, plutôt que {{ shop.currency }}. Testez chaque devise séparément avec l'outil de validation.
Pour les produits vendus par abonnement (via une app comme Recharge ou Bold Subscriptions), le balisage doit inclure la propriété offers.priceSpecification avec le type UnitPriceSpecification pour indiquer le prix récurrent. Exemple :
"priceSpecification": {
"@type": "UnitPriceSpecification",
"price": "19.99",
"priceCurrency": "EUR",
"billingDuration": "P1M",
"billingStartDate": "2025-01-01"
}Enfin, pour les produits avec des options personnalisables (gravure, texte), le balisage doit rester générique : ne tentez pas de baliser chaque combinaison possible, mais utilisez une offre unique avec un prix de base. Les options personnalisées sont gérées côté panier, pas dans les données structurées.
| Propriété | Type Schema | Obligatoire | Exemple Shopify |
|---|---|---|---|
| name | Product | Oui | {{ product.title }} |
| description | Product | Oui | {{ product.description | strip_html }} |
| image | Product | Oui | {{ product.featured_image | img_url: 'master' }} |
| sku | Product | Recommandé | {{ product.selected_variant.sku }} |
| gtin | Product | Recommandé | {{ product.selected_variant.barcode }} |
| price | Offer | Oui | {{ variant.price | money_without_currency | remove: ',' }} |
| priceCurrency | Offer | Oui | {{ shop.currency }} |
| availability | Offer | Oui | InStock / OutOfStock |
| url | Offer | Oui | {{ shop.url }}{{ product.url }}?variant={{ variant.id }} |
| Méthode | Complexité | Maintenance | Recommandation |
|---|---|---|---|
| Snippet JSON‑LD manuel dans theme.liquid | Moyenne | Faible (une fois en place) | Idéal pour les développeurs et agences |
| App Shopify (Schema Plus, JSON‑LD for SEO) | Faible | Moyenne (mise à jour de l'app) | Pour les marchands sans compétences techniques |
| App de flux Shopping (Simprosys, Feedonomics) | Faible | Moyenne (dépend du flux) | Si vous utilisez déjà un flux Merchant Center |
| Plugin tiers (LimeLight, SEO Manager) | Faible | Moyenne | Alternative aux apps dédiées |
Visibilité SEO & IA
On vérifie votre SEO technique, vos données structurées et votre présence dans les moteurs IA, puis on priorise les gains les plus rentables.
Product décrit l'article lui-même (nom, image, marque, GTIN), tandis que Offer décrit les conditions de vente (prix, devise, disponibilité). Un même produit peut avoir plusieurs offres (une par variante). Les deux types sont obligatoires pour un balisage complet.
Oui, chaque variante doit avoir sa propre offre dans le tableau 'offers'. Utilisez une boucle Liquid pour itérer sur toutes les variantes et générer un bloc Offer par variante, avec son prix, sa disponibilité et son URL spécifique.
Il est préférable de supprimer les microdonnées HTML et de les remplacer par un snippet JSON‑LD propre. Les deux formats peuvent coexister, mais cela augmente le risque d'erreurs et de duplication. Utilisez l'outil de test pour vérifier qu'un seul balisage est présent.
Pour chaque variante, utilisez la condition Liquid {% if variant.available %} pour définir la propriété availability sur 'InStock' ou 'OutOfStock'. N'incluez pas les variantes épuisées dans le tableau d'offres si elles ne sont pas visibles sur la page.
Oui, des apps comme Schema Plus ou JSON‑LD for SEO simplifient l'implémentation sans code. Cependant, vérifiez qu'elles gèrent correctement les variantes et les devises. Testez toujours avec l'outil Google après installation.
Elles n'ont pas d'impact direct sur le classement, mais elles augmentent le taux de clic (CTR) grâce aux rich snippets (prix, disponibilité). Un meilleur CTR peut indirectement améliorer votre positionnement dans les résultats de recherche.
Consultez le rapport 'Améliorations' > 'Produits' dans Search Console pour identifier les erreurs. Les plus fréquentes sont le prix manquant, la disponibilité incorrecte ou l'URL d'image invalide. Corrigez le snippet et validez avec l'outil de test.
Sources : Google — données structurées · Schema.org · Google Search Central.