Un e-commerce français de 12 000 SKUs dans le mobilier a vu son trafic organique transactionnel chuter de 34 % entre janvier et avril 2026 — sans aucune perte de positionnement. Ses pages produits étaient toujours en top 5. Le problème : les product packs Google captaient désormais le premier regard, et ce marchand n'y figurait pas correctement.
Les données publiées par Search Engine Land, issues de l'analyse de plus de 63 000 marchands, confirment ce que beaucoup de SEOs e-commerce soupçonnaient : les product packs ne sont plus un bonus de visibilité. C'est un canal de vente primaire, et la différence entre "apparaître" et "convertir" dans ces packs tient à des détails techniques que la majorité des marchands ignorent.
L'expansion silencieuse des product packs : ce que les données révèlent
Les product packs — ces carrousels de produits avec image, prix, vendeur et avis qui s'affichent directement dans les SERPs — occupent désormais la quasi-totalité des requêtes à intention d'achat. Sur les requêtes de type "[catégorie] + [attribut]" (ex. "chaussures de running homme légères"), leur présence dépasse les 85 % des SERPs selon les données agrégées de l'étude.
Le point critique que l'étude met en lumière : la corrélation entre la présence dans un product pack et le CTR n'est pas linéaire. Les marchands dont les listings respectent l'intégralité des attributs structurés (prix, disponibilité, avis, images conformes aux guidelines Merchant Center, GTIN valide) captent entre 3x et 5x plus de clics que ceux qui apparaissent avec des données partielles. Autrement dit, "être dans le pack" sans données complètes revient presque à ne pas y être.
Le basculement de 2025-2026
Ce qui a changé fondamentalement, c'est la position des packs dans la SERP. Jusqu'en 2024, les product packs apparaissaient majoritairement après les 2-3 premiers résultats organiques. Depuis mi-2025, Google les positionne de plus en plus en position 0 — au-dessus de tout résultat organique — sur les requêtes transactionnelles à forte intention commerciale.
Pour un site e-commerce qui dépendait de ses positions organiques pour ses catégories phares, cela signifie que même une position 1 ne garantit plus le premier clic. Le product pack agit comme un filtre intermédiaire : l'utilisateur compare les produits visuellement avant de décider s'il scrolle vers les résultats organiques.
Qui gagne, qui perd
L'analyse des 63 000+ marchands révèle un profil type des gagnants :
- Feed Merchant Center mis à jour au minimum toutes les 24h (les top performers sont en temps réel via Content API)
- Structured data Product complète sur chaque page produit, validée sans erreur dans le Rich Results Test
- Images produit qui respectent les exigences Google Merchant Center : fond blanc ou neutre, pas de texte superposé, résolution ≥ 100x100 px (recommandé 800x800+)
- GTIN/EAN présents et corrects pour plus de 95 % du catalogue
- Prix cohérent entre le feed, le structured data et la page d'atterrissage — zéro écart
Les perdants partagent un pattern commun : ils ont activé un feed Merchant Center à un moment donné, mais ne surveillent pas activement la cohérence entre leur structured data on-page, leur feed, et l'état réel de leur stock.
Structured data Product : les détails qui font la différence
La documentation Google sur les données structurées Product liste les propriétés requises et recommandées. Mais l'étude montre que les marchands qui dominent les product packs vont bien au-delà du minimum.
Voici un exemple de structured data Product optimisée pour maximiser l'éligibilité aux product packs, sur une fiche produit de chaussure de running :
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Nike ZoomX Vaporfly NEXT% 3 - Homme",
"image": [
"https://www.running-expert.fr/media/nike-vaporfly-3-main.jpg",
"https://www.running-expert.fr/media/nike-vaporfly-3-side.jpg",
"https://www.running-expert.fr/media/nike-vaporfly-3-sole.jpg"
],
"description": "Chaussure de compétition marathon, plaque carbone, mousse ZoomX, drop 8mm, 198g en taille 42.",
"sku": "NKE-VPF3-WHT-42",
"gtin13": "0196154746823",
"mpn": "DV4129-100",
"brand": {
"@type": "Brand",
"name": "Nike"
},
"color": "White/Volt",
"size": "42",
"material": "Mesh synthétique",
"weight": {
"@type": "QuantitativeValue",
"value": "198",
"unitCode": "GRM"
},
"offers": {
"@type": "Offer",
"url": "https://www.running-expert.fr/nike-vaporfly-next-3-homme-blanc",
"priceCurrency": "EUR",
"price": "259.99",
"priceValidUntil": "2026-12-31",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition",
"seller": {
"@type": "Organization",
"name": "Running Expert"
},
"shippingDetails": {
"@type": "OfferShippingDetails",
"shippingRate": {
"@type": "MonetaryAmount",
"value": "0.00",
"currency": "EUR"
},
"deliveryTime": {
"@type": "ShippingDeliveryTime",
"handlingTime": {
"@type": "QuantitativeValue",
"minValue": 0,
"maxValue": 1,
"unitCode": "d"
},
"transitTime": {
"@type": "QuantitativeValue",
"minValue": 1,
"maxValue": 3,
"unitCode": "d"
}
},
"shippingDestination": {
"@type": "DefinedRegion",
"addressCountry": "FR"
}
},
"hasMerchantReturnPolicy": {
"@type": "MerchantReturnPolicy",
"applicableCountry": "FR",
"returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
"merchantReturnDays": 30,
"returnMethod": "https://schema.org/ReturnByMail",
"returnFees": "https://schema.org/FreeReturn"
}
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.7",
"reviewCount": "342",
"bestRating": "5",
"worstRating": "1"
},
"review": [
{
"@type": "Review",
"author": {
"@type": "Person",
"name": "Marc D."
},
"datePublished": "2026-03-15",
"reviewBody": "Testée sur semi-marathon, rebond exceptionnel, taille un peu juste.",
"reviewRating": {
"@type": "Rating",
"ratingValue": "5",
"bestRating": "5"
}
}
]
}
</script>
Ce qui change par rapport au minimum requis
Trois éléments font la différence dans ce markup :
shippingDetails et hasMerchantReturnPolicy : Google les utilise directement dans l'affichage des product packs. Un listing qui affiche "Livraison gratuite" et "Retours gratuits sous 30 jours" directement dans la SERP convertit significativement mieux. Ces propriétés ne sont pas "requises" au sens strict, mais l'étude montre que les marchands qui les implémentent apparaissent 2x plus souvent en position dominante dans les packs.
Images multiples : le carrousel d'images dans les product packs favorise les listings avec 3+ images. Une seule image de face ne suffit plus.
weight, material, color, size : ces attributs alimentent les filtres de recherche Google Shopping. Sans eux, votre produit est invisible sur les requêtes filtrées — qui représentent une part croissante des recherches produit.
Feed Merchant Center : la synchronisation comme avantage compétitif
Le structured data on-page ne suffit pas. Google croise systématiquement les données du feed Merchant Center avec le markup de la page. Toute incohérence — un prix différent, une disponibilité contradictoire — déclenche des disapprovals ou réduit la visibilité du listing.
Le problème technique le plus fréquent : le décalage temporel. Votre stock change en temps réel, votre feed est mis à jour toutes les 6 heures, et votre structured data est cachée côté CDN avec un TTL de 4 heures. Résultat : un produit épuisé peut rester affiché comme disponible pendant 10 heures.
Automatiser la synchronisation avec la Content API
Pour un catalogue de plus de 5 000 produits, l'export CSV/XML planifié atteint ses limites. Voici un script TypeScript qui synchronise les changements de stock en temps réel via la Content API for Shopping :
import { google } from 'googleapis';
interface ProductStockUpdate {
offerId: string;
availability: 'in stock' | 'out of stock' | 'preorder';
price: { value: string; currency: string };
}
async function batchUpdateMerchantProducts(
merchantId: string,
updates: ProductStockUpdate[]
): Promise<void> {
const auth = new google.auth.GoogleAuth({
keyFile: './service-account.json',
scopes: ['https://www.googleapis.com/auth/content'],
});
const content = google.content({ version: 'v2.1', auth });
// Batch updates en groupes de 100 (limite API)
const chunks = chunkArray(updates, 100);
for (const chunk of chunks) {
const entries = chunk.map((update, index) => ({
batchId: index,
merchantId,
method: 'update' as const,
productId: `online:fr:FR:${update.offerId}`,
product: {
offerId: update.offerId,
availability: update.availability,
price: update.price,
},
}));
try {
const response = await content.products.custombatch({
requestBody: { entries },
});
const errors = response.data.entries?.filter(e => e.errors);
if (errors?.length) {
console.error(
`[MerchantSync] ${errors.length} erreurs sur ${chunk.length} produits`,
errors.map(e => ({
offerId: e.product?.offerId,
errors: e.errors?.errors?.map(err => err.message),
}))
);
}
console.log(
`[MerchantSync] ${chunk.length - (errors?.length || 0)} produits mis à jour`
);
} catch (error) {
console.error('[MerchantSync] Batch failed:', error);
throw error;
}
}
}
function chunkArray<T>(arr: T[], size: number): T[][] {
return Array.from({ length: Math.ceil(arr.length / size) }, (_, i) =>
arr.slice(i * size, i * size + size)
);
}
// Hook déclenché par chaque changement de stock dans votre OMS/ERP
export async function onStockChange(
offerId: string,
newQuantity: number,
currentPrice: number
): Promise<void> {
await batchUpdateMerchantProducts('YOUR_MERCHANT_ID', [
{
offerId,
availability: newQuantity > 0 ? 'in stock' : 'out of stock',
price: { value: currentPrice.toFixed(2), currency: 'EUR' },
},
]);
}
Ce pattern, branché sur les webhooks de votre système de gestion de stock, élimine le décalage feed/réalité. Les marchands top-performers de l'étude utilisent tous une approche événementielle similaire plutôt qu'un export batch planifié.
Scénario concret : migration et product packs d'un e-commerce textile
Prenons le cas de "ModeUrban.fr", un e-commerce de 15 000 produits dans le prêt-à-porter urbain, qui opérait sur une SPA React (CSR) avec un feed Merchant Center exporté 2x/jour via un plugin PrestaShop.
Situation initiale (janvier 2026)
- 15 200 fiches produits actives
- Feed Merchant Center : 11 400 produits approuvés (75 %), 3 800 en disapproval ou warning
- Structured data Product : générée côté client (React), invisible pour Googlebot dans 40 % des cas
- Présence dans les product packs : 8 % des requêtes ciblées
- CTR moyen depuis les product packs : 1.2 %
Le diagnostic en Search Console montrait des warnings massifs dans le rapport "Merchant listings" : incohérences de prix (le SSR retournait un prix avant promotion, le feed le prix promo), images non conformes, GTIN manquants sur 30 % du catalogue.
Le problème JavaScript était le plus insidieux. Leur structured data était injectée dynamiquement par un composant React — ce qui fonctionnait parfaitement dans un navigateur mais échouait quand Googlebot ne réussissait pas le rendering. Un problème documenté et récurrent sur les sites e-commerce en SPA.
Actions techniques (février-mars 2026)
1. Migration vers Next.js App Router avec SSR pour les fiches produits. Le structured data est désormais rendu côté serveur, dans le HTML initial. Vérification systématique avec :
# Vérification que le structured data est bien dans le HTML initial (pas besoin de JS)
curl -s "https://modeurban.fr/produit/veste-cargo-oversize-noire" \
| grep -o 'application/ld+json' \
| wc -l
# Attendu : 1 (au minimum)
# Extraction et validation du JSON-LD
curl -s "https://modeurban.fr/produit/veste-cargo-oversize-noire" \
| python3 -c "
import sys, json
from html.parser import HTMLParser
class LDJSONExtractor(HTMLParser):
def __init__(self):
super().__init__()
self.capture = False
self.data = []
def handle_starttag(self, tag, attrs):
if tag == 'script' and ('type', 'application/ld+json') in attrs:
self.capture = True
def handle_data(self, data):
if self.capture:
self.data.append(data)
def handle_endtag(self, tag):
if tag == 'script':
self.capture = False
parser = LDJSONExtractor()
parser.feed(sys.stdin.read())
for d in parser.data:
parsed = json.loads(d)
print(json.dumps(parsed, indent=2))
# Vérifications critiques
assert 'gtin13' in parsed or 'gtin' in parsed, 'GTIN manquant'
assert 'offers' in parsed, 'Offers manquant'
assert parsed['offers'].get('availability'), 'Availability manquant'
print('✓ Validations critiques passées')
"
# Test en batch sur un échantillon de 500 URLs
cat product_urls_sample.txt | xargs -P 10 -I {} sh -c \
'curl -s {} | grep -q "application/ld+json" && echo "OK: {}" || echo "FAIL: {}"' \
2>/dev/null | grep "FAIL" | wc -l
2. Refonte du feed Merchant Center : passage d'un export CSV biquotidien à la Content API événementielle (script TypeScript ci-dessus), branchée sur les événements de stock et de pricing de leur ERP.
3. Nettoyage GTIN : récupération des EAN manquants via l'API fournisseur, couverture portée de 70 % à 97 %.
4. Conformité images : pipeline automatisé (Sharp + script Node) pour reprocesser les images produit — suppression du fond non-blanc, resize à 1200x1200, suppression de tout overlay texte.
Résultats (mai 2026)
- Produits approuvés Merchant Center : 14 800 / 15 200 (97 %)
- Présence dans les product packs : 41 % des requêtes ciblées (vs 8 %)
- CTR moyen depuis les product packs : 3.8 % (vs 1.2 %)
- Trafic incrémental depuis les product packs : +2 400 sessions/semaine
- CA attribuable : +18 % sur les catégories couvertes
Le facteur le plus impactant n'était pas un seul changement, mais la combinaison SSR + feed temps réel + GTIN complets. Chaque élément isolé n'aurait produit qu'une fraction du résultat.
Monitoring : détecter les régressions avant qu'elles ne coûtent du CA
Le piège des product packs, c'est leur fragilité. Un déploiement qui casse le rendu du JSON-LD sur vos fiches produits, un changement de prix non répercuté dans le feed, une image reprocessée avec un nouveau pipeline qui ajoute un watermark — et vos listings disparaissent silencieusement des packs.
Les signaux à surveiller
En Search Console : le rapport "Shopping" > "Merchant listings" est votre tableau de bord principal. Mais il a un défaut majeur : les données arrivent avec 48-72h de décalage. Quand vous détectez un problème, vous avez déjà perdu 3 jours de visibilité.
En Screaming Frog : un crawl hebdomadaire avec extraction custom du JSON-LD permet de vérifier la complétude des structured data sur l'ensemble du catalogue. Configuration : Custom Extraction > XPath //script[@type='application/ld+json'] > Extract Inner HTML. Exportez et parsez en batch pour détecter les champs manquants.
En monitoring continu : c'est ici qu'un outil comme Seogard prend tout son sens. La détection automatique de régression sur les structured data — un champ offers.availability qui disparaît après un déploiement, un gtin13 qui passe de valide à manquant — permet d'intervenir en heures plutôt qu'en jours.
Les régressions les plus fréquentes
Le problème SSR/CSR hybride. Après une mise à jour de framework (Next.js 14 → 15 par exemple), certains composants basculent silencieusement en client-side rendering. Le structured data qui était dans le HTML initial se retrouve injecté uniquement après hydration. Googlebot le voit (la plupart du temps), mais avec un délai de rendering qui peut causer des incohérences temporelles avec le feed.
Ce type de régression silencieuse rejoint les problèmes documentés sur les sites e-commerce JavaScript : la page a l'air parfaite dans un navigateur, mais le HTML initial est incomplet.
La désynchronisation prix promotionnels. Les soldes, ventes flash et promotions temporaires sont un cauchemar de synchronisation. Le prix promo est actif sur le site, le feed affiche encore l'ancien prix, et le structured data montre un troisième montant intermédiaire. Google détecte l'incohérence et supprime le listing du pack — souvent sans notification explicite en Merchant Center.
Les soft 404 sur fiches produit. Un produit en fin de vie renvoyant une page avec un message "produit indisponible" mais un code HTTP 200 crée un conflit : la page dit "indisponible", le feed dit "out of stock" (ou pire, le feed n'a pas encore été mis à jour), et le structured data indique encore InStock. Ces cas de soft 404 sont particulièrement toxiques pour la confiance que Google accorde à votre feed.
Stratégie de pricing et d'attributs dans les packs
L'analyse des 63 000 marchands révèle un insight contre-intuitif : le prix le plus bas ne gagne pas toujours. Les listings qui dominent les product packs combinent prix compétitif, richesse d'attributs et signaux de confiance (nombre d'avis, politique de retour, délai de livraison).
Le rôle des shippingDetails
Sur le marché français, la mention "Livraison gratuite" dans le product pack est un différenciateur massif. Les marchands qui l'affichent via le structured data shippingDetails (pas juste dans le feed) voient un CTR 40 à 60 % supérieur à listing identique sans cette mention. Le raisonnement technique est simple : Google croise les données du feed et du markup. Si les deux concordent sur la livraison gratuite, le badge est affiché avec confiance.
Exploiter les additionalProperty pour les filtres
Google Shopping expose de plus en plus de filtres de recherche (taille, couleur, matière, usage). Ces filtres sont alimentés par les attributs du feed ET par les propriétés schema.org de la page. Les marchands qui utilisent additionalProperty pour déclarer des attributs spécifiques à leur vertical — "type de semelle", "résistance à l'eau", "certification bio" — apparaissent sur des requêtes longue traîne à très forte intention d'achat que les concurrents ne couvrent pas.
L'intersection avec l'AI Search et les AI Overviews
Les product packs ne vivent pas en isolation. Google intègre de plus en plus les résultats Shopping dans les AI Overviews et dans l'AI Mode. Quand un utilisateur pose une question comme "quelle est la meilleure chaussure pour un marathon en 2026", l'AI Overview peut intégrer un carrousel de produits directement dans la réponse générée.
Les marchands dont les structured data sont riches et cohérentes ont un avantage structurel dans ce contexte : l'IA de Google peut extraire et comparer les attributs produit de manière fiable. Un listing avec poids, drop, matériaux et avis structurés est infiniment plus exploitable par un LLM qu'une fiche produit avec uniquement un titre et un prix.
Ce croisement entre product packs classiques et AI Search signifie que l'investissement dans les structured data produit a un rendement double. Le guide Google sur l'optimisation pour les fonctionnalités génératives confirme que les données structurées sont un signal d'entrée clé pour ces nouveaux formats.
Le cas des requêtes comparatives
Les requêtes de type "X vs Y" ou "meilleur [catégorie] pour [usage]" déclenchent de plus en plus souvent un AI Overview suivi d'un product pack contextuel. Les marchands qui possèdent des fiches produit avec des attributs détaillés et des avis structurés apparaissent dans les deux formats simultanément — doublant leur surface de visibilité sur une seule SERP.
C'est un territoire où la qualité du contenu et la rigueur technique des structured data convergent. Un site qui produit du contenu scaled par IA sans substance ne tirera aucun bénéfice de cette convergence, même avec des structured data parfaites.
Audit et checklist d'éligibilité product packs
Pour déterminer votre position actuelle et identifier les quick wins, voici la méthodologie d'audit que les données de l'étude suggèrent, ordonnée par impact :
Tier 1 — Bloquants (sans eux, pas de product pack) :
- Structured data
Productvalide sur 100 % des fiches, rendues en SSR - Feed Merchant Center actif, sans disapprovals critiques
- Cohérence prix/disponibilité entre feed, structured data et page visible
- Images conformes aux guidelines Merchant Center
Tier 2 — Différenciateurs (passent de "présent" à "cliqué") :
- GTIN/EAN sur > 95 % du catalogue
shippingDetailsethasMerchantReturnPolicydans le markup- Fréquence de mise à jour du feed < 6h (idéalement temps réel)
aggregateRatingavec > 10 avis
Tier 3 — Avantage concurrentiel (domination sur la longue traîne) :
- Attributs spécifiques au vertical via
additionalProperty - Images multiples (3+) par produit
- Descriptions riches avec spécifications techniques extractibles
- Synchronisation événementielle via Content API
Les product packs Google ne sont plus un canal complémentaire — c'est la vitrine principale pour les requêtes transactionnelles. Les marchands qui traitent leur structured data et leur feed avec la même rigueur que leur code de production sont ceux qui captent le trafic. Les autres figurent dans les packs comme du bruit de fond. Un monitoring continu de la cohérence entre vos pages, votre feed et ce que Google affiche réellement est la seule façon de protéger cette visibilité dans la durée.