Konwersje Google Ads
Pomiar konwersji z kampanii Google Ads na koncie AW-5763834111. Etykiety dostarczone przez agencję dzielą się na dwie grupy:
| Konwersja | Etykieta | Gdzie się wdraża |
|---|---|---|
[SE] Formularz | CY7sCNnV4eQcEI3akMZE | aplikacja (ten projekt) |
[SE] Rozpoczęcie formularza | kxVwCNzV4eQcEI3akMZE | aplikacja (ten projekt) |
[SE] Klik Tel | 612GCN_V4eQcEI3akMZE | strona www |
[SE] Klik Email | thc-COLV4eQcEI3akMZE | strona www |
[SE] Strona kontakt | 0mccCOO57OQcEI3akMZE | strona www |
Aplikacja nie ma strony kontaktowej ani odnośników tel: / mailto:, więc trzy
ostatnie konwersje wdraża się na stronie klubu — gotowy kod znajduje się
na końcu tego dokumentu.
Integracja w aplikacji jest włączana z panelu administratora:
Panel administratora → Marketing — pomiar konwersji
(/dashboard/marketing-settings). Domyślnie jest wyłączona; identyfikator
konwersji i obie etykiety są wpisane wstępnie.
👤 Instrukcja dla marketingu
Co jest mierzone w aplikacji
| Konwersja | Kiedy się wysyła |
|---|---|
[SE] Rozpoczęcie formularza | w chwili wyboru usługi na ekranie zapisu, czyli gdy odwiedzający zaczyna wypełniać formularz |
[SE] Formularz | dopiero po potwierdzeniu kodu SMS, gdy backend utworzył konto |
Czego nie zobaczysz w Google Ads — i tak ma być:
- samego wejścia na stronę zapisu bez wyboru usługi,
- porzuconego formularza: dopóki konto nie powstanie, nie ma konwersji
[SE] Formularz, - drugiego „rozpoczęcia formularza" w tej samej sesji, gdy odwiedzający wróci do kafelków i wybierze inną usługę,
- powtórki konwersji przy odświeżeniu strony — każde zgłoszenie ma własny
transaction_id(registration_<id konta>), po którym Google odsiewa duplikaty, - ruchu z
dev.klient.acepark.pl,panel.acepark.pli ze środowisk lokalnych — tag ładuje się wyłącznie na produkcyjnym portaluklient.acepark.pl, - ruchu osób, które nie zaakceptowały banera cookies.
Włączenie integracji
- Google Ads → Cele → Podsumowanie → wybrana konwersja → „Skonfiguruj tag" —
stamtąd pochodzą identyfikator konwersji (
AW-…) i etykieta. - Panel administratora → Marketing — pomiar konwersji → karta Google Ads — konwersje: sprawdź identyfikator i etykiety, przełącz Integracja aktywna, zapisz.
- Włączenie bez identyfikatora konwersji albo bez żadnej etykiety jest odrzucane — panel nie pozwoli twierdzić, że integracja działa, gdy nie miałaby czego wysłać.
- Etykietę można zostawić pustą celowo: konwersja bez etykiety po prostu nie jest raportowana, reszta działa dalej.
Zgody
Tag Google Ads nie ładuje się w ogóle, dopóki odwiedzający nie zaakceptuje banera cookies — dokładnie tak samo jak Meta Pixel. Bez zgody nie powstaje żadne zdarzenie, a konwersja nie czeka w kolejce.
Weryfikacja
- Zainstaluj rozszerzenie Google Tag Assistant (lub otwórz podgląd w Google Ads → Cele → Diagnostyka).
- Otwórz
https://klient.acepark.pl, zaakceptuj baner cookies. - Wejdź na ekran zapisu i wybierz usługę → Tag Assistant pokaże zdarzenie
conversionzsend_to: AW-5763834111/kxVwCNzV4eQcEI3akMZE. - Dokończ rejestrację testową → drugie zdarzenie
conversion, tym razem z etykietąCY7sCNnV4eQcEI3akMZEi wypełnionymtransaction_id. - W Google Ads konwersja pojawia się na liście z opóźnieniem do kilku godzin — status „Brak ostatnich konwersji" tuż po teście jest normalny.
🔧 Dokumentacja techniczna
Przepływ
Moduły
| Plik | Rola |
|---|---|
lib/analytics/config.ts | lista hostów produkcyjnych i stałe zgody, wspólne z Meta |
lib/analytics/consent.ts | odczyt zgody na marketingowe cookies |
lib/google-ads/events.ts | nazwy konwersji i budowa transaction_id |
lib/google-ads/settings.ts | odczyt ustawień z D1 przez cache KV |
lib/google-ads/gtag-client.ts | wysyłka konwersji, kolejka i blokada powtórek |
lib/actions/google-ads-tracking-settings.ts | zapis ustawień z panelu (tylko ADMIN) |
components/analytics/google-ads-tag.tsx | kod bazowy gtag.js, bramka zgody, publikacja etykiet do klienta |
components/forms/google-ads-tracking-settings/… | formularz w panelu administratora |
app/register/[token]/registration-entry-client.tsx | miejsca wywołania obu konwersji |
Dwie bramki
Tag renderuje się tylko wtedy, gdy oba warunki są spełnione:
- Ustawienie —
google_ads_tracking_settings.enabled = 1z identyfikatorem konwersji (panel administratora). Ustawienie jest per tenant. - Host —
isTrackingHost()przepuszcza wyłącznieklient.acepark.pl(lib/analytics/config.ts, ten sam kod co Meta Pixel).
Trzecim warunkiem jest zgoda odwiedzającego, sprawdzana w przeglądarce.
Tabela google_ads_tracking_settings
Migracja 0234_create_google_ads_tracking_settings.sql, jeden wiersz na tenant:
enabled, conversion_id, form_submit_label, form_start_label,
updated_at, updated_by.
Etykiety są danymi, nie stałymi w kodzie: Google Ads generuje nową etykietę przy każdym odtworzeniu akcji konwersji, a kampanie nie mogą czekać na deploy.
Konfiguracja jest czytana przy każdym renderze strony, więc trzyma się w cache KV
(google-ads-tracking, TTL 300 s, unieważniany przy zapisie).
Kolejka i moment wysyłki
Konwersja [SE] Formularz powstaje tuż przed pełną nawigacją do aplikacji, więc:
- zdarzenie leci z
transport_type: 'beacon'—navigator.sendBeaconprzeżywa opuszczenie strony, zwykły obrazek pomiarowy niekoniecznie; - jeśli
gtagnie zdążył się załadować (albo etykiety nie zostały jeszcze opublikowane), konwersja czeka wsessionStoragei jest wysyłana na kolejnej stronie — maksymalnie przez 10 minut.
[SE] Rozpoczęcie formularza jest ograniczone kluczem w sessionStorage
(markGoogleAdsConversionReported('form-start', 'session')), więc powrót do
kafelków i wybór drugiej usługi nie tworzy drugiej konwersji.
Deduplikacja
| Konwersja | transaction_id | Źródło identyfikatora |
|---|---|---|
[SE] Formularz | registration_<userId> | id konta utworzonego przez backend (conversionEventId) |
[SE] Rozpoczęcie formularza | — | klucz sesyjny w przeglądarce |
conversionEventId jest tym samym identyfikatorem, którego używa Meta Pixel jako
event_id — backend zwraca go tylko wtedy, gdy konto naprawdę powstało, więc
nieudana rejestracja nie może zaraportować konwersji.
🌐 Strona www — gotowy kod
Poniższy kod dotyczy strony klubu (acepark.pl), a nie tego repozytorium.
Ładuj go dopiero po zgodzie na cookies marketingowe — na WordPressie robi to
zwykle wtyczka zgód, ustawiając kod jako „marketing".
1. Tag bazowy (w <head> każdej podstrony)
<script
async
src="https://www.googletagmanager.com/gtag/js?id=AW-5763834111"
></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'AW-5763834111');
</script>
2. Klik w telefon i w e-mail
Działa dla wszystkich odnośników tel: i mailto: na stronie, bez zmieniania ich
pojedynczo:
<script>
document.addEventListener('click', function (event) {
var link = event.target.closest('a[href^="tel:"], a[href^="mailto:"]');
if (!link || typeof gtag !== 'function') return;
var isPhone = link.getAttribute('href').indexOf('tel:') === 0;
gtag('event', 'conversion', {
send_to: isPhone
? 'AW-5763834111/612GCN_V4eQcEI3akMZE'
: 'AW-5763834111/thc-COLV4eQcEI3akMZE',
transport_type: 'beacon'
});
});
</script>
3. Strona kontakt
Na samej podstronie kontaktowej, po tagu bazowym:
<script>
gtag('event', 'conversion', {
send_to: 'AW-5763834111/0mccCOO57OQcEI3akMZE'
});
</script>
Wariant z Google Tag Managerem
Jeżeli strona ma GTM, zamiast wklejania kodu:
- Tagi → Nowy → Google Ads Conversion Tracking, Conversion ID
AW-5763834111, Conversion Label — etykieta z tabeli na górze dokumentu. - Reguły:
- Klik Tel — trigger „Just Links", warunek
Click URLzaczyna się odtel:. - Klik Email — trigger „Just Links", warunek
Click URLzaczyna się odmailto:. - Strona kontakt — trigger „Page View", warunek
Page Pathrówna się/kontakt.
- Klik Tel — trigger „Just Links", warunek
- Ustaw „Consent Settings" tagu na wymagające zgody
ad_storage, żeby respektował baner.
Czego nie robić
- Nie wklejaj tagu formularza (
CY7sCNnV4eQcEI3akMZE) na stronie www — formularz zapisu żyje w aplikacji i raportuje się sam. Podwójne wdrożenie policzyłoby jedno zgłoszenie dwa razy. - Nie ładuj tagu przed zgodą na cookies marketingowe.