# Analytics and marketing tracking

## Scope

The production website uses these tracking integrations:

- Google Tag Manager container `GTM-WL3GR3VG`;
- Meta Pixel `1370373888624638`, configured inside that GTM container with
  `PageView` and consent-gated `CompleteRegistration` events.

After a successful class signup, the application queues a one-time
`class_signup` event across the redirect. The shared tracking loader sends it
only when tracking consent is granted:

- GTM receives `class_signup` through `dataLayer` and routes it to the
  configured Google and Meta tags;
- the event includes a random `event_id`, `signup_type`, technical `class_id`,
  and `participant_type` (`self` or `child`), but no account ID, name, email,
  or other direct user identifier;
- supported signup types are `group_recurring`, `group_once`, and `course`.

The session queue is consumed by the first rendered page after the redirect,
so refreshing that page does not emit the signup again. The random `event_id`
is also available as a Google Ads transaction ID and as Meta's browser event
ID for deduplication.

Tracking is disabled when `ENVIRONMENT` is `DEV`, including local development
and the test-next environment. The local consent script is still present there,
so the consent UI can be tested without sending data to Google or Meta.

## Consent rule

The `cookie-consent-tracking-allowed` first-party cookie is the source of the
visitor's current choice:

- missing or `false`: Google Tag Manager and Meta Pixel must not be requested;
- `true`: both integrations may load;
- the choice expires after 365 days and can be changed through the
  `zarządzanie cookie` link in the footer.

The implementation uses Google's basic consent mode. When consent is granted,
the page queues a denied default for `ad_storage`, `analytics_storage`,
`ad_user_data`, and `ad_personalization`, updates these states to granted, and
then loads the GTM container. No consent-mode ping or other request is sent to
Google while consent is missing or denied.

Because GTM itself is not requested before consent, its Meta Pixel tag can only
initialize and send `PageView` after the same consent. If the visitor later
selects necessary cookies only, Google consent is updated to denied, Meta
consent is revoked when its library is present, and accessible first-party
Google and Meta tracking cookies are expired.

The GTM `noscript` fallback is rendered by PHP only for a production request
that already contains a granted consent cookie. It must never be moved outside
that server-side condition because an unconditional iframe request would
bypass the consent banner. The website does not render a separate Meta Pixel
`noscript` image.

## Tag Manager configuration

The container must not be used to bypass the website's consent rule. Any tag
added to GTM must have consent settings appropriate to its purpose. Non-Google
tags require explicit consent checks because they do not automatically honor
Google consent mode.

GTM is the only component allowed to load, initialize, or send events to Meta
Pixel. The shared website loader must not contain the Meta base code, pixel ID,
`PageView`, or `CompleteRegistration`. There must be exactly one Meta base tag
and one Meta conversion tag in the published container. Do not add pixel
`2250661981881655`; the production dataset remains `1370373888624638`.

The website currently reports a successful class signup as the final
conversion. It does not emit a separate account-creation event. Do not infer
account creation from a page view or reuse `class_signup` for that purpose. A
future account-creation conversion requires a separate application event and
an explicit decision about its Google and Meta event names so it cannot be
confused with a class signup.

## Google Tag Manager configuration for class signup

The repository sends the event to GTM but does not publish the external GTM
container. Configure container `GTM-WL3GR3VG` as follows:

1. Create Data Layer Variables (Version 2) named `DLV - event_id`,
   `DLV - signup_type`, `DLV - class_id`, and `DLV - participant_type`, using
   data layer variable names matching the suffixes exactly.
2. Create a Custom Event trigger named `CE - class_signup`, with event name
   `class_signup`, firing on all matching custom events.
3. Keep one Meta base tag for pixel `1370373888624638`. It must initialize the
   pixel and send one `PageView` on the initial GTM page event. Remove or pause
   every duplicate Meta base tag and do not add pixel `2250661981881655`.
4. Create a Meta `CompleteRegistration` tag triggered by `CE - class_signup`.
   It must send `signup_type`, `class_id`, and `participant_type` as event
   parameters and use `{{DLV - event_id}}` as Meta's `eventID`. This preserves
   one conversion per successful server-side signup and allows important class
   IDs to be separated through Meta custom conversions.
5. Confirm that the container has the Google tag and a Conversion Linker for
   the Google Ads destination. Because the whole container is loaded only after
   tracking consent, these tags must not add a separate pre-consent loader.
6. Create a Google Ads website conversion action in the Sign-up category. Use
   no monetary value and count one conversion per ad interaction.
7. In GTM, create a Google Ads Conversion Tracking tag with that conversion
   action's ID and label. Use `{{DLV - event_id}}` as Transaction ID and fire
   it on `CE - class_signup`.
8. Optionally create a GA4 Event tag triggered by `CE - class_signup`, using
   event name `generate_lead` and passing `event_id`, `signup_type`, `class_id`,
   and `participant_type` as event parameters. Mark `generate_lead` as a key
   event in GA4 if it should appear as a conversion there. Register
   event-scoped custom dimensions for `signup_type` and `participant_type` if
   those splits should be available in GA4 reports; avoid registering the
   higher-cardinality `class_id` unless there is a concrete reporting need.
9. Do not import the GA4 key event into Google Ads as a second primary
   conversion when the direct Google Ads tag is already primary. That would
   create two Google Ads conversion sources for one signup.
10. Verify in GTM Preview, Meta Test events, and Google Ads diagnostics, then
    publish the container.

After publication, Google Ads attributes the conversion to campaign, ad group,
ad, and keyword dimensions using its normal ad-click attribution. Add the
signup conversion and cost-per-conversion columns to those reports; no UTM
report or application-side join is required for this browser-only stage.

## Meta reporting configuration for class signup

After deployment and granted consent, the GTM-managed pixel sends
`CompleteRegistration` to dataset/pixel `1370373888624638`.

1. Verify the event in Events Manager under Test events.
2. In an ad set using the Website conversion location, select this dataset and
   `CompleteRegistration` as the conversion event when signup is the campaign
   objective.
3. In Ads Manager reporting, add the `CompleteRegistration` result/conversion
   column and its cost column at campaign, ad set, and ad level. The event
   parameters can be used to distinguish recurring groups, one-time classes,
   and courses in diagnostics or in separate custom conversions if that split
   is needed later.
4. For a separately reported important course or class, create a Meta custom
   conversion based on `CompleteRegistration` and its `class_id` parameter.
   Use a stable business-facing name and record the corresponding technical
   class ID in the campaign documentation.
5. Do not create a separate pixel or a separate base tag for each campaign.
   Meta attributes the same conversion event to the campaign, ad set, and ad
   that produced the visit. Separate pixels would fragment history and
   audiences rather than improve campaign reporting.

Changes to the container, connected destinations, event definitions, data
retention, or advertising purposes require a review of the cookie banner and
the privacy policy before publication.

## Verification

1. In a private browser session, open the production website and leave the
   consent dialog unanswered. Confirm in the Network panel that there are no
   requests to `googletagmanager.com`, `connect.facebook.net`, or
   `facebook.com/tr`.
2. Select `Akceptuj tylko niezbędne` and repeat the same check after navigation.
3. Reset the choice from the footer, select `Akceptuj wszystkie`, and confirm
   that GTM loads container `GTM-WL3GR3VG` and its Meta tag sends one
   `PageView` for pixel `1370373888624638`.
4. Navigate to another page and confirm that the consent remains active and
   only one Meta `PageView` is sent for that page.
5. Withdraw consent through the footer and confirm that subsequent navigation
   sends no requests from either integration.
6. With consent granted, complete each supported signup type. Confirm that GTM
   Preview receives one `class_signup` with the expected parameters, fires one
   Meta conversion tag, and Meta Test events receives one
   `CompleteRegistration` with the same `event_id`.
7. Refresh the destination page and confirm that neither signup event repeats.

The privacy policy must continue to identify Google and Meta, the purposes of
the tools, the categories of data involved, possible international transfers,
and the way consent can be withdrawn.
