Google Analytics 4 w Next.js App Router — konfiguracja z gtag i @next/third-parties
Jak poprawnie wdrożyć GA4 w Next.js App Router: gtag, @next/third-parties, page_view przy client-side navigation, consent mode v2 i custom events bez chaosu w danych.
Najważniejsze na początek jest to, że @next/third-parties to wygodne i stabilne rozwiązanie, natomiast przy bardziej restrykcyjnym consent mode, warunkowym ładowaniu skryptu albo niestandardowej logice związanej z wysyłaniem pageview, ręczny setup nadal daje nam znacznie większą kontrolę.
Zanim zaczniesz
Potrzebujesz Measurement ID z panelu GA4. Znajdziesz go w Admin → Data Streams → wybierz stream → Measurement ID. Format to G-XXXXXXXXXX.
Kilka istotnych detali w tym kodzie. send_page_view: false w konfiguracji gtag wyłącza automatyczne pageviews, zamiast tego wysyłamy je ręcznie w useEffect, reagując na zmiany pathname i searchParams. Bez tego przy client-side navigation (kliknięcie w Link) GA4 nie zarejestruje przejścia między stronami. strategy="afterInteractive" ładuje skrypt po hydratacji strony, co minimalizuje wpływ na Core Web Vitals to zestaw metryk Google oceniających realne doświadczenie użytkownika: LCP (szybkość ładowania), INP (responsywność) i CLS (stabilność wizualna). Wpływają na ranking i konwersję.. Suspense wokół komponentu jest potrzebny, bo useSearchParams wymaga granicy Suspense w App Router.
Diagram
Bezpieczna kolejność ładowania GA4 w Next.js App Router
GA4 opiera pomiar na zdarzeniach. Najpierw korzystaj ze zdarzeń zbieranych automatycznie lub przez Enhanced Measurement, a dla działań biznesowych stosuj rekomendowane nazwy, takie jak generate_lead, sign_up, add_to_cart, begin_checkout i purchase. Dzięki temu raporty są łatwiejsze do interpretacji niż przy własnej nazwie dla każdej odmiany kliknięcia.
Zdarzenie ważne dla wyniku biznesowego oznacz w GA4 jako key event. Przykładowo strona usługowa może oznaczyć generate_lead, a sklep purchase; nie oznaczaj jako key event każdej drobnej interakcji. W panelu Analytics robisz to w Admin -> Events, wskazując istniejące zdarzenie albo definiując nowe z góry.
Podejście 2: @next/third-parties
Pakiet @next/third-parties to oficjalne rozwiązanie od Vercel, które upraszcza integrację z popularnymi skryptami third-party. Warto jednak śledzić aktualną dokumentację przy większych wdrożeniach.
To wszystko — komponent automatycznie ładuje skrypt gtag i konfiguruje go z Twoim Measurement ID.
Wysyłanie eventów
Pakiet eksportuje helper sendGAEvent:
Code
'use client'import { sendGAEvent } from '@next/third-parties/google'export function SignUpButton() { return ( <button onClick={() => { sendGAEvent('event', 'sign_up', { method: 'email' }) }} > Zarejestruj się </button> )}
Ograniczenia @next/third-parties
@next/third-parties jest wygodny, ale ma swoje ograniczenia. Nie daje takiej kontroli nad momentem inicjalizacji Google tag, jak ręczny setup, co jest problematyczne, jeśli potrzebujesz bardziej rygorystycznego consent mode. Do tego łatwo dojść do momentu, w którym i tak trzeba dopisać własną logikę do warunkowego ładowania, page_view albo dodatkowych integracji.
Consent Mode — implementacja
Dla stron w UE Consent Mode to konieczność. Oto jak go zaimplementować z manualnym podejściem:
Kluczową rzeczą jest to, że najpierw musisz ustawić domyślne zgody (np. wszystko zablokowane), zanim załaduje się główny kod GA4. Dopiero potem, gdy użytkownik wyrazi zgodę, aktualizujesz te ustawienia. Robiąc to w złej kolejności, GA4 może zacząć zbierać dane, zanim użytkownik się zgodzi, co jest niezgodne z obowiązującym prawem.
Warunki ładowania skryptu
Jeśli wolisz, żeby kod GA4 w ogóle się nie ładował, dopóki użytkownik nie wyrazi zgody, możesz to zrobić tak:
Code
'use client'import Script from 'next/script'import { useEffect, useState } from 'react'export default function GoogleAnalytics() { const [hasConsent, setHasConsent] = useState(false) useEffect(() => { const consent = localStorage.getItem('analytics-consent') if (consent === 'granted') { setHasConsent(true) } // Nasłuchuj na zmiany zgody z cookie bannera const handler = () => setHasConsent(true) window.addEventListener('analytics-consent-granted', handler) return () => window.removeEventListener('analytics-consent-granted', handler) }, []) if (!hasConsent) return null return ( <> <Script src={`https://www.googletagmanager.com/gtag/js?id=${process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID}`} strategy="afterInteractive" /> {/* ... config script */} </> )}
Testowanie i debugowanie
DebugView
Włącz specjalny tryb debug, dodając parametr w konfiguracji:
Po włączeniu powyższego trybu, wszystkie zdarzenia, które wysyłasz, pojawią się w czasie rzeczywistym w sekcji "DebugView" w panelu GA4.
Sprawdzanie w DevTools
Otwórz narzędzia deweloperskie (zazwyczaj F12), przejdź do zakładki "Network" i wpisz "collect" w polu wyszukiwania - zobaczysz tam wszystkie zapytania wysyłane do serwerów Google Analytics. Właśnie w ten sposób, szybko możemy sprawdzić, czy zdarzenia w ogóle są wysyłane.
Tag Assistant
Google Tag Assistant (rozszerzenie Chrome albo wersja webowa na tagassistant.google.com) pozwala podejrzeć, jakie eventy są wysyłane i czy konfiguracja jest poprawna.
Typowe błędy
Brak pageviews przy client-side navigation to najczęstszy problem. Dzieje się tak ponieważ Next.js przy nawigacji przez <Link> nie ładuje strony od nowa, więc gtag nie wysyła automatycznie pageview. Rozwiązaniem jest ręczne wysyłanie page_view w useEffect reagującym na zmiany pathname.
Podwójne pageviews — jeśli masz ustawione send_page_view: true (domyślne) i jednocześnie wysyłasz ręcznie pageviews w useEffect, dostajesz duplikaty. By to naprawić, ustaw w konfiguracji send_page_view: false.
Brak danych w development — wtyczki blokujące reklamy i rozszerzenia prywatności blokują requesty do google-analytics.com. W trakcie developmentu testuj w oknie incognito z wyłączonymi rozszerzeniami albo korzystaj z DebugView.
Zmienne środowiskowe undefined — zapomniane NEXT_PUBLIC_ prefiks lub brak .env.local w katalogu projektu. Pamiętaj, że po dodaniu zmiennej musisz zrestartować serwer deweloperski.
Które podejście wybrać?
Wybór @next/third-parties ma większy sens, jeśli chcesz szybko dodać GA4 bez szerokiej customizacji, a Twoja strona nie wymaga złożonego warunkowego ładowania skryptu.
Podejście manualne z gtag sprawdzi się lepiej, gdy potrzebujesz pełnej kontroli nad Consent Mode (strony w UE, więc też PL), chcesz warunkowo ładować skrypt na podstawie zgody użytkownika, potrzebujesz niestandardowej logiki śledzenia pageviews lub integrujesz GA4 z innymi narzędziami (np. Google Tag Manager).
Dla większości polskich projektów — gdzie RODO wymaga Consent Mode — manualne podejście daje więcej kontroli i jest bezpieczniejszym wyborem - właśnie to rekomenduje.
Często zadawane pytania
O autorze
Maciej Sala
Maciej Sala — Product Manager i Frontend Developer z bogatym doświadczeniem w marketingu internetowym oraz SEO. Na co dzień pracuje z Reactem, Next.js i TypeScriptem, a ostatnio także z Astro i narzędziami do automatyzacji procesów AI. Sprawnie łączy perspektywę produktową z praktycznym podejściem do kodu. Przez kilka lat był związany z branżą gier wideo jako project manager i game designer. Absolwent historii na Uniwersytecie Jagiellońskim oraz studiów podyplomowych z marketingu internetowego na AGH w Krakowie. Po godzinach trenuje na siłowni, maluje figurki i rozwija własne projekty side-projecty.
Remarketing Google Ads w React i Next.js bez marketingowych uproszczeń: eventy, Merchant Center, listy odbiorców w GA4, Customer Match i wymogi consent.