# Repejo Google Tag Manager / dataLayer reference

> Repejo's checkout pushes events to `window.dataLayer` in the donor's
> browser: GA4 ecommerce funnel events, a server-built `purchase`
> conversion, and a `repejo_click` event for individual element
> interactions (inputs, buttons, radios). Your existing GTM container picks
> them up — Repejo never loads its own container and never overwrites an
> existing dataLayer.

- Human docs page: https://app.repejo.se/docs/gtm-events
- Enable under *Settings → Integrations → Google Tag Manager* in the Repejo
  back office. No container ID is needed.

## Consent

Events are pushed only with marketing-cookie consent — via Cookiebot when
present, the `user-has-consented-to-marketing-cookies` attribute on the
embed element when you run your own CMP, or the built-in cookie banner on
the hosted checkout.

## Funnel events (GA4 standard names)

Built client-side, PII-free, pushed once per page load and event type:

| Event | Fires when |
|-------|------------|
| `begin_checkout` | the donor makes the first choice that starts the flow (e.g. picks an amount) |
| `view_item` | the donor leaves the first step (contact details submitted) |
| `add_payment_info` | the donor confirms a payment method |

```js
window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
  event: "begin_checkout",          // or "view_item" / "add_payment_info"
  ecommerce: { currency: "SEK", value: 205 }
});
```

## purchase

Built once server-side and pushed only when the payment is confirmed on the
thank-you page. Same `transaction_id` as the optional server-side
Measurement Protocol relay, so GA4 deduplicates. Top-level `donation_type`
(`recurring` / `onetime` / `gift_card` / `membership` / `p2p` / `product` /
`lottery`) distinguishes Repejo purchases from a shop checkout sharing the
container.

```js
window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
  event: "purchase",
  donation_type: "recurring",
  ecommerce: {
    transaction_id: "rec_…",
    value: 205.0,
    currency: "SEK",
    items: [{ item_name: "Monthly donation", item_category: "recurring",
              price: 205.0, quantity: 1 }]
  }
});
```

Optional keys (`repejo_metadata`, `user_data`, `gclid`, `fbclid`) are
included only when present; `user_data` is off by default and requires the
per-integration `include_user_data` opt-in.

## repejo_click — element interactions

One event for every tracked input, button, link, radio and dropdown in the
checkout, so funnel progression can be measured element by element:

```js
window.dataLayer.push({
  event: "repejo_click",
  click_classes: "form_radio",        // element category, see tables below
  click_id: "payment_method",         // stable element id
  click_value: "autogiro",            // payment_method radios only
  checkout_step: "select_payment_method"  // internal state name, when known
});
```

Semantics:

- **Inputs and dropdowns** (`form_field` / `form_dropdown`) push once per
  checkout instance, on first focus — "the donor engaged with this field".
- **Buttons, links and radios** (`form_button` / `form_link` /
  `form_radio`) push on every click. The `payment_method` radio includes
  the chosen method as `click_value` (`autogiro`, `swish`, `swish_onetime`,
  `card`, `apple_pay`, `google_pay`, `sepa_direct_debit`).

### GTM setup

1. Create a **Custom Event** trigger with event name `repejo_click`.
2. Create two **Data Layer Variable**s: `click_classes` and `click_id`
   (and `click_value` if you split on payment method).
3. Filter triggers on the variables, e.g. *click_id equals
   to_payment_method* for "reached payment-method selection".

### Why not GTM's built-in Click triggers?

The checkout UI renders inside **shadow DOM** in every embed mode — the
flow component inside `<repejo-checkout>` uses a shadow root, and the modal
(`<repejo-checkout-button>`) and sticky (`<repejo-sticky-checkout>`) embeds
add another shadow boundary around it. The browser retargets events
crossing a shadow boundary, so GTM's built-in Click Classes / Click ID
variables only ever see the outer host element, never the clicked element.
`repejo_click` is pushed by Repejo itself from inside the component and
therefore works in **every** embed mode — use it. (Tracked elements still
carry their category class and an id — e.g.
`class="form_button" id="start_payment"` — which custom listeners that
pierce open shadow roots can read, but the supported surface is
`repejo_click`.)

### Element vocabulary — step 1 (amount + contact details)

| click_classes | click_id | Element |
|---------------|----------|---------|
| `form_field` | `custom_amount` | the custom "other amount" input |
| `form_field` | `phone` | phone number input |
| `form_field` | `email` | email input |
| `form_field` | `pnr` | personal identity number (personnummer) input |
| `form_button` | `fetch_address` | "Hämta adress" — fetch address from personnummer |
| `form_link` | `manual_contact_info` | "fill in my address myself" link |
| `form_button` | `to_payment_method` | the submit button to the payment-method step |

### Element vocabulary — step 2 (payment method)

| click_classes | click_id | Element |
|---------------|----------|---------|
| `form_radio` | `payment_method` | payment-method radio; `click_value` carries the method |
| `form_button` | `choose_payment_method` | "Fortsätt med …" — confirms the selected method |

### Element vocabulary — step 3 (Autogiro bank details + BankID)

| click_classes | click_id | Element |
|---------------|----------|---------|
| `form_button` | `fetch_account_details` | "Hämta bankuppgifter" — open-banking account fetch |
| `form_field` | `clearing_number` | clearing number input |
| `form_field` | `account_number` | account number input |
| `form_dropdown` | `bank` | bank select |
| `form_button` | `start_payment` | "Godkänn med BankID" — submits the mandate |
| `form_button` | `complete_donation` | "Öppna BankID på denna enhet" on the signing screen |

Note on DOM attributes: the DOM `id` of the inputs follows the field name
(`phone_number`, `personal_identity_number`, `amount`), not the `click_id`
above — buttons and links carry their `click_id` as the DOM id. The
`repejo_click` event always uses the vocabulary in these tables.

## Testing

Add `?gtm_debug=1` to the checkout URL (or enable debug mode on the
integration): every push is logged to the DevTools console with the
`[Repejo GTM]` prefix. Verify triggers with GTM Preview / Tag Assistant
before wiring live tags.
