# Google Tag Manager Integration

## Official Tag Template (recommended)

The easiest install: download the official tag template from
<https://cdn.findip.net/shield/gtm/findip-shield.tpl> and import it via GTM →
Templates → Tag Templates → New → Import. It exposes the site key, auto-track,
privacy mode, and dataLayer options as configured fields — no HTML editing.

### Identify the visitor (optional)

The template has an **Identify the visitor** section. Point its fields at the
variables your site already exposes for logged-in users, typically the Data
Layer Variables you use for GA4's `user_id`:

| Field | What to select | What Shield receives |
|---|---|---|
| User ID | e.g. `{{DLV - userId}}` | `user_id_hash` — SHA-256 of the ID |
| Email address | e.g. `{{DLV - userEmail}}` | `email_hash` — SHA-256 of the lowercased address, plus `email_domain` (e.g. `gmail.com`) |
| Plan | e.g. `{{DLV - plan}}` or a constant | `plan` |
| Hash salt | an optional secret string | mixed into both hashes: `SHA-256(salt + ':' + value)` |

The SDK hashes the values in the browser before anything is sent. The raw
user ID and email never leave the page. Every automatic event then carries the
hashes. To find the account behind a hash shown in the dashboard, compute the
same SHA-256 of the user ID (with the same salt) in your own system. See
[Identify Users and Add Context](https://www.findip.net/docs/shield/identify-users.md).

## Custom HTML Tag

If you prefer a Custom HTML tag, load the SDK and call `FindIP.init()` from
the script's `onload` handler:

```html
<script>
(function () {
  var s = document.createElement('script');
  s.src = 'https://cdn.findip.net/shield/v1.js';
  s.async = true;
  s.onload = function () {
    if (window.FindIP) {
      window.FindIP.init({
        siteKey: 'pub_xxxxxxxxx',
        autoTrack: true,
        privacyMode: 'balanced',
        pushToDataLayer: true
      });
    }
  };
  document.head.appendChild(s);
})();
</script>
```

Trigger: All Pages. Leave "Support document.write" unchecked.

### Custom HTML tag with visitor identification

To attach your own user to each session, add an `identify` option to the
`init` call with your GTM variables. GTM substitutes `{{Variable}}`
references inside Custom HTML before the tag runs, and the SDK hashes the
values in the browser, so Shield never receives the raw ID or email.

```js
window.FindIP.init({
  siteKey: 'pub_xxxxxxxxx',
  autoTrack: true,
  privacyMode: 'balanced',
  identify: {
    userId: '{{DLV - userId}}',
    email: '{{DLV - userEmail}}',
    plan: '{{DLV - plan}}'
  }
});
```

The dashboard's Install page generates the full tag with your site key filled
in (Google Tag Manager tab → Custom HTML tag → "Identify logged-in visitors").
See [Identify Users and Add Context](https://www.findip.net/docs/shield/identify-users.md) for what each field
becomes.

> **Do not use the `data-site-key` attribute form inside GTM.** GTM does not
> insert Custom HTML verbatim: it re-creates every `<script>` element and copies
> only `src`, `type`, `charset`, and `id`. All `data-*` attributes are dropped,
> so `<script src="…/v1.js" data-site-key="…">` loads the SDK but never
> initializes it and no events are sent. The `data-*` form is only for a
> script tag placed directly in your page HTML.

While testing, add `debug: true` to the `init` options to log every event to
the browser console, then remove it.

## dataLayer Events

The SDK pushes risk results automatically:

```js
{
  event: 'findip_risk_result',
  findip_session_id: 'sess_xxx',
  findip_visitor_id: 'vis_xxx',
  findip_request_id: 'req_xxx',
  findip_risk_score: 87,
  findip_risk_level: 'high',
  findip_recommendation: 'challenge',
  findip_is_vpn: true,
  findip_is_proxy: false,
  findip_is_tor: false,
  findip_is_relay: false,
  findip_is_hosting: true,
  findip_is_malicious: false,
  findip_country: 'US',
  findip_asn: 12345
}
```

Create a GTM trigger on `event equals findip_risk_result` to act on risk scores.

## Passing Context via dataLayer

Push context before form events:

```js
dataLayer.push({
  email_domain: 'gmail.com',
  plan: 'enterprise',
  user_id_hash: 'sha256_hash_here',
});
```

The SDK reads allowlisted fields from existing dataLayer entries. Push them
before the Shield tag fires; the first value found for each key wins. For the
full field list, hashing guidance, and troubleshooting, see
[Identify Users and Add Context](https://www.findip.net/docs/shield/identify-users.md).

## Consent Mode

Integrate with CMP:

```js
// On consent granted
FindIP.setConsent(true);

// On consent denied
FindIP.setConsent(false);
```

## Troubleshooting

- **SDK loads but no events, no `_fip_*` cookies:** you used the `data-site-key`
  attribute form in a Custom HTML tag. Switch to the `onload` + `init` snippet
  above or to the official template.
- Disable dataLayer push: `pushToDataLayer: false` in `init` (or the template's
  dataLayer toggle)
- SDK auto-detects GTM via `google_tag_manager` or `dataLayer` presence

---

Canonical page: https://www.findip.net/docs/shield/google-tag-manager · Markdown: https://www.findip.net/docs/shield/google-tag-manager.md · All Shield docs in one file: https://www.findip.net/llms-full.txt
