Modelowane listy odbiorców nie zawierają konkretnych osób, tylko prawdopodobieństwa. Wyjaśniam, jak powstają, gdzie ich szukać w panelu i jak czytać ich raporty.
Dostaję dziś do opieki coraz więcej serwisów, w których treść leży w jednym systemie, a strona, którą widzi użytkownik, jest osobną aplikacją pobierającą tę treść przez interfejs programistyczny. Zwykle trafiam do takiego projektu w jednym z dwóch momentów: albo tuż przed migracją, albo pół roku po niej, kiedy ruch z wyszukiwarki nie wrócił do poprzedniego poziomu.
Chcę od razu rozprawić się z uproszczeniem, które krąży w obie strony. Rozdzielenie treści od warstwy prezentacji nie jest ani zabójstwem SEO, ani jego usprawnieniem. Jest przesunięciem odpowiedzialności. W klasycznym systemie zarządzania treścią bardzo dużo rzeczy istotnych dla wyszukiwarki działało domyślnie — adresy, przekierowania, znaczniki, mapa witryny, statusy odpowiedzi. Po rozdzieleniu warstw nic nie działa domyślnie. Wszystko trzeba świadomie zaimplementować.
Poniżej lista rzeczy, które w takich projektach sprawdzam i o które proszę zespół. Ułożona nie tematycznie, a według tego, jak często brak danego elementu kosztuje widoczność.
W architekturze rozdzielonej treść jest przechowywana bez informacji o tym, jak ma zostać wyświetlona. Aplikacja frontendowa pobiera ją i buduje z niej stronę. Zaletą jest swoboda: ta sama treść zasila serwis, aplikację mobilną i inne kanały.
Problem dla wyszukiwarki jest prostszy, niż się zwykle opisuje. Robot potrzebuje adresu, który zwraca poprawny status i kompletną treść wraz z metadanymi oraz linkami prowadzącymi dalej. W klasycznym systemie ten kontrakt był spełniony przez sam silnik. Tutaj każdy jego element realizuje kod napisany przez zespół, który — i mówię to bez złośliwości — bardzo często nie miał w wymaganiach ani słowa o wyszukiwarce.
Stąd charakterystyczna cecha takich wdrożeń: strona działa bez zarzutu dla człowieka i jednocześnie jest w połowie niewidoczna dla robota. Nie ma tu żadnej kary ani uprzedzenia algorytmu wobec nowoczesnych technologii. Jest brak kilku elementów, które nikomu nie przyszły do głowy, bo w poprzednim świecie były darmowe.
Najważniejsza decyzja techniczna w takim projekcie dotyczy tego, gdzie powstaje kod strony. Warianty są cztery i różnią się konsekwencjami.
Praktyczna zasada, którą powtarzam na spotkaniach technicznych: wszystko, co ma się pozycjonować, powinno być w dokumencie przychodzącym z serwera. Elementy interaktywne mogą doładowywać się później, ale treść, nagłówki, metadane i linki nie należą do tej kategorii.
Lista z audytów, w kolejności częstotliwości.
Linki, które nie są linkami. Nawigacja zbudowana na elementach reagujących na kliknięcie, bez klasycznego odnośnika z adresem, jest dla robota ścianą. To pojedynczy najczęstszy i najkosztowniejszy błąd w tej architekturze.
Statusy odpowiedzi. Nieistniejąca podstrona zwraca poprawną odpowiedź i wyświetla komunikat o błędzie w treści. Wyszukiwarka widzi tysiące poprawnych, pustych adresów. To samo dotyczy przekierowań realizowanych po stronie przeglądarki zamiast po stronie serwera.
Metadane wstawiane dopiero po wczytaniu skryptu. Tytuł i opis podmieniane w przeglądarce działają zwykle, ale w praktyce widuję wersje, gdzie każda podstrona ma w źródle ten sam tytuł domyślny.
Adresy kanoniczne. Albo nie ma ich wcale, albo wszystkie wskazują na stronę główną, albo są generowane z bieżącego adresu razem z parametrami sortowania.
Paginacja i filtry. Nieskończone przewijanie bez alternatywnych adresów oznacza, że dalsze pozycje z listy nie istnieją dla robota. Filtry przepisane do adresu bez ograniczeń tworzą z kolei nieskończoną liczbę kombinacji do odwiedzenia.
Środowiska testowe. Kopia serwisu dostępna publicznie, bez blokady indeksowania, konkurująca z produkcją. Zdarza się w tej architekturze częściej niż w klasycznej, bo takich środowisk jest więcej.
Ten punkt jest organizacyjny, ale odpowiada za bardzo dużą część efektu.
W klasycznym systemie osoba redagująca ma pod treścią pola na tytuł w wyszukiwarce, opis, adres podstrony i obrazek do udostępniania. W systemie bezgłowym te pola trzeba świadomie zdefiniować w modelu treści. Jeśli tego nie zrobiono, redakcja nie ma jak wpłynąć na to, co widać w wynikach — i po wdrożeniu okazuje się, że tytuł jest generowany automatycznie z nazwy wpisu.
Minimalny zestaw, o który proszę na etapie projektowania modelu: tytuł dla wyszukiwarki, opis, uchwyt adresu z historią zmian, obrazek do udostępniania, przełącznik indeksowania oraz pole na adres kanoniczny w przypadkach szczególnych. Do tego pole na dane strukturalne albo mechanizm ich generowania z pól treści.
Historia zmian uchwytu adresu jest tu elementem, o którym najczęściej się zapomina. Bez niej zmiana tytułu wpisu przez redaktora zmienia adres i tworzy błąd w miejscu, gdzie wcześniej była działająca podstrona z linkami.
Serwis rozdzielony bywa bardzo szybki i bywa bardzo wolny, w zależności od tego, ile pracy zostawiono przeglądarce. Dwie rzeczy pilnuję szczególnie.
Pierwsza to rozmiar paczki JavaScriptu i to, czy jest dzielona według widoków. Aplikacja ładująca kod całego serwisu przy wejściu na jeden artykuł obciąża każde urządzenie, a najmocniej te słabsze.
Druga to czas odpowiedzi serwera przy renderowaniu na żądanie. Bez buforowania i bez sieci dostarczania treści łatwo tu wyjść gorzej niż w krytykowanym klasycznym systemie z porządną wtyczką cache.
Mapa witryny musi być generowana automatycznie z zawartości systemu treści i aktualizowana przy publikacji, nie przy budowaniu raz na tydzień. Przy dużych serwisach dzielę ją na części i pilnuję, żeby zawierała wyłącznie adresy indeksowalne — mapa z połową adresów zablokowanych to sygnał, który sam sobie zaprzecza.
Osobno sprawdzam plik z regułami dla robotów. W tej architekturze bywa on generowany dynamicznie i widziałem przypadki, w których środowisko produkcyjne odziedziczyło regułę blokującą wszystko z wersji testowej.
Trzy narzędzia i jedna zasada.
Zasada: nie oceniam tego, co widzę w przeglądarce z włączonym JavaScriptem, bo to najbardziej optymistyczny możliwy scenariusz. Sprawdzam surowy kod odpowiedzi serwera — najprościej narzędziem wiersza poleceń pobierającym dokument bez wykonywania skryptów. Jeśli treści tam nie ma, dalsze testy są tylko potwierdzaniem nadziei.
Potem test pobrania i wyrenderowania w Search Console, na kilku typach podstron, z obejrzeniem zrzutu ekranu i kodu po renderowaniu. Następnie przejście robotem indeksującym po całym serwisie, żeby wyłapać statusy odpowiedzi, łańcuchy przekierowań, powtarzające się tytuły i adresy bez linków wewnętrznych.
Na koniec rzecz, którą polecam wpisać do procesu wdrożeń: krótka lista kontrolna uruchamiana przed każdym wydaniem. Cztery pozycje wystarczą — czy treść jest w źródle, czy metadane są unikalne, czy nieistniejący adres zwraca właściwy status, czy blokada indeksowania nie została włączona przypadkiem. Zajmuje kwadrans i oszczędza tygodnie tłumaczenia spadków ruchu.
Przy przejściu na taką architekturę najwięcej ruchu traci się nie na technologii, a na zaniedbaniu dwóch rzeczy.
Pierwsza to mapa przekierowań. Kompletna lista starych adresów zestawiona z nowymi, przygotowana przed wdrożeniem, wdrożona jako przekierowania stałe po stronie serwera, bez łańcuchów. Jeśli struktura adresów się nie zmienia — a przy tego typu migracji często nie musi — to jest to najlepsza możliwa decyzja i warto o nią walczyć.
Druga to porównanie treści przed i po. W praktyce nowy szablon prawie zawsze coś gubi: fragment opisu kategorii, sekcję z pytaniami, dane strukturalne, wewnętrzne linkowanie w treści. Robię więc pełny zrzut kluczowych podstron przed migracją i po niej, i porównuję je pozycja po pozycji.
Do tego dwa nawyki na okres po wdrożeniu: obserwacja raportu indeksowania częściej niż zwykle przez pierwszy miesiąc oraz zachowanie starych logów serwera do porównania zachowania robota. To ostatnie kosztuje jedną prośbę do administratora, a bywa jedynym sposobem ustalenia, co się faktycznie zmieniło.
Używamy plików cookies, aby ułatwić Ci nawigację oraz wykonywanie określonych funkcji. Szczegółowe informacje o wszystkich plikach cookies znajdziesz w każdej kategorii zgody poniżej.
Pliki cookies oznaczone jako "Niezbędne" są przechowywane w Twojej przeglądarce, ponieważ są one kluczowe dla zapewnienia podstawowych funkcji strony.
Używamy również plików cookies firm trzecich, które pomagają nam analizować, w jaki sposób korzystasz z tej strony, zapamiętują Twoje preferencje oraz dostarczają treści i reklamy odpowiednie dla Ciebie. Te pliki cookies będą przechowywane w Twojej przeglądarce tylko za Twoją uprzednią zgodą.
Możesz zdecydować, czy chcesz włączyć lub wyłączyć niektóre bądź wszystkie te pliki cookies, jednak wyłączenie niektórych z nich może wpłynąć na Twoje doświadczenia podczas przeglądania strony.
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| __cf_bm | 13 minutes | Cloudflare bot management — distinguishes humans from bots. |
| rc::* | Persistent | Google reCAPTCHA — localStorage holding anti-bot challenge state. |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| wpEmojiSettingsSupports | Session | WordPress — sessionStorage flag caching whether the browser can render emoji (feature detection). |
| ytidb* | Persistent | YouTube — IndexedDB storing playback/search state for embedded videos. |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| _ga_* | 400 days | Google Analytics 4 — persists session state per property. |
| _ga | 400 days | Google Analytics — distinguishes unique users via a client id. |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| NID | 183 days | Google — stores preferences for personalized ads. |
| fr | 90 days | Meta — encrypted Facebook id and browser id for ads. |
| _gcl_au | 90 days | Google AdSense/Ads — experiments with advertising efficiency (conversion linker). |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| __Secure-YNID | 180 days | |
| YSC | Session | |
| __Secure-ROLLOUT_TOKEN | 180 days | |
| VISITOR_INFO1_LIVE | 180 days | |
| VISITOR_PRIVACY_METADATA | 180 days | |
| datr | 400 days | |
| sb | 400 days | |
| wd | 7 days |