Google Analytics 4 w Next.js App Router — konfiguracja z gtag i @next/third-parties
GA4 w Next.js App Router bez dziurawej atrybucji — gtag, consent mode v2 i zdarzenia przy client-side navigation. Jak to zrobić poprawnie raz.
Maciej Sala
Founder StriveLab
6 min czytaniaOpublikowano 18 października 2025 (Aktualizacja 26 maja 2026)
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 konfigurację GA4 w Next.js
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 . 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: GA4 przez @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 przez @next/third-parties
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 w GA4: implementacja w Next.js
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 GA4
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 GA4 w Next.js
DebugView w Google Analytics 4
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 GA4 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 dla GA4
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 konfiguracji GA4 w Next.js
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.
gtag.js czy @next/third-parties: 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. Kiedy pojawia się potrzeba remarketingu, wielu tagów i niezależności marketingu od deployów, następnym krokiem jest GTM — jak go wdrożyć poprawnie w App Router opisuję w artykule o Google Tag Manager w Next.js.
Kampanie, landing page, tracking konwersji, GA4 i GTM w jednym procesie.
Wystarczy w prostych wdrożeniach, ale przy Consent Mode, niestandardowych eventach i pełnej kontroli page_view często lepszy jest ręczny setup gtag lub warstwa GTM.
Dlaczego page_view w Next.js trzeba obsłużyć ostrożnie?
App Router używa nawigacji client-side, więc samo załadowanie skryptu nie wystarcza do poprawnego pomiaru kolejnych przejść między podstronami.
Kiedy zamiast gtag wybrać Google Tag Manager?
GTM ma sens, gdy marketing potrzebuje samodzielnie zarządzać tagami, triggerami i narzędziami bez deployu aplikacji przy każdej zmianie.
Dlaczego GA4 nie rejestruje przejść między stronami w Next.js?
Next.js używa client-side navigation — przy kliknięciu w <Link> strona nie jest przeładowywana, więc gtag nie wysyła automatycznie pageview. Rozwiązaniem jest ustawienie send_page_view: false w konfiguracji gtag i ręczne wysyłanie eventu page_view w useEffect, który reaguje na zmiany pathname i searchParams z hooków next/navigation.
Czy `@next/third-parties` jest gotowe do użycia produkcyjnego?
Pakiet działa stabilnie i jest oficjalnie rozwijany przez Vercel. Do prostego wdrożenia GA4 bez specjalnych wymagań może być wystarczający, ale jeśli potrzebujesz precyzyjnej kontroli nad Consent Mode, warunkowego ładowania skryptu na podstawie zgody lub niestandardowej logiki pageviews, lepiej wybrać manualne podejście z gtag.
Jak poprawnie wdrożyć Consent Mode v2 w Next.js?
Consent Mode wymaga ustawienia domyślnych wartości (denied) przed załadowaniem skryptu gtag. W Next.js oznacza to użycie strategy="beforeInteractive" dla skryptu z domyślnymi zgodami i strategy="afterInteractive" dla samego gtag. Po wyrażeniu zgody przez użytkownika wywołujesz gtag('consent', 'update', {...}) z wartościami granted. Kolejność ładowania jest krytyczna — odwrócenie jej powoduje zbieranie danych przed wyrażeniem zgody.
Gdzie znajdę Measurement ID dla GA4?
Measurement ID znajdziesz w panelu Google Analytics w sekcji Admin → Data Streams → kliknij na wybrany stream → Measurement ID. Format to G-XXXXXXXXXX, wklej to ID do zmiennej środowiskowej NEXT_PUBLIC_GA_MEASUREMENT_ID w pliku .env.local — prefiks NEXT_PUBLIC_ jest obowiązkowy, bez niego zmienna nie będzie dostępna w kodzie klienckim.
Dlaczego widzę zduplikowane pageviews w GA4?
Duplikaty pageviews wynikają najczęściej z jednoczesnego aktywnego ustawienia send_page_view: true (domyślne) w konfiguracji gtag i ręcznego wysyłania pageview w useEffect. Rozwiązaniem jest ustawienie send_page_view: false w konfiguracji gtag, żeby wyłączyć automatyczne pageviews i polegać wyłącznie na ręcznym wysyłaniu.
Czy GA4 działa poprawnie w React Server Components?
Tak, ale sam tag GA4 i każde odwołanie do window, document albo gtag() musi żyć po stronie klienta. Server Components mogą bez problemu renderować HTML strony, natomiast tracking osadzasz w Client Componentach lub helperach wywoływanych z klienta.
Jak testować GA4 w środowisku lokalnym?
Włącz tryb debugowania w konfiguracji GA4 (debug_mode: true), a zdarzenia pojawią się w "DebugView" w panelu GA4. Alternatywnie sprawdź zakładkę Network w DevTools i filtruj po „collect", a zobaczysz requesty do google-analytics.com/g/collect. Pamiętaj, że wtyczki blokujące reklamy mogą to utrudniać, więc testuj w trybie incognito z wyłączonymi rozszerzeniami.
Czy warto używać GA4 z GTM zamiast bezpośredniej integracji?
To zależy od potrzeb, ponieważ bezpośrednia integracja gtag jest prostsza i daje pełną kontrolę deweloperowi. GTM warto rozważyć, gdy masz kilka narzędzi analitycznych i marketingowych, zespół marketingowy potrzebuje samodzielnie dodawać tagi bez deployów, lub gdy chcesz centralnie zarządzać zgodami dla wielu tagów. Szczegóły tej decyzji opisuję w artykule o GTM w Next.js.
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 rozwijam własne projekty.
Jak zbudować custom dashboard analityczny w Next.js, który pobiera dane bezpośrednio z GA4 Data API? Server-side, autoryzacja, cache i wizualizacja z Recharts.
Maciej Sala
Founder StriveLab
Jak wdrożyć remarketing Google Ads w aplikacji React? Dynamiczny remarketing ecommerce, listy odbiorców na podstawie zachowań użytkowników i integracja z listami odbiorców w GA4.
Maciej Sala
Founder StriveLab
Praktyczny poradnik GTM w Next.js: dataLayer contract, SPA page views, custom triggers, ecommerce, consent mode i współpraca deweloper–marketer.