import { Metadata } from 'next';
type Props = {
searchParams: { [key: string]: string | string[] | undefined };
};
export async function generateMetadata({ searchParams }: Props): Promise<Metadata> {
// Păstrăm doar parametrii relevanți (ex: paginația)
// Eliminăm UTM-urile și filtrele irelevante pentru SEO
const page = typeof searchParams.page === 'string' ? `?page=${searchParams.page}` : '';
const canonicalUrl = `https://siteul-tau.ro/blog${page}`;
return {
alternates: {
canonical: canonicalUrl,
},
};
}Am văzut prea multe site-uri penalizate aiurea sau cu pagini importante ignorate de Google doar pentru că tag-ul canonical a fost tratat ca "un detaliu de frontend". Dacă ai parametrii de tracking, paginare sau domenii multiple, o setare greșită îți poate distruge traficul organic în câteva zile. Hai să vedem cum facem asta corect, din experiența mea cu un magazin online de peste 50k de produse unde am salvat 40% din bugetul de crawl doar prin curățarea acestor tag-uri.
Coșmarul parametrilor din URL (UTM-uri, filtre, sortări)
Cea mai des întâlnită problemă pe care am rezolvat-o a fost la sistemele de e-commerce. Ai un produs, să zicem o cană de cafea. URL-ul curat e /produs/cana-cafea. Dar userul ajunge acolo din newsletter cu ?utm_source=newsletter sau aplică un filtru de culoare precum ?color=blue.
Dacă nu pui canonical către URL-ul curat, Google va crede că ai 5 pagini diferite cu același conținut. Crawlerul își pierde timpul (crawl budget irosit), iar autoritatea paginii se împarte la cinci.
Trade-off-ul aici: Auto-referențierea (self-referential canonical) e sfântă. Fiecare pagină curată trebuie să aibă un canonical către ea însăși ca să blocheze mizeria de parametri tracking. Dar atenție: dacă pui canonical greșit pe o pagină cu filtre active (unde filtrele chiar schimbă drastic conținutul și vrei ca acele pagini să fie indexate), Google le va ignora complet și nu vei mai ranka pe cuvinte cheie long-tail.
Paginarea: Mitul lui rel="canonical" spre prima pagină
Am văzut asta la greu pe site-uri de știri sau bloguri mari. Ai /blog?page=2, /blog?page=3 și un fost coleg de echipă pune canonical către /blog. Este complet greșit și o rețetă sigură pentru a-ți ascunde conținutul vechi de boții de indexare.
Dacă faci asta, Google va indexa doar prima pagină și va ignora restul paginilor din listă. Consecința? Nu va mai crawla link-urile către articolele mai vechi care apar doar pe paginile 2, 3 sau 4. Practic, îți îngropi propriul conținut.
Cum e corect: Fiecare pagină din paginare trebuie să aibă canonical către ea însăși (ex: /blog?page=2 are canonical către /blog?page=2). Alternativ, dacă ai o pagină de tip "View All" care se încarcă rapid și conține toate articolele, poți trimite toate paginile de paginare acolo. Dar la proiecte mari, varianta self-referential pe fiecare pagină din listă e cea mai sigură și performantă.
Cross-domain canonicals când distribui conținutul
Am avut un caz la un proiect unde publicam aceleași articole tehnice pe blogul companiei și pe Medium sau Dev.to pentru reach. Fără cross-domain canonical, Google penaliza blogul nostru mic în favoarea platformelor mari care aveau autoritate uriașă, considerând că noi am copiat textul.
Dacă preiei conținut din altă parte sau îl distribui pe mai multe domenii pe care le controlezi, pune tag-ul canonical pe platformele secundare către sursa originală (site-ul tău). Google înțelege schema asta și pasează autoritatea (link juice) către site-ul tău principal, chiar dacă textul apare identic în trei locuri diferite.
În concluzie, canonical nu este o directivă obligatorie pentru Google (cum e noindex), ci o recomandare puternică. Dacă îi dai semnale contradictorii (ex: pui canonical către pagina X, dar în sitemap pui pagina Y), Google te va ignora complet și va alege el ce versiune vrea să afișeze.
Voi cum generați dinamic canonical-ul în stack-ul actual? Folosiți middleware sau îl lăsați în seama framework-ului de frontend?