Zdarza się, że wiem dokładnie, co trzeba zmienić na stronie klienta: tytuły kategorii, przekierowania po migracji, znaczniki hreflang. Nie mogę jednak tego zrobić, bo CMS na to nie pozwala, a kolejka zadań zespołu programistów sięga kilku miesięcy. W takich sytuacjach wdrażam zmiany przez middleware w CDN, czyli kod, który modyfikuje odpowiedzi serwera, zanim trafią do użytkownika i robota Google. W tym wpisie pokazuję, jak to robię w Cloudflare Workers, jakie zmiany nadają się do takiego wdrożenia i jakich zasad pilnuję, żeby nie narobić więcej szkody niż pożytku.
Kiedy sięgam po Edge SEO
Edge SEO traktuję jako rozwiązanie na sytuacje, w których poprawka w kodzie strony jest niemożliwa albo zajęłaby zbyt długo:
- stary lub zamknięty CMS, który nie pozwala edytować tytułów, opisów czy adresów kanonicznych,
- migracja, po której trzeba szybko wdrożyć tysiące przekierowań bez obciążania serwera,
- błąd, który kosztuje ruch codziennie, np. przypadkowy
noindexw szablonie, a wdrożenie poprawki w aplikacji czeka na kolejne wydanie, - test zmiany, której wpływ chcę sprawdzić, zanim zespół wdroży ją na stałe.
Jeśli zmianę można wprowadzić w CMS lub kodzie w rozsądnym czasie, robię to tam. Każda poprawka na brzegu sieci to dodatkowa warstwa logiki, o której trzeba pamiętać.
Jak wdrażam zmiany w Cloudflare Workers
Worker to krótki skrypt uruchamiany w CDN przy każdym żądaniu do wybranych adresów. Pobiera odpowiedź z serwera, a zanim przekaże ją dalej,
może ją zmienić. Do modyfikacji HTML służy wbudowany w Cloudflare HTMLRewriter, który przetwarza dokument strumieniowo, bez
wczytywania całej strony do pamięci. Przykład podmiany tytułu i dodania adresu kanonicznego na stronach kategorii:
const TITLES = {
'/kategoria/buty-damskie': 'Buty damskie – sneakersy, botki i szpilki | Sklep',
};
export default {
async fetch(request) {
const url = new URL(request.url);
const response = await fetch(request);
const type = response.headers.get('content-type') || '';
if (!type.includes('text/html')) return response;
const title = TITLES[url.pathname];
return new HTMLRewriter()
.on('title', { element(el) { if (title) el.setInnerContent(title); } })
.on('head', { element(el) {
el.append(`<link rel="canonical" href="${url.origin}${url.pathname}">`, { html: true });
}})
.transform(response);
},
};
Przekierowań nie zapisuję w kodzie workera, tylko w regułach przekierowań zbiorczych Cloudflare albo w magazynie danych, z którego worker je odczytuje. Lista tysięcy adresów jest wtedy łatwa do zmiany bez wdrażania kodu, a przekierowanie odbywa się, zanim żądanie dotrze do serwera. Mapę adresów przygotowuję tak samo jak przy każdej zmianie struktury, bo od niej zależy, czy migracja strony internetowej obędzie się bez spadków ruchu.
Zmiany, które najczęściej wdrażam na brzegu sieci
| Zmiana | Dlaczego na brzegu | Na co uważam |
|---|---|---|
| Przekierowania 301 | tysiące reguł bez obciążania serwera i pliku .htaccess | brak łańcuchów i konfliktów z przekierowaniami w CMS |
| Tytuły, opisy, adresy kanoniczne | CMS nie pozwala ich edytować | zapisanie zmian w dokumentacji, żeby nie nadpisać ich przy migracji |
| Znaczniki hreflang | wersje językowe w różnych systemach | poprawne odwołania zwrotne między wszystkimi wersjami |
| Nagłówki odpowiedzi | X-Robots-Tag, cache, nagłówki bezpieczeństwa bez dostępu do serwera | żeby nie zablokować indeksowania całych sekcji |
| Testy zmian wydajności | porównanie wersji strony na części ruchu | stałe przypisanie użytkownika do wariantu |
Testy zmian na części ruchu wykonane na brzegu sieci są lżejsze niż narzędzia działające w przeglądarce, bo użytkownik dostaje swój wariant od razu w HTML. Wyniki takich testów A/B mierzę w GA4, przekazując informację o wariancie przez warstwę danych.
Ryzyka i zasady, których pilnuję
- Te same zmiany dla robota i użytkownika. Reguły opieram na adresie, kraju czy języku, nigdy na tym, że stronę odwiedza Googlebot. Inaczej Edge SEO zamienia się w cloaking, a granicę dobrze pokazuje dynamic rendering a cloaking.
- Kod w repozytorium i dokumentacja. Zmiany na brzegu są niewidoczne dla programistów pracujących przy aplikacji. Kod workera trzymam w repozytorium, a listę zmian w dokumentacji projektu, żeby przy kolejnym wdrożeniu nikt nie szukał, skąd bierze się tytuł, którego nie ma w CMS.
- Pamięć podręczna. Zmodyfikowany HTML musi mieć poprawne nagłówki cache, bo inaczej CDN może serwować starą wersję albo przetwarzać każdą stronę przy każdym żądaniu. To jeden z punktów, które sprawdzam przy każdej konfiguracji CDN.
- Limity i awarie. Worker ma limity czasu procesora i liczby żądań. Kod piszę tak, żeby w razie błędu zwracał oryginalną odpowiedź serwera, a nie stronę błędu.
- Docelowo poprawka w kodzie. Zmiany na brzegu traktuję jako tymczasowe lub uzupełniające. Gdy tylko zespół może wdrożyć je w aplikacji, przenoszę je tam i usuwam z workera.
Jak sprawdzam, czy zmiany działają
Po wdrożeniu sprawdzam surową odpowiedź HTML poleceniem curl oraz w narzędziu do sprawdzania adresów URL w Search Console, które
pokazuje kod widziany przez Google. Przy przekierowaniach crawluję listę starych adresów w Screaming Frogu i porównuję kody odpowiedzi z mapą
przekierowań. Dopiero gdy wszystkie trzy źródła pokazują to samo, uznaję zmianę za wdrożoną.