export function getCanonicalUrl(rawUrl: string): string {
const url = new URL(rawUrl);
const allowedParams = ['page', 'category'];
const keys = Array.from(url.searchParams.keys());
keys.forEach((key) => {
if (!allowedParams.includes(key)) {
url.searchParams.delete(key);
}
});
// Eliminăm slash-ul de la final pentru consistență
return url.toString().replace(/\/$/, "");
}Am văzut prea multe site-uri cu indexarea vraiște doar pentru că echipa de dev a tratat tag-ul <link rel="canonical"> ca pe o chestie opțională de SEO. E o greșeală care te costă scump, mai ales când ai mii de pagini generate dinamic. Hai să vedem cum se face treaba asta corect, direct din ce am lovit eu în producție pe un proiect cu peste 15.000 de URL-uri active.
Parametrii de URL și cum ne furăm singuri căciula
La un magazin online de nișă, ne-am trezit că Googlebot ne consuma tot crawl budget-ul pe pagini duplicate generate de filtre și tracking. URL-uri gen ?utm_source=facebook sau ?sort=price_desc erau indexate separat.
Regula de aur: orice pagină care doar filtrează sau sortează conținutul existent trebuie să aibă canonical către varianta "curată".
Trade-off-ul de care trebuie să fii conștient: Dacă pui canonical pe varianta curată, pierzi din vizibilitatea pe căutări foarte specifice (ex: "pantofi roșii mărimea 42"). Dacă ai un landing page dedicat pentru acea nișă, îi faci URL curat și canonical propriu. Altfel, dacă e doar un simplu parametru de sortare, canonical-ul trebuie să trimită la categoria principală, fără parametri.
Paginația: Marea greșeală pe care o văd peste tot
De când Google a scos din uz suportul pentru rel="prev" și rel="next", am văzut o grămadă de developeri care pun canonical de pe paginile /blog?page=2, /blog?page=3 către prima pagină /blog.
Să nu faceți asta niciodată. Este o greșeală majoră.
Dacă faci asta, îi spui practic motorului de căutare că paginile 2, 3 și 4 sunt identice cu prima pagină. Rezultatul? Google nu va mai accesa link-urile către articolele mai vechi listate pe acele pagini secundare, iar acele articole vor dispărea din index.
Soluția corectă este simplă: fiecare pagină de paginație trebuie să aibă canonical către ea însăși (self-referential). Adică /blog?page=2 va avea canonical tag către /blog?page=2.
Cross-domain canonicals
Am avut cazul unui client care a cumpărat un site concurent mai mic și a vrut să îi mute conținutul pe domeniul principal, fără să facă redirect 301 imediat, din motive de branding tranzitoriu. Am copiat articolele pe domeniul nou și am pus pe domeniul vechi un tag canonical care indica spre cel nou.
Funcționează brici. Google înțelege perfect că autoritatea trebuie transferată către noul domeniu și nu te penalizează pentru conținut duplicat, chiar dacă vorbim de domenii complet diferite.
Cum generăm canonical-ul programatic
Aici e o metodă simplă în TypeScript pentru a curăța URL-ul de parametrii inutili de tracking, păstrând în același timp parametrii esențiali (cum ar fi paginația).
Voi cum gestionați canonicals pe proiecte mari? Mergeți pe automatizări din router sau le generați manual în backend pe baza unei scheme de bază de date?