Logo David Burdelak
SEO

Edge SEO – jak wdrożyć zmiany na stronie przez middleware CDN?

Edge SEO

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 noindex w 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

ZmianaDlaczego na brzeguNa co uważam
Przekierowania 301tysiące reguł bez obciążania serwera i pliku .htaccessbrak łańcuchów i konfliktów z przekierowaniami w CMS
Tytuły, opisy, adresy kanoniczneCMS nie pozwala ich edytowaćzapisanie zmian w dokumentacji, żeby nie nadpisać ich przy migracji
Znaczniki hreflangwersje językowe w różnych systemachpoprawne odwołania zwrotne między wszystkimi wersjami
Nagłówki odpowiedziX-Robots-Tag, cache, nagłówki bezpieczeństwa bez dostępu do serwerażeby nie zablokować indeksowania całych sekcji
Testy zmian wydajnościporównanie wersji strony na części ruchustał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ą.