Skip to content

Installation guides

Every guide installs the same tag. Replace pk_live_xxxxxxxx with the key from Settings → Installation.

<script defer
data-site="pk_live_xxxxxxxx"
data-api="https://ingest.tracing.tools"
src="https://ingest.tracing.tools/t.js"></script>

data-api is optional — it defaults to https://ingest.tracing.tools — but including it makes the snippet explicit and is what the dashboard copies.

Paste it before the closing </head> tag of every page. Static-site generators usually have one layout or partial that every page shares — put it there.

index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script defer
data-site="pk_live_xxxxxxxx"
data-api="https://ingest.tracing.tools"
src="https://ingest.tracing.tools/t.js"></script>
</head>
<body>
<!-- … -->
</body>
</html>

No plugin is needed. Two options, in order of preference.

Theme header (child theme or a code snippet plugin):

functions.php
add_action('wp_head', function () {
?>
<script defer
data-site="pk_live_xxxxxxxx"
data-api="https://ingest.tracing.tools"
src="https://ingest.tracing.tools/t.js"></script>
<?php
}, 1);

Enqueue it properly, which lets caching plugins version and defer it correctly:

functions.php
add_action('wp_enqueue_scripts', function () {
wp_enqueue_script(
'tracing',
'https://ingest.tracing.tools/t.js',
[],
null,
['strategy' => 'defer', 'in_footer' => false]
);
});
add_filter('script_loader_tag', function ($tag, $handle) {
if ($handle !== 'tracing') return $tag;
return str_replace(
'<script ',
'<script data-site="pk_live_xxxxxxxx" data-api="https://ingest.tracing.tools" ',
$tag
);
}, 10, 2);

Exclude the admin area from reports with Settings → General → Excluded paths:

/wp-admin/**
/wp-login.php
  1. Tags → New → Tag Configuration → Custom HTML.

  2. Paste the snippet. Leave Support document.write unchecked.

    <script defer
    data-site="pk_live_xxxxxxxx"
    data-api="https://ingest.tracing.tools"
    src="https://ingest.tracing.tools/t.js"></script>
  3. Triggering → Initialization - All Pages. Not All Pages: initialization fires earlier, which keeps the landing hit — and the campaign on it — intact.

  4. Set Tag firing options to Once per page.

  5. Submit and publish.

To send a custom event from another GTM tag, call the global directly:

<script>
window.tracing && window.tracing("form_submitted", {
form: {{Form ID}}
});
</script>

The tracker needs to load from the collector and to POST to it. With a strict CSP, add the collector origin to two directives:

Content-Security-Policy
script-src 'self' https://ingest.tracing.tools;
connect-src 'self' https://ingest.tracing.tools;

What each one covers:

Directive Why Requests
script-src loading /t.js GET https://ingest.tracing.tools/t.js
connect-src the mode probe and every hit GET /c/:key, POST /e, and navigator.sendBeacon to /e

The tracker adds no inline script, no styles, no images and no iframes, so style-src, img-src and frame-src need nothing.

If you proxy the collector behind your own domain, both directives can stay at 'self' and you need no exception at all.

  1. Load a page in a normal tab (not localhost).
  2. In DevTools → Network, filter for t.js — it should be 200 and about 5 KB.
  3. Look for c/pk_live_… — a 200 with {"m":"hash"}.
  4. Look for a POST to /e — a 202.
  5. Open Realtime in the dashboard.

If any of those are missing, work through Opt-out & debugging.