Przejdź do głównej zawartości

Konwersje Google Ads

Pomiar konwersji z kampanii Google Ads na koncie AW-5763834111. Etykiety dostarczone przez agencję dzielą się na dwie grupy:

KonwersjaEtykietaGdzie się wdraża
[SE] FormularzCY7sCNnV4eQcEI3akMZEaplikacja (ten projekt)
[SE] Rozpoczęcie formularzakxVwCNzV4eQcEI3akMZEaplikacja (ten projekt)
[SE] Klik Tel612GCN_V4eQcEI3akMZEstrona www
[SE] Klik Emailthc-COLV4eQcEI3akMZEstrona www
[SE] Strona kontakt0mccCOO57OQcEI3akMZEstrona 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

KonwersjaKiedy się wysyła
[SE] Rozpoczęcie formularzaw chwili wyboru usługi na ekranie zapisu, czyli gdy odwiedzający zaczyna wypełniać formularz
[SE] Formularzdopiero 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.pl i ze środowisk lokalnych — tag ładuje się wyłącznie na produkcyjnym portalu klient.acepark.pl,
  • ruchu osób, które nie zaakceptowały banera cookies.

Włączenie integracji

  1. Google Ads → Cele → Podsumowanie → wybrana konwersja → „Skonfiguruj tag" — stamtąd pochodzą identyfikator konwersji (AW-…) i etykieta.
  2. Panel administratora → Marketing — pomiar konwersji → karta Google Ads — konwersje: sprawdź identyfikator i etykiety, przełącz Integracja aktywna, zapisz.
  3. 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ć.
  4. 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

  1. Zainstaluj rozszerzenie Google Tag Assistant (lub otwórz podgląd w Google Ads → Cele → Diagnostyka).
  2. Otwórz https://klient.acepark.pl, zaakceptuj baner cookies.
  3. Wejdź na ekran zapisu i wybierz usługę → Tag Assistant pokaże zdarzenie conversion z send_to: AW-5763834111/kxVwCNzV4eQcEI3akMZE.
  4. Dokończ rejestrację testową → drugie zdarzenie conversion, tym razem z etykietą CY7sCNnV4eQcEI3akMZE i wypełnionym transaction_id.
  5. 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

PlikRola
lib/analytics/config.tslista hostów produkcyjnych i stałe zgody, wspólne z Meta
lib/analytics/consent.tsodczyt zgody na marketingowe cookies
lib/google-ads/events.tsnazwy konwersji i budowa transaction_id
lib/google-ads/settings.tsodczyt ustawień z D1 przez cache KV
lib/google-ads/gtag-client.tswysyłka konwersji, kolejka i blokada powtórek
lib/actions/google-ads-tracking-settings.tszapis ustawień z panelu (tylko ADMIN)
components/analytics/google-ads-tag.tsxkod 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.tsxmiejsca wywołania obu konwersji

Dwie bramki

Tag renderuje się tylko wtedy, gdy oba warunki są spełnione:

  1. Ustawieniegoogle_ads_tracking_settings.enabled = 1 z identyfikatorem konwersji (panel administratora). Ustawienie jest per tenant.
  2. HostisTrackingHost() przepuszcza wyłącznie klient.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.sendBeacon przeżywa opuszczenie strony, zwykły obrazek pomiarowy niekoniecznie;
  • jeśli gtag nie zdążył się załadować (albo etykiety nie zostały jeszcze opublikowane), konwersja czeka w sessionStorage i 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

Konwersjatransaction_idŹródło identyfikatora
[SE] Formularzregistration_<userId>id konta utworzonego przez backend (conversionEventId)
[SE] Rozpoczęcie formularzaklucz 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:

  1. Tagi → Nowy → Google Ads Conversion Tracking, Conversion ID AW-5763834111, Conversion Label — etykieta z tabeli na górze dokumentu.
  2. Reguły:
    • Klik Tel — trigger „Just Links", warunek Click URL zaczyna się od tel:.
    • Klik Email — trigger „Just Links", warunek Click URL zaczyna się od mailto:.
    • Strona kontakt — trigger „Page View", warunek Page Path równa się /kontakt.
  3. 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.