// utils/getCanonicalUrl.ts
export function buildCanonicalUrl(baseUrl: string, pathname: string, searchParams: Record<string, string | string[] | undefined>): string {
const url = new URL(pathname, baseUrl);
// Whitelist pentru parametri care generează pagini unice ce TREBUIE indexate
const allowedParams = ['page', 'brand'];
Object.entries(searchParams).forEach(([key, value]) => {
if (allowedParams.includes(key) && typeof value === 'string') {
url.searchParams.set(key, value);
}
});
return url.toString();
}Am curățat recent un dezastru pe un e-commerce cu vreo 45.000 de SKU-uri unde traficul organic scăzuse cu 30% în doar două luni. Problema? Echipa de frontend pusese tag-ul canonical de pe toate paginile din categorie către pagina principală fără filtre, iar Google începuse să de-indexeze paginile de produs. Dacă lucrezi cu URL-uri dinamice, paginare sau conținut preluat pe mai multe domenii, un tag canonical setat prost îți distruge SEO-ul mult mai repede decât un server lent.
Parametrii din URL: ce păstrezi și ce elimini
Filtrele de sortare, culorile, mărimile, tracking-ul de marketing (?utm_source=...) sau parametrii de sesiune creează mii de URL-uri pentru exact aceeași pagină. Google le vede pe toate ca fiind conținut duplicat.
Regula de aur pe care o aplic pe orice proiect: URL-urile cu parametri de tracking sau sortare trebuie să aibă tag-ul canonical îndreptat către URL-ul curat, fără acești parametri.
Există totuși un trade-off important aici: dacă ai pagini de filtru dedicate pe care chiar vrei să le indexezi (de exemplu, /telefoane/samsung), acelea trebuie să aibă canonical self-referential (/telefoane/samsung), nu către /telefoane. Dacă le trimiți pe toate în rădăcină, pierzi tot traficul pe keywords de nișă (long-tail).
Paginarea: mitul "Page 2 trimite la Page 1"
Asta e o greșeală rămasă din vremurile când Google folosea rel="next" și rel="prev". Din 2019, Google ignoră complet acele tag-uri și tratează paginarea ca pe niște pagini individuale.
Dacă pui rel="canonical" de pe /produse?page=2 către /produse, îi spui practic botului: "Ignoră produsele de pe pagina 2, sunt la fel ca cele de pe pagina 1". Rezultatul? Google nu mai indexează produsele accesibile doar din paginile secundare.
Soluția corectă este ca fiecare pagină din paginare să aibă un tag canonical self-referential:
/produseare canonical către/produse/produse?page=2are canonical către/produse?page=2
Cross-domain canonicals și syndication
Am avut cazul unui client care publica articolele de pe blogul tehnic pe încă două platforme media ale partenerilor. Fără un tag cross-domain, domeniul partenerilor (care avea autoritate mai mare) fura tot traficul pentru articolul original.
Pe site-ul secundar trebuie să adaugi un tag care trimite direct la sursa primară. Google înțelege că acolo e autorul original și va credita URL-ul tău. Singura condiție e ca domeniul sursă să fie accesibil și să nu aibă redirect-uri în lanț.
Voi cum gestionați generarea dinamică de canonical-uri în proiectele voastre? Le curățați într-un middleware pe server sau aveți helpers dedicați în frontend?