Dokumentacja

Ustaw adres kanoniczny

Ustaw adres kanoniczny

Ta sama strona jest zwykle dostępna pod kilkoma adresami: z www i bez, z ukośnikiem na końcu lub bez, z ?utm_source=newsletter albo ?sort=price na końcu. Znacznik kanoniczny (canonical) mówi Google, który adres jest prawdziwy, więc strona jest w wynikach raz, z wszystkimi linkami liczonymi razem, zamiast konkurować z własnymi kopiami.

Dwie rzeczy idą źle. Bez znacznika Google zgaduje i czasem wybiera adres z parametrami śledzącymi. Gorzej, gdy canonical wskazuje na inną stronę, prawie zawsze na adres testowy (https://staging.example.com/…), który został po starcie: mówi Google, że prawdziwa strona jest gdzie indziej, i działająca strona może wypaść z wyników na rzecz adresu, którego nikt nie powinien widzieć. Lista kontrolna strony oznacza brak znacznika jako Popraw, a canonical na innym hoście jako Sprawdź.

Jak wygląda poprawny canonical

Jeden znacznik w <head> strony, z pełnym adresem tej samej strony:

<link rel="canonical" href="https://example.com/services/">
Canonical Wynik
własny adres strony w Twojej domenie OK
Twoja domena z www lub bez OK (ale użyj wersji, na którą strona przekierowuje, zobacz jeden adres, z www lub bez)
inny host, np. staging.example.com lub example.webflow.io Sprawdź
brak znacznika Popraw

Każda strona wskazuje na siebie, nie na stronę główną. Canonical na stronę główną na każdej podstronie mówi Google, że wszystkie strony są kopiami strony głównej.

Sprawdź sam

Zamiast example.com wpisz swoją stronę i sprawdź też podstronę:

curl -sL https://example.com | grep -ioE '<link[^>]+rel="?canonical"?[^>]*>'
curl -sL https://example.com/services/ | grep -ioE '<link[^>]+rel="?canonical"?[^>]*>'

Każde polecenie powinno wypisać jeden znacznik, którego href to własny adres tej strony w działającej domenie.

Jak to naprawić

WordPress

Sam WordPress dodaje canonical tylko do pojedynczych wpisów i stron. Yoast SEO i Rank Math dodają go do każdej strony (główna, kategorie, archiwa) i są najprostszą poprawką brakującego znacznika: zainstaluj jedną z nich, a znacznik się pojawi.

Gdy canonical wskazuje na adres testowy, stary adres jest gdzieś jeszcze zapisany:

  1. Settings → General: WordPress Address (URL) i Site Address (URL) muszą być oba adresem produkcyjnym.
  2. Pojedyncza strona może mieć własny canonical: pole Yoast SEO → Advanced → Canonical URL albo Rank Math → Advanced → Canonical URL. Puste oznacza "ta strona", i o to chodzi.
  3. Jeśli adres testowy jest jeszcze w bazie (wpisy, widżety, ustawienia wtyczek), zamień go wszędzie. Z WP-CLI najpierw zrób próbę bez zmian:
wp search-replace 'https://staging.example.com' 'https://example.com' --all-tables --dry-run
wp search-replace 'https://staging.example.com' 'https://example.com' --all-tables

Przed drugim poleceniem zrób kopię zapasową bazy. Bez WP-CLI to samo zrobi wtyczka do wyszukiwania i zamiany. Potem wyczyść pamięć podręczną strony.

Node.js i Next.js

W Next.js App Router ustaw metadataBase raz w głównym layoucie, a canonical na każdej stronie:

// app/layout.js
export const metadata = {
    metadataBase: new URL('https://example.com'),
};

// app/services/page.js
export const metadata = {
    alternates: { canonical: '/services/' },
};

Dla stron dynamicznych zwróć go z generateMetadata:

export async function generateMetadata({ params }) {
    const { slug } = await params;

    return { alternates: { canonical: `/blog/${slug}` } };
}

Nie umieszczaj alternates.canonical w głównym layoucie: każda strona, która go nie nadpisze, go odziedziczy, i cała witryna wskaże na stronę główną. Jeśli canonical pokazuje adres podglądu, metadataBase jest budowany ze zmiennej środowiskowej, której nie ustawiono dla produkcji.

Laravel

W <head> szablonu:

<link rel="canonical" href="{{ url()->current() }}">

url()->current() to bieżący adres bez parametrów zapytania, więc warianty z ?utm_… i ?page= wskazują na czysty adres. Za load balancerem lub Cloudflare upewnij się, że Laravel ufa proxy, inaczej zbuduje adresy http://. Jeśli budujesz canonical z config('app.url'), sprawdź APP_URL w .env na produkcji i uruchom php artisan config:cache.

Statyczny HTML

Dodaj znacznik do <head> każdej strony, każdy z jej własnym adresem:

<link rel="canonical" href="https://example.com/contact/">

Użyj dokładnie tej formy, której strona naprawdę używa: https://, z www lub bez i z ukośnikiem na końcu lub bez, tak jak strona przekierowuje.

Shopify

Motywy Shopify wypisują canonical w theme.liquid. Jeśli lista kontrolna go nie znajduje, otwórz Online Store → Themes → … → Edit code → Layout → theme.liquid i dodaj w <head>:

<link rel="canonical" href="{{ canonical_url }}">

Jeśli wskazuje na *.myshopify.com lub starą domenę, ustaw właściwą domenę jako główną w Settings → Domains.

Wix

Wix sam dodaje canonical na podstawie podłączonej domeny. Jeśli wskazuje na zły host, sprawdź, czy Twoja domena jest podłączona i ustawiona jako główna. Pojedyncza strona może mieć własny canonical w ustawieniach SEO strony (Advanced SEO); zostaw go pustym, chyba że masz powód.

Webflow

Otwórz Site settings → SEO i ustaw Global canonical tag URL na domenę produkcyjną, np. https://example.com (bez ścieżki; Webflow dodaje ścieżkę każdej strony). Sprawdź też, czy domena jest ustawiona jako domyślna w Site settings → Publishing, potem kliknij Publish.

Squarespace

Squarespace sam dodaje canonical i nie da się go edytować. Używa domeny głównej: jeśli pokazuje *.squarespace.com lub starą domenę, ustaw właściwą jako główną w ustawieniach Domains.

Po starcie lub przeprowadzce

Sprawdź canonical w dniu startu strony i po każdej zmianie domeny. To jeden z niewielu błędów, których nie widać na stronie, które niczego nie psują odwiedzającym i które przez tygodnie po cichu kierują Google na zły adres.

Potwierdź poprawkę

Uruchom ponownie polecenia curl z sekcji Sprawdź sam, potem otwórz cel w PulseKeeper i kliknij Sprawdź teraz na zakładce Lista kontrolna. Pozycja zmieni się na OK w ciągu kilku minut, a nie dopiero przy kolejnym codziennym sprawdzeniu. W Google Search Console URL inspection pokazuje zarówno canonical, który podałeś, jak i ten, który wybrał Google.