Schema markup per articoli con link affiliati: Product, Review, ItemList senza penalizzazioni
Guida tecnica a schema markup per articoli affiliate: Product, Review, ItemList, FAQPage con esempi JSON-LD e best practice Google.
Gli articoli affiliate vivono o muoiono sui dettagli tecnici. Puoi avere la migliore recensione del web, ma se Search Console segnala errori di structured data o se Google considera il tuo markup manipolativo, il rich result sparisce e con lui buona parte del CTR organico. Questa guida copre gli schema effettivamente utili per contenuti affiliate, gli esempi JSON-LD pronti da adattare, e gli errori che vediamo più spesso nei progetti editoriali italiani.
L'obiettivo non è ottenere stelline a tutti i costi: è costruire una semantica coerente che rispetti le linee guida Google, renda l'articolo eleggibile per i rich result dove ha senso, e non entri in conflitto con altri strumenti di monetizzazione. AnchorLabs, il widget JS che usiamo in produzione per iniettare link contestuali affiliati, è stato progettato proprio per non toccare il JSON-LD già presente nella pagina: qualunque sia la tua strategia di markup, il widget lavora sul DOM editoriale senza interferire.
Quali schema servono davvero (e quali no)
La tentazione di impilare ogni schema disponibile è forte. Sbagliata. Google ignora o penalizza markup ridondante, e ogni tipo aggiuntivo è un vettore di warning in più. Per un articolo affiliate tipico ti servono al massimo tre o quattro tipi.
Article (o NewsArticle / BlogPosting) è il contenitore base. Marca autore, data di pubblicazione, data di aggiornamento, headline, immagine principale. Non è opzionale: senza Article, Google fatica a capire che stai pubblicando contenuto editoriale e non una pagina prodotto travestita.
Product va usato solo se l'articolo recensisce effettivamente uno o più prodotti specifici. Se stai scrivendo una guida comparativa ("migliori aspirapolvere robot 2026"), Product diventa utile solo quando la recensione è abbastanza approfondita da giustificarlo: immagine, marca, descrizione originale, e idealmente una Review o AggregateRating.
Review e AggregateRating sono i più delicati. Dal settembre 2019 Google ha ristretto i self-serving reviews per i tipi LocalBusiness e Organization: un'azienda non può marcare con stelle le recensioni su se stessa presenti sul proprio sito. Questa restrizione non si applica al tipo Product, che resta eleggibile per review snippet anche su siti editoriali affiliate. La regola pratica è: se hai testato il prodotto o fatto un confronto strutturato, Review è lecita; se stai solo riassumendo informazioni di terzi, salta il rating. Il vero rischio per Product è la spam policy: AggregateRating con numeri inventati espone a un'azione manuale.
ItemList è il pattern ideale per listicle ("i 10 migliori"). Ordina gli elementi, comunica a Google la struttura della pagina, e funziona bene con HowTo o Article come contenitore. È anche lo schema più sicuro da implementare perché non richiede rating e non innesca i controlli anti-manipolazione.
FAQPage aumenta lo spazio occupato in SERP, ma i rich result FAQ sono oggi riservati esclusivamente a siti governativi e sanitari: per editoria affiliate generica non vengono mostrati. Attenzione: Google vuole FAQ genuine, non domande inventate per farcire keyword.
Article + Product: il pattern base
Ecco un esempio completo per una recensione singola. Nota come l'Article e il Product siano entità separate ma collegate via mainEntity, e come il Review sia annidato dentro Product con un Author distinto dall'autore dell'articolo solo se la review è attribuibile a una persona fisica diversa.
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "BlogPosting",
"@id": "https://example.it/recensione-xyz#article",
"headline": "Recensione XYZ Pro: vale i 499 euro?",
"datePublished": "2026-05-20T09:00:00+02:00",
"dateModified": "2026-05-20T09:00:00+02:00",
"author": {
"@type": "Person",
"name": "Stefano Rossi",
"url": "https://example.it/autori/stefano"
},
"publisher": {
"@type": "Organization",
"name": "Example Magazine",
"logo": {
"@type": "ImageObject",
"url": "https://example.it/logo.png"
}
},
"image": "https://example.it/img/xyz-pro-hero.jpg",
"mainEntityOfPage": "https://example.it/recensione-xyz",
"about": { "@id": "https://example.it/recensione-xyz#product" }
},
{
"@type": "Product",
"@id": "https://example.it/recensione-xyz#product",
"name": "XYZ Pro",
"brand": { "@type": "Brand", "name": "XYZ" },
"image": "https://example.it/img/xyz-pro.jpg",
"description": "Aspirapolvere robot con mappatura laser e svuotamento automatico.",
"review": {
"@type": "Review",
"author": { "@type": "Person", "name": "Stefano Rossi" },
"datePublished": "2026-05-20",
"reviewBody": "Dopo due settimane di test su 120 metri quadri, XYZ Pro si conferma...",
"reviewRating": {
"@type": "Rating",
"ratingValue": "4.5",
"bestRating": "5",
"worstRating": "1"
}
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.4",
"reviewCount": 312,
"bestRating": "5"
},
"offers": {
"@type": "AggregateOffer",
"priceCurrency": "EUR",
"lowPrice": "479",
"highPrice": "529",
"offerCount": 4,
"availability": "https://schema.org/InStock",
"url": "https://example.it/recensione-xyz#offerte"
}
}
]
}
Tre dettagli che fanno la differenza. Primo: @graph con @id espliciti permette di collegare Article e Product senza duplicare dati. Secondo: AggregateOffer invece di Offer singola evita di dover aggiornare il markup ogni volta che un merchant cambia prezzo; lowPrice e highPrice coprono il range reale. Terzo: la URL dentro offers punta a un'ancora interna (#offerte), non direttamente al link affiliato. Questo è cruciale, ne parliamo nella prossima sezione.
Offers con link affiliati: il problema e la soluzione
Il punto più frainteso del markup affiliate è la proprietà offers.url. Molti editori la fanno puntare direttamente al link di tracking del network (Amazon Associates, Awin, TradeDoubler), pensando di aiutare Google a capire dove va il click. È un errore tecnico e strategico.
Tecnico perché Google vuole che offers.url punti alla pagina dove l'utente può completare l'acquisto in modo trasparente. Un link di tracking con parametri affiliate e redirect multipli è fragile (scade, cambia formato, viene bloccato) e viene letto da Googlebot come una URL diversa ogni volta. Strategico perché così esponi il tuo link di monetizzazione direttamente nel sorgente machine-readable della pagina: è un segnale debole ma continuo di commercial intent che non aiuta l'articolo a posizionarsi come contenuto editoriale.
La soluzione è semplice: offers.url punta a un'ancora interna della tua stessa pagina (la sezione "dove comprarlo") oppure alla URL merchant canonica senza parametri di tracking. I link affiliati reali restano nel corpo HTML, marcati con rel="sponsored". Se usi un widget come AnchorLabs per iniettare link contestuali affiliati in modo dinamico, il JSON-LD statico non va toccato: il widget lavora sul testo, non sul markup semantico, e questo mantiene la separazione pulita fra livello editoriale e livello di monetizzazione.
Sulle linee guida rel: dal settembre 2019 Google accetta tre valori per i link commerciali: sponsored (link pagati o affiliati), ugc (contenuto generato dagli utenti), nofollow (generico). Per affiliate la scelta corretta è sponsored. Puoi combinarlo (rel="sponsored nofollow") per compatibilità con vecchi crawler, ma non è necessario. Evita rel="nofollow" da solo sugli affiliate: funziona, ma comunica meno informazione a Google rispetto a sponsored.
ItemList per listicle e guide comparative
Per le guide "migliori N" ItemList è lo schema più efficace. Ecco un esempio completo che combina BlogPosting come contenitore e ItemList come mainEntity, con ciascun elemento tipizzato come Product.
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "BlogPosting",
"@id": "https://example.it/migliori-aspirapolvere-robot-2026#article",
"headline": "I 5 migliori aspirapolvere robot del 2026",
"datePublished": "2026-05-20",
"dateModified": "2026-05-20",
"author": { "@type": "Person", "name": "Stefano Rossi" },
"mainEntity": { "@id": "https://example.it/migliori-aspirapolvere-robot-2026#list" }
},
{
"@type": "ItemList",
"@id": "https://example.it/migliori-aspirapolvere-robot-2026#list",
"itemListOrder": "https://schema.org/ItemListOrderAscending",
"numberOfItems": 5,
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"item": {
"@type": "Product",
"name": "XYZ Pro",
"image": "https://example.it/img/xyz-pro.jpg",
"url": "https://example.it/migliori-aspirapolvere-robot-2026#xyz-pro",
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.5",
"reviewCount": 312
}
}
},
{
"@type": "ListItem",
"position": 2,
"item": {
"@type": "Product",
"name": "ABC Smart",
"image": "https://example.it/img/abc-smart.jpg",
"url": "https://example.it/migliori-aspirapolvere-robot-2026#abc-smart",
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.3",
"reviewCount": 198
}
}
}
]
}
]
}
L'ordine (itemListOrder) è importante: se la tua classifica è ranked mettilo ascending o descending, se è puramente editoriale usa Unordered. Ogni item.url deve puntare a un'ancora esistente nella pagina: Google valida questa corrispondenza e un link rotto genera warning immediato.
Errori comuni che vediamo in Search Console
Dopo aver migrato decine di testate su setup affiliate strutturato, questi sono i warning ricorrenti.
Missing field "offers" su Review o Product. Succede quando marchi un prodotto senza prezzo. Soluzione: AggregateOffer con range di prezzo derivato dai merchant attivi, o rimuovi del tutto Product se l'articolo non è una recensione vera e propria.
Missing field "author" su Review. Il reviewer deve essere una Person o Organization esplicita. "Redazione" come string non basta: serve { "@type": "Organization", "name": "Redazione Example" }.
Invalid value in field "ratingValue". Google vuole numeri, non stringhe in formato localizzato. Usa "4.5" o 4.5, mai "4,5".
Duplicate field "aggregateRating". Accade quando marchi sia Product che Review con aggregateRating e i valori divergono. Tienilo solo a livello Product.
Spam policy: review snippets. Questo non è un warning tecnico ma un'azione manuale. Scatta quando Google giudica che il rating non corrisponda a un giudizio editoriale genuino. Prevenzione: rating solo su prodotti realmente testati o confrontati, reviewBody con contenuto originale di almeno 80-100 parole, AggregateRating basato su dati reali (non inventati per avere le stelline).
Per approfondire l'impatto che strutture markup pesanti possono avere sul caricamento, affiliate link e Core Web Vitals tratta il lato performance di queste decisioni.
Validator e testing: il workflow pratico
Tre strumenti, in ordine di utilità. Rich Results Test di Google (search.google.com/test/rich-results) ti dice se la pagina è eleggibile per rich result e quali warning ha. È l'unico che riflette davvero cosa Google farà. Schema Markup Validator (validator.schema.org) controlla la conformità schema.org pura: utile per intercettare syntax error, meno per decisioni di eligibility. Search Console > Enhancements mostra dati aggregati su tutta la property: è dove vedi errori che compaiono solo in crawl reali, non nel test puntuale.
Il workflow che consigliamo: Rich Results Test prima del deploy, Schema Validator per double-check sintassi, Search Console monitoring settimanale. Quando aggiungi un nuovo template (per esempio passi da Review singola a ItemList), testa almeno 5 URL reali prima di propagare il template a tutta la categoria.
Un pattern spesso ignorato: il JSON-LD va iniettato server-side o almeno renderizzato prima del first paint. Se lo aggiungi via JavaScript post-load, Googlebot lo processa ma con latenza e alcuni rich result smettono di attivarsi. Le sezioni affiliate dinamiche (widget di comparazione prezzi, tabelle live) vanno gestite come componenti separati dal markup semantico statico. AnchorLabs, per esempio, inietta link contestuali sul DOM ma non produce JSON-LD: la responsabilità del markup semantico resta del tuo CMS, ed è così che deve essere per evitare race condition fra crawl e rendering.
FAQPage: ancora utile?
Dal 2023 Google ha ridotto drasticamente i rich result FAQ, riservandoli esclusivamente a siti governativi e sanitari. Per editoria affiliate i rich result FAQ non vengono mostrati, senza eccezioni per nicchia o query. Il markup FAQPage resta però utile per un motivo: aiuta Google a capire la struttura semantica della pagina e può favorire featured snippet estratti dalle risposte.
La regola pratica: se hai davvero FAQ genuine sull'argomento (non domande retoriche), marcale. Se devi inventartele per riempire la pagina, lascia perdere: il rischio di essere filtrato come spam supera il beneficio potenziale.
Coordinare markup e strategia editoriale
Il markup strutturato funziona solo se riflette la realtà editoriale. Una testata che scrive recensioni vere con metodologia dichiarata può permettersi Review + AggregateRating aggressivi. Un aggregatore di offerte no, e dovrebbe fermarsi a Article + ItemList. Questa auto-onestà è la variabile più sottovalutata: Google ha diversi segnali per distinguere i due casi, e forzare markup da recensione su contenuto da aggregatore è uno dei modi più rapidi per attirare un'azione manuale.
Sul versante monetizzazione, la separazione fra livello semantico (JSON-LD) e livello commerciale (link affiliati nel corpo) è la stessa separazione che raccomandiamo a livello tecnico: gli script di monetizzazione non devono riscrivere o contaminare il markup strutturato. Per chi usa AnchorLabs questo è il default: il widget si attacca a selettori CSS editoriali e aggiunge trigger di tooltip sui keyword, senza modificare head, senza iniettare JSON-LD, senza toccare gli offers già dichiarati. Se vuoi approfondire come bilanciare monetizzazione e qualità editoriale, monetizzare una testata online offre una prospettiva più ampia, mentre link contestuali vs banner mostra perché la strategia di placement influisce sui segnali di qualità che Google osserva.
Checklist finale
Prima di pubblicare un articolo affiliate con structured data, verifica questa lista. Article o BlogPosting presente con author, datePublished, dateModified, image. Product solo se recensisci davvero, mai su liste generiche. Review con reviewBody originale di almeno 80 parole e author esplicito. AggregateRating solo con numeri reali, mai inventati. Offers con AggregateOffer e url interna, non link di tracking diretto. ItemList per listicle con itemListOrder dichiarato e item.url che punta ad ancore reali. Rel="sponsored" su tutti i link affiliati nel corpo. Rich Results Test passato senza errori e senza warning critici. JSON-LD renderizzato server-side, non post-load via JS.
Se il setup rispetta questa lista sei al di sopra del 90% delle testate affiliate italiane che vediamo in audit. Il markup non ti farà classificare da solo, ma eviterà che le tue pagine vengano declassate per problemi tecnici, e questo in un ecosistema affollato come quello affiliate è già un vantaggio competitivo significativo.
Domande frequenti
Posso usare Product schema su un articolo editoriale con link affiliati?
Sì, ma solo se l'articolo recensisce realmente il prodotto e fornisce contenuto originale. Google richiede che la pagina sia la destinazione primaria dell'informazione sul prodotto, non un semplice elenco di offerte scrapate da altri siti.
Devo marcare ogni link affiliato con rel=sponsored?
Sì. Google dal 2019 raccomanda rel=sponsored per link affiliati e pubblicitari. Puoi combinarlo con nofollow (rel="sponsored nofollow") ma sponsored da solo è sufficiente e semanticamente più corretto.
ItemList causa problemi se contiene prodotti con link affiliati?
No, ItemList è perfettamente compatibile con contenuti affiliate purché ogni item punti a una URL reale raggiungibile e rappresenti un elemento effettivamente presente nella pagina visibile all'utente.
Come evito il warning "Missing field offers" su Review schema?
Aggiungi una proprietà offers con Offer o AggregateOffer anche minimale (price, priceCurrency, availability, url). Se non conosci il prezzo esatto usa AggregateOffer con lowPrice e highPrice derivati dai merchant partner.