DataLayer w PrestaShop to nie plugin do kliknięcia w panelu — to kilkanaście linii kodu wpiętych w konkretne hooki i kontrolery. Bez niego GA4 pokaże Ci ruch i źródła wejść, ale nie pokaże, co ludzie dodają do koszyka, na którym kroku rezygnują i za co faktycznie płacą. Poniżej masz część organizacyjną: kolejność prac, typowe błędy i listę kontrolną przed uznaniem wdrożenia za skończone. Warstwę techniczną (hooki, kontrolery, przykładowy kod) opisujemy w pozostałych sekcjach artykułu. Jeśli wdrożenie ma iść równolegle z innymi integracjami, zobacz też, jak u nas wygląda organizacja integracji z PrestaShop.
DataLayer to zwykła tablica JavaScript. Deklaracja wygląda tak: window.dataLayer = window.dataLayer || []; — i tyle. Sklep dopisuje do niej obiekty przez dataLayer.push({...}): co się stało, na jakim produkcie, za ile. Sama tablica nic nie wysyła i nie wie nic o Google Analytics 4. To magazyn danych w przeglądarce, z którego Google Tag Manager czyta i decyduje, dokąd co przekazać.
W praktyce masz trzy sposoby mierzenia e-commerce i warto znać różnicę:
Po czym poznać, że sklep nie ma warstwy danych? Wejdź w GA4 → Raporty → Monetyzacja → Wyświetlenia produktów i sprawdź kolumny item_id oraz item_name. Jeśli widzisz „(not set)” — dane nie są wysyłane. Typowe objawy braku DataLayer:
Zasada, którą warto powtarzać zespołowi: PrestaShop nie wie o GA4, GA4 nie wie o PrestaShop. GTM jest tłumaczem pomiędzy nimi. Dzięki temu DataLayer wdrażasz raz i podłączasz kolejne narzędzia bez dotykania sklepu. Jeśli robisz to równolegle z modułami płatności czy feedami, zobacz, jak u nas wygląda organizacja integracji z PrestaShop, żeby nie wdrażać dwóch rzeczy w tym samym pliku w tym samym tygodniu.
| Sposób | Gdzie mieszka logika | Zmiana narzędzia analitycznego | Ryzyko przy aktualizacji motywu |
|---|---|---|---|
| dataLayer.push() | Kod sklepu + GTM | Nowy tag w GTM, zero zmian w sklepie | Średnie — trzeba zachować własny szablon |
| gtag('event') | Kod sklepu + konto Google | Drugie narzędzie = kolejny kod w motywie | Wysokie — snippet w szablonie |
| Hardkodowane piksele | Tylko motyw | Edycja każdego snippetu osobno | Bardzo wysokie — praca ginie przy podmianie motywu |
Zdarzeń e-commerce w GA4 jest dziesięć. Nie wdrażaj wszystkich naraz. W 90% sklepów MŚP wystarczy minimum: view_item, add_to_cart, begin_checkout, purchase. To one odpowiadają na pytania „co oglądają”, „co wkładają do koszyka”, „gdzie odpadają” i „za co faktycznie płacą”. Resztę dokładasz w drugiej iteracji, po 2–4 tygodniach zbierania danych.
Każde zdarzenie produktowe musi nieść tablicę items. Parametry przedmiotu: item_id, item_name, price, quantity, item_brand, item_category, item_variant. Parametry zdarzenia: currency, value, transaction_id, tax, shipping, coupon. currency ustaw na PLN, a value licz konsekwentnie — jeśli w GA4 raportujesz przychód bez dostawy, to samo rób w Merchant Center. Rozjazd w definicji kwoty między narzędziami to najczęstszy powód, dla którego raporty „się nie zgadzają”.
Największa pułapka: item_id wypełniony id_product zamiast reference (SKU). Wewnętrzne ID zmienia się przy pełnym imporcie katalogu, jest inne w każdym sklepie i nie łączy się z feedem produktowym. Efekt: po dwóch kwartałach nikt nie potrafi zestawić sprzedaży z GA4 z danymi w Merchant Center, a zmiana kodu produktu w PrestaShop rozwala całą historię. Ustaw item_id = reference, a przy produktach z wariantami — reference kombinacji, i nazwę atrybutu (rozmiar, kolor) wrzuć w item_variant.
Druga pułapka dotyczy płatności. add_payment_info i purchase przy wracaniu z bramki potrafią odpalić się dwa razy albo wcale. Przy wdrożeniach z PayPalem i przelewami sposób, w jaki ułożysz moduł płatności w PrestaShop, bezpośrednio wpływa na to, czy transakcja trafi do GA4 z poprawnym transaction_id. Transakcje deduplikuj zawsze po transaction_id, nigdy po kwocie i dacie.
| Zdarzenie | Kiedy wysyłać | Priorytet |
|---|---|---|
| view_item | wyświetlenie karty produktu | 1 — minimum |
| add_to_cart | dodanie do koszyka, także przez AJAX | 1 — minimum |
| begin_checkout | wejście na pierwszy krok zamówienia | 1 — minimum |
| purchase | strona potwierdzenia zamówienia | 1 — minimum |
| view_item_list | lista kategorii, wyniki wyszukiwania | 2 — druga iteracja |
| view_cart | wejście na koszyk | 2 — druga iteracja |
| remove_from_cart | usunięcie pozycji z koszyka | 3 — jeśli czas pozwala |
| add_shipping_info | wybór metody dostawy | 3 — jeśli czas pozwala |
| add_payment_info | wybór metody płatności | 3 — jeśli czas pozwala |
| refund | zwrot, najczęściej przez API lub z panelu | 3 — jeśli czas pozwala |
Wdrożenie w PrestaShop to zwykle 6–10 plików i 4–6 hooków. Zaczynasz od kontenera globalnego. W PS 1.7 i 8.x najwygodniej wpiąć go w hook displayHeader — bezpośrednio w themes/[motyw]/templates/layouts/layout.tpl albo przez własny moduł zarejestrowany na ten hook. Tam ustawiasz window.dataLayer = window.dataLayer || []; i wrzucasz dane kontekstowe: typ strony, id_shop, id_lang, status zalogowania. Jeśli chcesz mniej blokować render, ten sam kontener możesz wypisać na displayBeforeBodyClosingTag.
Dalej mapujesz zdarzenia na miejsca, gdzie dane już istnieją po stronie PHP:
$product (reference, nazwa, cena, kategoria, atrybuty), szablon templates/catalog/product.tpl, uzupełniająco hook displayProductAdditionalInfo przy AJAX-owych zakładkach.$cart, hook displayShoppingCart.$order, hook displayOrderConfirmation w templates/checkout/order-confirmation.tpl.Smarty (starsze motywy) i Twig (1.7+/8.x) różnią się składnią, nie logiką: Smarty to {assign var=x value=$y} i {$x}, Twig to {% set x = y %} i {{ x }}. W obu przypadkach dane przygotuj w PHP i przypisz przez $this->context->smarty->assign(). Trzymanie obliczeń ceny w kontrolerze jest łatwiejsze do przetestowania niż wyliczanie ich w szablonie.
Dwie rzeczy psują wdrożenie najczęściej. Pierwsza: purchase odpalany przy każdym odświeżeniu strony potwierdzenia — F5 i masz drugą transakcję. Rozwiązanie: hook actionOrderConfirmation zapisuje znacznik, że zdarzenie już wysłano, a skrypt w szablonie sprawdza ten znacznik przed pushem. Druga: multishop. Jeśli prowadzisz dwa sklepy w jednej instalacji, do każdego pusha dodaj id_shop i id_lang, a w GTM rozdziel je zmienną i osobnym tagiem. Inaczej ruch z obu sklepów wpadnie do jednego strumienia GA4 i raporty przestaną mieć sens. Najprościej: osobny kontener GTM na każdą domenę.
Listę hooków i kontrolerów dla swojej wersji sprawdź w PrestaShop Developer Documentation — część z nich różni się między 1.7 a 8.x. Stronę organizacyjną (kto, co i w jakiej kolejności) opisujemy w materiale o organizacji wdrożenia sklepu PrestaShop krok po kroku.
| Hook lub plik | Zdarzenia | Skąd dane |
|---|---|---|
| displayHeader (templates/layouts/layout.tpl) | kontener dataLayer, dane kontekstowe | Context: id_shop, id_lang, typ strony |
| displayBeforeBodyClosingTag | kontener alternatywny (koniec body) | Context |
| displayProductAdditionalInfo (templates/catalog/product.tpl) | view_item, add_to_cart z AJAX | $product z ProductController |
| displayShoppingCart | view_cart, remove_from_cart, add_to_cart | $cart z CartController |
| displayOrderConfirmation + actionOrderConfirmation (templates/checkout/order-confirmation.tpl) | purchase, deduplikacja transakcji | $order z OrderConfirmationController |
Cel na dziś: w GTM Preview masz zobaczyć dwa zdarzenia — view_item na karcie produktu i add_to_cart po dodaniu do koszyka. Reszta ścieżki to ten sam schemat.
Krok 1. Kontener i tag bazowy. Kontener typu Web, tag Google (GA4) z identyfikatorem pomiaru w formacie G-XXXXXXXXXX i wyzwalaczem Initialization – All Pages. Jeśli planujesz Consent Mode v2, ten sam tag ustaw na Consent Initialization. W Preview sprawdź, że tag odpala się dokładnie raz na odsłonę — dwa razy oznacza podwójne zdarzenia i zawyżone raporty.
Krok 2. Wstawienie kontenera. Snippet wklejasz w themes/twoj-motyw/templates/_partials/head.tpl albo — bezpieczniej — przez hook displayHeader w prostym module. Po aktualizacji motywu edycja pliku przepada; moduł albo child theme ten problem rozwiązuje. Listę hooków i zasadę działania modułów opisuje dokumentacja dla deweloperów PrestaShop: devdocs.prestashop-project.org.
Krok 3. Dane produktu. W templates/catalog/product.tpl masz kontekst $product i $currency. Minimalny blok wygląda tak:
{if $page.page_name == 'product'}
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'view_item',
ecommerce: {
currency: '{$currency.iso_code}',
value: {$product.price_amount|floatval},
items: [{
item_id: '{$product.reference}',
item_name: '{$product.name|escape:'javascript'}',
item_category: '{$product.category_name|default:'brak'}',
price: {$product.price_amount|floatval},
quantity: 1
}]
}
});
</script>
{/if}Kluczowa decyzja: cena. $product.price_amount to kwota w kontekście klienta — z VAT i z rabatem jego grupy, a nie surowa wartość z tabeli ps_product. Jeśli sklep pokazuje netto dla B2B, do dataLayer też idzie netto, bo inaczej GA4 pokaże przychód, którego nie ma w księgowości. Walutę zawsze bierz z $currency->iso_code.
add_to_cart. Domyślny motyw PrestaShop przeładowuje stronę po dodaniu do koszyka, więc zdarzenie łapiesz po odpowiedzi AJAX. Motyw emituje zdarzenie updateCart: prestashop.on('updateCart', function(params){ ... }) — nazwę potwierdź w theme.js swojego motywu, bo modyfikacje potrafią ją zmienić. W params.reason sprawdzasz, czy akcja to dodanie do koszyka, i dopiero wtedy pushujesz add_to_cart. Jeśli motyw i tak przeładowuje stronę, potrzebujesz flagi w sessionStorage, inaczej zdarzenie przepadnie albo zapisze się dwa razy.
Tu wykłada się większość wdrożeń. Trzy problemy: skąd wziąć dane, jak nie policzyć zamówienia dwa razy i jak rozbić kwoty.
Skąd dane. Koszyk jest już pusty, więc dane pobierasz z obiektu $order — w kontrolerze OrderConfirmationController lub przez hook displayOrderConfirmation. $order->getProducts() daje pozycje z ceną jednostkową i ilością, $order->total_paid — kwotę faktycznie zapłaconą przez klienta, $order->total_shipping_tax_incl — koszt dostawy.
transaction_id. Zawsze $order->id. Bez tego GA4 zliczy zamówienie przy każdym odświeżeniu strony potwierdzenia, a przychód w raportach rozjedzie się z rzeczywistością w kilka dni.
Ochrona przed duplikatem. Po pushu zapisz flagę sessionStorage.setItem('dd_purchase_' + transaction_id, '1') i przy wejściu sprawdź, czy już istnieje. Pamiętaj, że sessionStorage działa per karta — klient otwierający potwierdzenie w drugiej karcie wygeneruje drugie zdarzenie. GA4 odrzuca duplikaty po tym samym transaction_id, ale to druga linia obrony, nie jedyna.
| Pole w dataLayer | Skąd wziąć | Co zawiera |
|---|---|---|
| transaction_id | $order->id | unikalny numer zamówienia |
| value | $order->total_paid | kwota brutto zapłacona przez klienta, z dostawą i VAT |
| tax | total_paid_tax_incl − total_paid_tax_excl | suma VAT w zamówieniu |
| shipping | $order->total_shipping_tax_incl | koszt dostawy brutto |
| items[].price | cena jednostkowa brutto po rabacie | nie cena katalogowa z karty produktu |
| currency | $currency->iso_code | waluta, w której rozliczono zamówienie |
Kolejność zdarzeń. Najpierw consent default z odmową, potem snippet GTM, potem zdarzenia e-commerce, a na końcu consent update po kliknięciu akceptacji. Blok startowy wklejasz przed kontenerem:
window.dataLayer = window.dataLayer || [];
function gtag(){ dataLayer.push(arguments); }
gtag('consent', 'default', {
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
analytics_storage: 'denied',
wait_for_update: 500
});Ta czwórka to pełny Consent Mode v2. ad_storage i ad_user_data dotyczą tagów reklamowych, ad_personalization — remarketingu i list odbiorców, analytics_storage — GA4. Parametr wait_for_update: 500 daje CMP pół sekundy na odpowiedź, zanim tagi wystartują z odmową.
Integracja z CMP. Cookiebot, CookieYes i Cookie Information mają wbudowane wsparcie Consent Mode — w panelu włączasz integrację, a CMP sam wysyła consent update po akceptacji. Pułapka siedzi w mapowaniu kategorii: jeśli w CMP „statystyka” jest wyłączona, a GA4 ma działać dopiero po zgodzie, musisz powiązać ją z analytics_storage. Inaczej klient zaakceptuje wszystko, a dane nie popłyną. Weryfikacja: zakładka Consent w GTM Preview plus DebugView w GA4.
Czego nie wrzucać do dataLayer. E-mail, telefon, pełne imię i nazwisko, numer zamówienia z danymi klienta. dataLayer jest widoczny w Preview, w DebugView i w źródle strony — to nie miejsce na dane osobowe. Jeśli używasz Enhanced Conversions, trafiają do Google wyłącznie w formie zhashowanej (SHA-256), a hashowanie robisz po stronie serwera, nigdy w JavaScript prosto z formularza.
Nie publikuj kontenera, dopóki nie przejdziesz trzech niezależnych sprawdzeń. Pierwsze: GTM → Preview. Otwórz sklep w nowej karcie, wykonaj akcję (wejście na kartę produktu, dodanie do koszyka, wejście w checkout) i w panelu Preview kliknij zdarzenie. Zakładka z warstwą danych pokaże dokładnie, co poszło w pushu — sprawdź, czy obiekt ecommerce.items zawiera item_id, item_name, price i quantity, a nie puste stringi. Testuj w trybie incognito i na wyczyszczonym koszyku, żeby nie łapać zdarzeń z poprzedniej sesji.
Drugie: GA4 → Administracja → DebugView. Wymaga aktywnego podglądu GTM albo parametru debug_mode w tagu konfiguracyjnym. Zdarzenia pojawiają się w kilka sekund, z parametrami rozbitymi na ep.* (parametry zdarzenia) i pr.* (parametry produktu). Raport czasu rzeczywistego traktuj jako trzecią, zgrubną weryfikację — potwierdzi, że zdarzenie dotarło, ale nie pokaże wartości parametrów.
Trzecie: DevTools → Console. Wpisz window.dataLayer i rozwiń ostatni wpis albo console.table(window.dataLayer). Następnie zakładka Network: filtruj po collect, wejdź w request do GA4 i porównaj en=purchase oraz parametry ep.* z tym, co wysłał DataLayer. Jeśli w konsoli jest poprawny push, a w Network nie ma hita — problem leży w tagu GTM, nie w kodzie sklepu.
Na koniec zamówienie testowe w trybie sandbox bramki płatniczej, z pełnym przejściem przez checkout. Porównaj transaction_id z numerem zamówienia w PrestaShop i sprawdź, czy purchase poszedł dokładnie raz. Sposób konfiguracji samej bramki opisujemy osobno w materiale o module PayPal w PrestaShop i organizacji wdrożenia płatności.
| Narzędzie | Gdzie | Co potwierdzasz |
|---|---|---|
| GTM Preview | Tag Assistant w GTM | Nazwę zdarzenia i zawartość pusha przed publikacją kontenera |
| GA4 DebugView | Administracja → DebugView | Że zdarzenie dotarło z parametrami ep.* i pr.* |
| Raport czasu rzeczywistego | GA4 → Raporty → Czas rzeczywisty | Że ruch i zdarzenia w ogóle lecą z tego strumienia |
| DevTools Console | window.dataLayer | Ostatni push — czy obiekt jest kompletny |
| DevTools Network | filtr: collect | Że hit GA4 wychodzi z oczekiwanymi parametrami |
Poniższe siedem problemów odpowiada za większość rozjazdów między raportami GA4 a panelem PrestaShop. Każdy ma charakterystyczny objaw — zanim zaczniesz grzebać w kodzie, sprawdź, czy Twój sklep go nie ma.
| Błąd | Objaw | Jak wykryć |
|---|---|---|
| Duplikat purchase po odświeżeniu strony potwierdzenia | Liczba transakcji wyższa o 10–30% niż liczba zamówień | Porównaj oba liczniki za ten sam dzień; w DebugView odśwież stronę potwierdzenia — drugi purchase oznacza brak blokady (sessionStorage lub flaga w bazie) |
| Brak view_item po włączeniu CCC (Combine, Compress, Cache) | Zdarzenia są na części stron albo znikają po włączeniu optymalizacji | Wyłącz CCC w Parametry zaawansowane → Wydajność, wyczyść cache, przetestuj ponownie; szukaj inline JS w plikach .tpl |
| item_id „not set” | Raporty produktów w GA4 są puste, brak przypisania do ID | GTM Preview → zmienna z ecommerce.items; sprawdź, czy kontroler produktu przekazuje referencję do szablonu |
| Znikające zdarzenia po aktualizacji motywu lub modułu | Wdrożenie działało, po deployu przestało | Porównaj pliki .tpl z kopią lub repozytorium; nowa wersja motywu nadpisuje szablony bez ostrzeżenia |
| Mieszanie danych z wielu sklepów w jednym strumieniu GA4 | Raporty pokazują sumę, nie da się rozdzielić sklepów | Sprawdź, czy każdy sklep w multishopie ma osobny identyfikator strumienia lub kontenera |
| Zdarzenia wysyłane przed zgodą | Ryzyko RODO i zawyżone, nierealistyczne dane | W Network sprawdź, czy hit collect wychodzi przed kliknięciem zgody w banerze |
| Zamówienia z wartością 0 lub bez shipping | Zaniżona średnia wartość zamówienia, przychód nie zgadza się z panelem | W DebugView sprawdź value i koszt dostawy przy purchase — osobno dla zamówienia z darmową i płatną wysyłką |
Nazwy hooków i kontrolerów, w których te dane powinny być budowane, znajdziesz w dokumentacji PrestaShop dla deweloperów. Zanim zgłosisz błąd jako „losowy”, zapisz wersję motywu i listę aktywnych modułów — to najczęstsza przyczyna nagłych zmian w danych.
Poniższą listę przechodź zawsze w tej kolejności: najpierw zdarzenia produktowe, potem koszyk i checkout, na końcu purchase. Kontener publikuj dopiero, gdy wszystkie punkty z kolumny „przed publikacją” są odklikane na środowisku testowym.
| Element | Przed publikacją kontenera | Po starcie |
|---|---|---|
| view_item | Poprawny item_id, cena i nazwa na 3 losowych produktach | Raz w tygodniu sprawdź raport produktów w GA4 |
| add_to_cart | Zdarzenie z karty produktu i z listingu | Porównaj z liczbą dodanych pozycji w PrestaShop |
| begin_checkout | Odpala się raz, przy pierwszym wejściu w checkout | Sprawdź lejek w GA4 po każdej zmianie modułu zamówienia |
| purchase | transaction_id zgodny z ID zamówienia, brak duplikatów | Porównaj przychód GA4 z panelem co miesiąc |
| Zgoda użytkownika | Brak hitów przed akceptacją banera | Test po każdej zmianie CMP |
| Multishop | Osobny strumień lub kontener dla każdego sklepu | Sprawdź rozdzielenie danych w raportach |
GTM Server-Side rozważ, gdy masz duży wolumen zdarzeń, własną domenę do pomiaru i potrzebę kontroli nad danymi po stronie serwera. Dla sklepu MŚP z kilkoma tysiącami sesji miesięcznie to zwykle przerost formy — dochodzi koszt hostingu, utrzymania kontenera serwerowego i osobnej konfiguracji.
Planuj utrzymanie: warstwę danych testuj po każdej aktualizacji PrestaShop i motywu, tak samo jak po dodaniu modułu zmieniającego koszyk. To wpisuje się w szerszy temat, który rozwijamy w materiale o integracjach z PrestaShop i organizacji wdrożenia.
Jeśli nie chcesz samodzielnie wchodzić w hooki i szablony Smarty, wdrożenie DataLayer zajmuje nam zwykle 6–12 h w zależności od liczby zdarzeń i liczby sklepów w multishopie. Napisz, ile zdarzeń chcesz mierzyć — wycenimy konkretnie.
item_id wysyłany z id_product (wewnętrzne ID bazy) zamiast reference (SKU).
Jak wykryć: W GA4 DebugView i w raportach e-commerce item_id to krótkie liczby, które nie zgadzają się z identyfikatorami produktów w Merchant Center ani w feedzie.
Jak naprawić: Użyj $product->reference jako item_id, a id_product zostaw jako dodatkowy parametr własny. Jeśli reference jest pusty w części katalogu — najpierw uzupełnij dane produktów, potem wdrażaj zdarzenia.
Brak deduplikacji zdarzenia purchase przy odświeżeniu strony potwierdzenia zamówienia.
Jak wykryć: Liczba transakcji w GA4 jest wyższa niż liczba zamówień w PrestaShop lub w panelu operatora płatności. Widać duplikaty z tym samym transaction_id.
Jak naprawić: Wysyłaj purchase raz na zamówienie: sprawdzaj po stronie serwera, czy zdarzenie dla danego id_order już zostało wypchnięte, i dopiero wtedy renderuj skrypt. transaction_id musi być identyfikowalny i niezmienny.
Zdarzenia e-commerce wpadają do dataLayer przed załadowaniem kontenera GTM.
Jak wykryć: W podglądzie GTM zdarzenia pojawiają się, ale bez parametrów lub nie są widoczne wcale. Kolejność skryptów w kodzie strony jest odwrotna, niż być powinna.
Jak naprawić: Kontener GTM wstawiaj w displayHeader, a zdarzenia zależne od kontekstu strony wypychaj po nim albo w displayBeforeBodyClosingTag. Sprawdź kolejność w źródle strony, nie tylko w podglądzie GTM.
add_to_cart działa tylko przy przeładowaniu strony, a nie przy dodawaniu produktu przez AJAX.
Jak wykryć: Dodaj produkt do koszyka z poziomu listy kategorii i sprawdź GA4 DebugView — zdarzenia nie ma, mimo że produkt trafił do koszyka. Przy dodaniu z karty produktu (pełne przeładowanie) zdarzenie się pojawia.
Jak naprawić: Nasłuchuj odpowiedzi koszyka po stronie frontu i wypchnij dataLayer.push dopiero po potwierdzeniu, że produkt znalazł się w koszyku. Dodaj flagę jednorazowego wysłania, żeby nie łapać tego samego zdarzenia dwa razy.
Brak waluty w formacie ISO albo value wysyłane jako sformatowany tekst ze spacjami i przecinkiem.
Jak wykryć: W raportach GA4 wartości zamówień są zerowe lub mocno zaniżone, a kursy walut się mieszają. W DebugView parametr currency przyjmuje wartość typu zł lub PLN ze spacją.
Jak naprawić: Zawsze wysyłaj currency jako trzyliterowy kod ISO, np. PLN, oraz value jako liczbę z kropką dziesiętną, bez separatora tysięcy i bez symbolu waluty.
Kod dataLayer wpisany bezpośrednio w pliki motywu bez child theme ani własnego modułu.
Jak wykryć: Po aktualizacji motywu albo po podmianie szablonu zdarzenia znikają z GA4, choć nikt nie zmieniał kontenera GTM.
Jak naprawić: Trzymaj kod w osobnym module albo w child theme i wersjonuj zmiany w repozytorium. Przy aktualizacji motywu sprawdź po wdrożeniu, czy wszystkie zdarzenia nadal się wysyłają.
DataLayer w PrestaShop to warstwa danych, którą wdraża się raz i utrzymuje niezależnie od zmian w motywie czy narzędziach analitycznych. Zacznij od czterech zdarzeń: view_item, add_to_cart, begin_checkout i purchase — z poprawnym item_id, walutą ISO i transaction_id. Najczęstsze problemy to duplikaty transakcji, add_to_cart działający tylko przy przeładowaniu strony oraz kod znikający razem z aktualizacją motywu. Pilnuj kolejności skryptów i kontekstu sklepu w multishopie, a raporty po dwóch tygodniach będą się zgadzać z zamówieniami.
Technicznie da się to zrobić edycją plików motywu, ale przy najbliższej aktualizacji motywu kod zniknie. Bezpieczniej jest przygotować mały własny moduł albo child theme i tam trzymać całą logikę wypychania danych. Hooki i kontrolery opisuje dokumentacja dla deweloperów PrestaShop: devdocs.prestashop-project.org.
Minimalny zakres — view_item, add_to_cart, begin_checkout i purchase — to zwykle kilka dni pracy: przygotowanie danych produktu, kod zdarzeń, testy i poprawki. Pełny zestaw zdarzeń e-commerce z refundami i dodatkowymi parametrami to zwykle drugie tyle. Najwięcej czasu schodzi nie na kod, tylko na testy i porządkowanie danych produktowych.
Nie. W większości sklepów MŚP sensowny start to view_item, add_to_cart, begin_checkout i purchase. Reszta — view_item_list, view_cart, add_shipping_info, add_payment_info, refund — dokładana jest w drugiej iteracji, gdy pierwsze cztery są stabilne i zweryfikowane. Lepiej mieć cztery rzetelne zdarzenia niż dziesięć, w których połowa parametrów jest pusta.
GTM nadal mierzy odsłony i kliknięcia, ale zdarzenia e-commerce musisz wtedy wyciągać ze struktury strony, co jest kruche — każda zmiana szablonu może je zepsuć. W praktyce raporty sprzedaży w GA4 pokazują wtedy niepełne dane: brak item_id, brak wartości koszyka i brak rozbicia na produkty. DataLayer odwraca ten problem: sklep raz podaje dane w ustalonym formacie, a GTM tylko je czyta.
Sam dataLayer to tablica w przeglądarce i nie wysyła danych na zewnątrz. Dopiero tagi w GTM — w tym GA4 i narzędzia reklamowe — przekazują je dalej i to one podlegają zgodom. Dlatego kontener warto uruchamiać w trybie Consent Mode i przetestować, jak zachowują się zdarzenia po odrzuceniu zgody. Zakres wymaganych zgód skonsultuj z osobą odpowiedzialną za zgodność w Twojej firmie — to nie jest kwestia techniczna.
Mechanika jest podobna — Smarty, hooki, kontrolery — więc technicznie jest to możliwe. Pamiętaj jednak, że PrestaShop 1.6 nie jest już rozwijany, więc wsparcie dla nowych rozwiązań i pluginów będzie z czasem coraz trudniejsze. W nowszych wersjach (1.7 i 8.x) szablony Twig są czytelniejsze i łatwiej utrzymać kod zdarzeń.
Porównaj liczbę transakcji w GA4 z liczbą zamówień w PrestaShop za ten sam okres — różnica powinna mieścić się w granicach błędu pomiaru. Sprawdź, czy w raportach Monetization widać konkretne produkty, a nie pusty wiersz. Jeśli dane się rozjeżdżają, najpierw sprawdź deduplikację purchase i kompletność transaction_id, dopiero potem szukaj winy w GTM.
Jeśli chcesz mieć pewność, że dane z Twojego sklepu są kompletne, zanim podejmiesz decyzje na ich podstawie, napisz do nas — przejrzymy wdrożenie i wskażemy, co poprawić. Możemy też zająć się całością: od kontenera GTM po zdarzenia e-commerce.