Un média en ligne de 8 000 articles constate que ses contenus n'apparaissent jamais dans le carrousel Top Stories, malgré un flux de publication quotidien et des Core Web Vitals corrects. Le diagnostic : aucun balisage Article Schema en place. Trois semaines après déploiement sur l'ensemble du catalogue, 23% des impressions proviennent de Top Stories et Discover. Le balisage structuré Article n'est pas un "nice to have" — c'est le ticket d'entrée pour les surfaces de recherche les plus visibles de Google.
Article, NewsArticle, BlogPosting : quel type choisir
Schema.org définit une hiérarchie précise. Article est le type parent. NewsArticle et BlogPosting en héritent. Le choix n'est pas cosmétique — il influence directement les fonctionnalités de recherche auxquelles vous êtes éligible.
NewsArticle
Réservé aux contenus journalistiques au sens strict : actualités, reportages, enquêtes. Google l'utilise comme signal d'éligibilité pour le carrousel Top Stories. Si vous n'êtes pas un média d'information (au sens Google News), utiliser NewsArticle ne vous donnera pas accès magiquement à Top Stories — mais ne pas l'utiliser quand vous y êtes éligible est une erreur.
La documentation Google sur Article précise que NewsArticle est un sous-type approprié pour les articles d'actualité.
BlogPosting
Le choix naturel pour les blogs d'entreprise, les blogs techniques, les blogs personnels. Google traite BlogPosting comme éligible aux rich results classiques : image en vignette, date de publication visible, fil d'Ariane enrichi.
Article (type générique)
En cas de doute, Article fonctionne. C'est le type le plus sûr si votre contenu ne rentre pas clairement dans les deux autres catégories. Un tutoriel technique, un guide pratique, un article d'opinion — Article couvre tout.
Le piège courant : certains CMS (WordPress avec Yoast, par exemple) forcent NewsArticle sur tous les posts par défaut. Si vous gérez un blog e-commerce avec des guides produit, ce n'est pas le bon type. Vérifiez votre configuration.
Arbre de décision
| Contenu | Type recommandé |
|---|---|
| Actualité, breaking news, reportage | NewsArticle |
| Billet de blog, tutoriel, opinion | BlogPosting |
| Guide long-form, étude de cas, contenu mixte | Article |
| Article sponsorisé / advertorial | Article (pas de type spécifique) |
Si vous avez déjà implémenté d'autres types de données structurées sur votre site — Product Schema pour l'e-commerce, FAQ Schema ou BreadcrumbList — la logique est identique : un type Schema = un contrat sémantique avec Google.
Implémentation JSON-LD complète
Voici un balisage BlogPosting complet, avec toutes les propriétés que Google recommande ou requiert. Pas un exemple jouet — un balisage production pour un blog tech publiant 20 articles par mois.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "Migrer de React SPA vers Next.js SSR : retour d'expérience à 15 000 pages",
"description": "Comment nous avons migré un e-commerce de 15 000 pages de React SPA vers Next.js SSR en 3 mois, avec un gain de 40% de trafic organique.",
"image": [
"https://tech.example-store.com/images/migration-nextjs-16x9.webp",
"https://tech.example-store.com/images/migration-nextjs-4x3.webp",
"https://tech.example-store.com/images/migration-nextjs-1x1.webp"
],
"datePublished": "2026-02-15T08:00:00+01:00",
"dateModified": "2026-03-10T14:30:00+01:00",
"author": [{
"@type": "Person",
"name": "Marie Dupont",
"url": "https://tech.example-store.com/auteurs/marie-dupont",
"jobTitle": "Lead SEO",
"sameAs": [
"https://www.linkedin.com/in/marie-dupont-seo",
"https://twitter.com/mariedupont_seo"
]
}],
"publisher": {
"@type": "Organization",
"name": "Example Store Tech Blog",
"logo": {
"@type": "ImageObject",
"url": "https://tech.example-store.com/logo.png",
"width": 600,
"height": 60
}
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://tech.example-store.com/blog/migration-react-spa-nextjs-ssr"
},
"wordCount": 2847,
"articleSection": "Engineering",
"inLanguage": "fr-FR",
"isAccessibleForFree": true
}
</script>
Propriétés critiques — détail
headline : 110 caractères maximum selon les guidelines Schema.org. Google tronque au-delà. Ne pas dupliquer bêtement le <title> — le headline est le titre éditorial de l'article, le title tag est optimisé pour le CTR SERP. Ils peuvent différer. Pour approfondir l'optimisation des title tags, consultez cet article dédié.
image : Google recommande explicitement de fournir trois ratios (16:9, 4:3, 1:1). La raison : selon la surface d'affichage (SERP desktop, Discover mobile, Top Stories), Google choisit le ratio le plus adapté. Une seule image = vous perdez potentiellement des affichages enrichis. Chaque image doit faire au minimum 1200px de large pour être éligible aux fonctionnalités AMP/Discover. L'optimisation des images va au-delà du Schema, mais le format et la taille sont un prérequis ici.
datePublished et dateModified : format ISO 8601 avec fuseau horaire. Google utilise dateModified pour afficher "Mis à jour le..." dans les SERP. Une date de modification antérieure à la date de publication génère une erreur dans le Rich Results Test. Plus subtil : mettre à jour dateModified sans modification substantielle du contenu est un pattern que Google détecte et pénalise (John Mueller l'a confirmé à plusieurs reprises dans des Google Search Central hangouts).
author : depuis fin 2023, Google pousse fortement la notion d'auteur vérifiable (E-E-A-T). Fournir url et sameAs avec des profils sociaux réels n'est pas optionnel en pratique. Un auteur sans page dédiée ni profil vérifiable affaiblit la crédibilité du balisage.
isAccessibleForFree : si vous avez un paywall, cette propriété devient obligatoire. Google s'appuie dessus conjointement avec hasPart et cssSelector pour savoir quelle portion du contenu est gratuite. Ignorer cette propriété sur un site avec metered paywall, c'est risquer la désindexation des pages paywallées.
Génération dynamique avec un framework JavaScript
Sur un site statique ou un CMS serveur classique, le JSON-LD est injecté dans le HTML. Sur un site Next.js, Nuxt, ou Astro, il faut s'assurer que le balisage est présent dans le HTML servi au crawler — pas injecté côté client après hydration.
Si votre site utilise du CSR pur, Google pourrait ne pas voir le balisage structuré. C'est le même problème que pour tout contenu injecté côté client — sujet traité en détail dans SSR vs CSR et impact SEO et pourquoi Google voit une page blanche sur votre SPA.
Voici un composant TypeScript pour Next.js (App Router) qui génère le balisage Article Schema côté serveur :
// components/ArticleSchema.tsx
import type { Article, WithContext } from "schema-dts";
interface ArticleSchemaProps {
title: string;
description: string;
publishedAt: string;
modifiedAt: string;
authorName: string;
authorUrl: string;
authorLinkedIn: string;
images: string[];
url: string;
wordCount: number;
section: string;
type?: "Article" | "BlogPosting" | "NewsArticle";
}
export function ArticleSchema({
title,
description,
publishedAt,
modifiedAt,
authorName,
authorUrl,
authorLinkedIn,
images,
url,
wordCount,
section,
type = "BlogPosting",
}: ArticleSchemaProps) {
const schema: WithContext<Article> = {
"@context": "https://schema.org",
"@type": type,
headline: title.slice(0, 110),
description,
image: images,
datePublished: publishedAt,
dateModified: modifiedAt,
author: [
{
"@type": "Person",
name: authorName,
url: authorUrl,
sameAs: [authorLinkedIn],
},
],
publisher: {
"@type": "Organization",
name: "Example Store",
logo: {
"@type": "ImageObject",
url: "https://tech.example-store.com/logo.png",
},
},
mainEntityOfPage: {
"@type": "WebPage",
"@id": url,
},
wordCount,
articleSection: section,
inLanguage: "fr-FR",
isAccessibleForFree: true,
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
Deux points techniques à noter :
-
Le package
schema-dts(de Google) fournit les types TypeScript pour Schema.org. Il vous empêche de passer une propriété invalide ou un type incorrect à la compilation. Sur un blog à 500+ articles, ce filet de sécurité évite les erreurs silencieuses qui ne se manifestent que dans le Rich Results Test. -
Le
dangerouslySetInnerHTMLest nécessaire pour que Next.js injecte le JSON-LD brut dans le HTML. Avec l'App Router de Next.js 14+, ce composant Server Component sera rendu côté serveur par défaut — le JSON-LD apparaîtra dans la réponse HTML initiale, avant toute exécution JavaScript côté client.
Scénario concret : déploiement sur un média de 6 500 articles
Voici un cas réaliste. Un média spécialisé tech francophone — 6 500 articles publiés sur 4 ans, 120 nouveaux articles par mois, stack WordPress avec un thème custom.
État initial
- Aucun balisage Article Schema (le thème ne l'incluait pas)
- Yoast SEO installé mais la fonctionnalité Schema désactivée par le développeur précédent (conflit avec un autre plugin)
- Trafic organique : 280 000 sessions/mois
- Impressions Google Discover : quasi nulles (< 500/mois)
- Aucune apparition dans Top Stories
Déploiement
Semaine 1 : Audit avec Screaming Frog. Crawl complet du site avec extraction custom du JSON-LD via le mode "Custom Extraction" (XPath : //script[@type='application/ld+json']). Résultat : 0 pages avec Article Schema. 312 pages avaient un résidu de balisage microdata incomplet dans le HTML du thème (des itemprop="author" orphelins sans itemscope).
Semaine 2 : Implémentation via un mu-plugin WordPress pour ne pas dépendre de Yoast :
<?php
/**
* Plugin Name: Article Schema Generator
* Description: Génère le balisage Article Schema JSON-LD pour les posts
*/
add_action('wp_head', 'inject_article_schema');
function inject_article_schema(): void {
if (!is_singular('post')) {
return;
}
$post = get_post();
$author = get_userdata($post->post_author);
$images = [];
$thumbnail_id = get_post_thumbnail_id($post->ID);
if ($thumbnail_id) {
// Générer les 3 ratios recommandés par Google
$ratios = [
'16x9' => [1200, 675],
'4x3' => [1200, 900],
'1x1' => [1200, 1200],
];
foreach ($ratios as $key => [$width, $height]) {
$img = wp_get_attachment_image_url($thumbnail_id, "schema-{$key}");
if ($img) {
$images[] = $img;
}
}
// Fallback sur l'image originale si les tailles custom n'existent pas
if (empty($images)) {
$images[] = wp_get_attachment_image_url($thumbnail_id, 'full');
}
}
$category = get_the_category($post->ID);
$section = !empty($category) ? $category[0]->name : 'General';
// Déterminer le type selon la catégorie
$news_categories = ['Actualités', 'Breaking', 'Industrie'];
$type = in_array($section, $news_categories, true)
? 'NewsArticle'
: 'BlogPosting';
$schema = [
'@context' => 'https://schema.org',
'@type' => $type,
'headline' => mb_substr(get_the_title($post), 0, 110),
'description' => get_the_excerpt($post),
'image' => $images,
'datePublished' => get_the_date('c', $post),
'dateModified' => get_the_modified_date('c', $post),
'author' => [[
'@type' => 'Person',
'name' => $author->display_name,
'url' => get_author_posts_url($author->ID),
'sameAs' => array_filter([
get_the_author_meta('linkedin', $author->ID),
get_the_author_meta('twitter', $author->ID),
]),
]],
'publisher' => [
'@type' => 'Organization',
'name' => get_bloginfo('name'),
'logo' => [
'@type' => 'ImageObject',
'url' => 'https://media.example-tech.fr/logo.png',
],
],
'mainEntityOfPage' => [
'@type' => 'WebPage',
'@id' => get_permalink($post),
],
'wordCount' => str_word_count(wp_strip_all_tags($post->post_content)),
'articleSection' => $section,
'inLanguage' => 'fr-FR',
'isAccessibleForFree' => true,
];
printf(
'<script type="application/ld+json">%s</script>' . "\n",
wp_json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
);
}
Semaine 2-3 : Validation. Soumission d'un échantillon de 50 URLs dans le Rich Results Test de Google. 3 erreurs détectées : des articles sans image à la une (champ image vide). Correction : ajout d'un fallback sur une image par défaut par catégorie.
Vérification en parallèle via l'API URL Inspection de la Search Console pour confirmer que Googlebot voit bien le JSON-LD dans le HTML rendu.
Semaine 3 : Soumission du sitemap mis à jour dans Google Search Console pour accélérer le recrawl des 6 500 URLs. Le sitemap XML incluait déjà les <lastmod> — la modification du mu-plugin ne change pas le contenu visible, donc pas de mise à jour de <lastmod> nécessaire. Mais le recrawl naturel sur 6 500 pages prend 2-3 semaines pour un site de cette taille.
Résultats à 6 semaines
- Rich results (vignette + date) : de 0 à 4 200 pages éligibles dans le rapport "Améliorations" de Search Console
- Impressions Google Discover : de 500/mois à 18 000/mois
- CTR moyen SERP : +2,1 points (de 3,8% à 5,9%) — l'affichage enrichi avec image et date attire davantage le clic
- Trafic organique total : +14% (de 280 000 à 319 000 sessions/mois)
Le gain Discover est le plus spectaculaire. Google Discover favorise fortement les articles avec balisage structuré complet et images haute résolution. Sans Article Schema, le contenu était pratiquement invisible sur cette surface.
Erreurs fréquentes et edge cases
headline vs title tag
Le headline du Schema et le <title> de la page n'ont pas besoin d'être identiques. Le headline est le titre éditorial. Le title tag est optimisé pour la SERP. Mais un écart trop important (sujet différent, mots-clés contradictoires) peut être interprété comme du cloaking implicite. Règle : même sujet, formulation différente si nécessaire.
Dates incohérentes
Google croise datePublished du Schema avec la date visible sur la page et les signaux de crawl historiques. Si votre Schema indique "publié le 10 mars 2026" mais que Googlebot a vu la page pour la première fois en 2024 via le crawl historique, c'est un signal négatif. Ne modifiez jamais datePublished sur un contenu existant.
De même, mettre à jour dateModified sans modifier réellement le contenu (technique dite de "freshness abuse") est un pattern que Google détecte. La Search Console peut signaler des erreurs de dates dans le rapport Rich Results.
Multiples types Schema sur une même page
Vous pouvez (et devriez souvent) combiner Article Schema avec d'autres types. Un article de blog e-commerce peut contenir :
BlogPostingpour l'article lui-mêmeBreadcrumbListpour le fil d'Ariane (guide dédié)FAQPagesi l'article contient une section FAQ (guide FAQ Schema)
Chaque type est un bloc <script type="application/ld+json"> distinct. Ne les imbriquez pas dans un seul objet — utilisez un @graph ou des scripts séparés. La documentation Google sur les données structurées JSON-LD détaille cette approche.
author : Person vs Organization
Google recommande Person pour l'auteur. Utiliser Organization comme auteur est techniquement valide selon Schema.org, mais Google le déconseille explicitement pour les articles. Si l'article est rédigé par une équipe sans auteur identifié, utilisez quand même Person avec "Équipe Éditoriale" et un lien vers une page "À propos" — c'est le compromis le plus sûr pour E-E-A-T.
Articles paginés
Si un article long est découpé sur plusieurs pages (pattern de plus en plus rare mais encore courant sur les médias), le Schema Article doit être présent sur chaque page avec le même @id dans mainEntityOfPage. Chaque page contient son propre headline (ex: "Titre - Page 2"). La gestion SEO de la pagination interagit directement avec le balisage structuré ici.
Validation et monitoring en production
Validation initiale
Trois outils complémentaires :
-
Rich Results Test : le seul outil qui montre exactement ce que Google extraira de votre balisage. Testez en mode "URL" (pas "code") pour vérifier que le JSON-LD est dans le HTML servi par votre serveur.
-
Schema Markup Validator (schema.org) : plus strict que le Rich Results Test. Il valide contre le vocabulaire Schema.org complet, pas seulement les propriétés que Google utilise. Utile pour détecter des propriétés mal typées.
-
Screaming Frog avec extraction custom : pour valider à l'échelle. Configurez une extraction XPath sur
//script[@type='application/ld+json'], puis exportez en CSV et parsez avec un script Python pour détecter les champs manquants ou incohérents sur des milliers de pages.
Monitoring continu
Le problème avec les données structurées, c'est le "silent failure". Un développeur modifie un template, le bloc JSON-LD disparaît, et personne ne s'en aperçoit pendant 3 semaines — jusqu'à ce que le trafic Discover s'effondre.
La Search Console signale les erreurs dans le rapport "Améliorations" > "Article", mais avec un délai de plusieurs jours. Et elle ne vous alerte pas quand un balisage disparaît — elle cesse simplement de le rapporter.
Un outil de monitoring SEO technique comme SEOGard détecte ce type de régression en temps réel : si le JSON-LD Article disparaît d'un template après un déploiement, vous le savez dans l'heure, pas trois semaines après. Sur un média avec 120 publications par mois, cette réactivité évite des pertes de trafic significatives.
Rapport Search Console
Dans la Search Console, le rapport "Améliorations" > "Article" liste :
- Les pages avec balisage valide
- Les erreurs (propriétés manquantes, types incorrects)
- Les avertissements (propriétés recommandées mais absentes)
Un avertissement "image manquante" n'empêche pas l'indexation du Schema, mais vous prive de l'affichage enrichi avec vignette — ce qui réduit votre CTR de manière mesurable. Traitez les avertissements comme des erreurs.
AMP, Discover et Top Stories : les interactions à connaître
AMP n'est plus requis pour Top Stories depuis 2021. Mais le balisage Article Schema reste un prérequis de fait pour les trois surfaces enrichies de Google :
Top Stories : NewsArticle recommandé. Image obligatoire (≥ 1200px). datePublished dans les 48 dernières heures pour les contenus d'actualité. Le site doit respecter les règles Google News.
Google Discover : pas de type Schema spécifique requis, mais les articles avec balisage Article ou BlogPosting complet (image haute résolution + auteur + dates) sont visiblement favorisés dans la sélection algorithmique. Discover est la surface où le ROI du balisage structuré est le plus élevé en 2026 — et la plus imprévisible.
Rich snippets classiques : l'affichage avec vignette, date et fil d'Ariane dans les résultats organiques standard. Fonctionne avec les trois types (Article, BlogPosting, NewsArticle). C'est le gain le plus stable et prévisible.
Une erreur que les médias commettent souvent : ne pas vérifier que les pages qui génèrent le plus de trafic Discover sont correctement balisées. Discover est capricieux — si Google perd le signal structuré sur vos articles les plus performants, le trafic chute brutalement sans warning dans la Search Console.
Pour s'assurer que Google peut bien accéder à vos articles et les rendre correctement — condition préalable à tout balisage structuré — vérifiez que vos pages ne sont pas bloquées par des erreurs d'indexation ou des problèmes de rendu.
En résumé
Le balisage Article Schema est l'un des rares investissements SEO technique à ROI quasi garanti : quelques heures de développement pour un accès durable aux surfaces les plus visibles de Google. La clé, c'est la rigueur — les trois ratios d'image, les dates cohérentes, l'auteur vérifiable, et surtout la surveillance continue pour que rien ne casse silencieusement en production.