> For the complete documentation index, see [llms.txt](https://docs.dapta.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dapta.ai/dforms/connect/tracking-and-pixels.md).

# Tracking & pixels

Add Google Tag Manager, Meta Pixel, PostHog or the HubSpot tracking code to a form's public page, understand when each tag fires, including the Lead conversion on a completed form, and see how UTM par

**Tracking & pixels** lets you measure the traffic that reaches a form with the tools you already use. You paste an ID, publish, and the matching tag loads on the form's public page. Nothing loads in the editor, and nothing loads for a tool whose ID you left empty.

This is optional. dForms already counts views, starts, submissions and drop-off on its own under [Analytics](/dforms/results/analytics.md); tracking IDs are for stitching form traffic into your own campaign reporting.

***

**Step 1:** Open the form in the editor and click the **Connect** tab. Scroll past **Integrations** to the **Tracking & pixels** section.

<figure><img src="https://3835013762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCy5rSNtQmtqYCGzJlNEB%2Fuploads%2Fgit-blob-2f3c2b3b179d13ad90cc1877793854829b7a69ed%2Fforms-tracking-and-pixels-01-connect-tab.png?alt=media" alt="The Connect tab of the form editor showing the Integrations cards and the start of the Tracking and pixels section"><figcaption><p>The <strong>Connect</strong> tab holds <strong>Integrations</strong>, <strong>Tracking &#x26; pixels</strong>, <strong>Emails</strong> and <strong>Spam protection (captcha)</strong>.</p></figcaption></figure>

***

**Step 2:** Fill in only the fields for the tools you use. Every field is optional and independent.

<figure><img src="https://3835013762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCy5rSNtQmtqYCGzJlNEB%2Fuploads%2Fgit-blob-6c9be5ec0a57118dc74bfc6d0fbc992b0c449e3e%2Fforms-tracking-and-pixels-02-fields.png?alt=media" alt="The five tracking fields filled in, each with its help text: Google Tag Manager ID, Meta Pixel ID, PostHog project key, PostHog host and HubSpot tracking ID"><figcaption><p>Five fields, five tags. Leave a field empty and that tag is never loaded.</p></figcaption></figure>

| Field                       | What you paste             | What it does on the form page                                                                                                                                                                                |
| --------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Google Tag Manager ID**   | `GTM-XXXXXXX`              | Loads your GTM container so your tags fire, and pushes a `form_lead` event when someone completes the form.                                                                                                  |
| **Meta Pixel ID**           | `123456789012345`          | Fires a `PageView` when the form loads, and a `Lead` when someone completes it.                                                                                                                              |
| **PostHog project key**     | `phc_...`                  | Captures a pageview in PostHog for product analytics.                                                                                                                                                        |
| **PostHog host (optional)** | `https://us.i.posthog.com` | Defaults to PostHog US cloud; set your EU or self-hosted ingestion URL.                                                                                                                                      |
| **HubSpot tracking ID**     | `12345678`                 | Loads the HubSpot tracking code for your portal on the form page. If you embed this form in pages that already load your HubSpot tracking code, leave it empty: the embed passes the visit from those pages. |

> **💡 Tip:** The **PostHog host** field only matters if your project is not on PostHog US cloud. It must be a full address, for example `https://eu.i.posthog.com`. Anything else is refused with **Enter a full http(s) URL, e.g. <https://eu.i.posthog.com>.**

***

**Step 3:** Click **Publish**. Tracking IDs are part of your draft, so they only reach visitors once the form is published.

<figure><img src="https://3835013762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCy5rSNtQmtqYCGzJlNEB%2Fuploads%2Fgit-blob-8f804b4094309f57c3539e81b0ff5d0beeb51695%2Fforms-tracking-and-pixels-03-staged-until-publish.png?alt=media" alt="The staged banner above the tracking fields and the Publish button in the topbar, both outlined in red"><figcaption><p>The banner says it plainly: tracking IDs are staged with your draft, <strong>Integrations</strong> are not.</p></figcaption></figure>

The banner above the fields reads: "These IDs are staged with the rest of your draft: click Publish to put them on the live form. Integrations above save to the live form immediately."

That difference is worth remembering:

* **Tracking & pixels**: saved into the draft, live after **Publish**.
* **Integrations** (webhook, HubSpot): saved to the live form the moment you change them, no publish needed.

See [Autosave, drafts & publishing](/dforms/builder/autosave-and-publishing.md) for the rest of the draft lifecycle.

***

## When each tag fires

The rules are the same for every tool, so what you measure stays predictable:

* Tags load **only on the public form page**. The editor, the preview and the admin never load them.
* Each visit produces **exactly one pageview**: one GTM container load, one Meta `PageView`, one PostHog `$pageview`, one HubSpot tracking script.
* Moving from one question to the next fires **nothing**. A slides form is a single page for your analytics, however many steps it has.
* Completing the form fires **one conversion**: a Meta `Lead` and a `form_lead` event in the GTM `dataLayer`. See the next section.

> **⚠️ Note:** dForms does not show a cookie or consent banner on the public form. If your visitors need one, handle consent in your own GTM container and gate your tags there.

***

## The conversion on a completed form

When someone completes the form:

* with a **Meta Pixel ID**, the pixel fires the standard `Lead` event;
* with a **Google Tag Manager ID**, the form pushes `{ event: 'form_lead' }` to the `dataLayer`. In GTM, create a **Custom Event** trigger with the event name `form_lead` and attach your conversion tags to it.

Three rules keep the count honest:

* It fires only after dForms has saved the complete submission. A partial submission, or a send that failed, never fires it.
* It fires once per visit. A double click, or a reload of the thank-you screen in the same tab, does not count twice.
* It goes out before the redirect of the [ending screen](/dforms/logic/ending-screen.md), so an ending that redirects with no delay does not cancel it.

## LinkedIn, TikTok, Google Ads and everything else

There are only five fields, and there is no separate field for LinkedIn Insight, TikTok Pixel, Google Ads or any other tool. Load those through **Google Tag Manager**: set the **Google Tag Manager ID** here, then add each tag inside your container, with `form_lead` as the trigger for their conversion tags. One ID on the form, as many tags as you like in GTM.

## UTM parameters are captured for you

You do not need a pixel to know where a lead came from. When someone opens a form with campaign parameters on the link, for example:

```
https://app.dforms.ai/acme/f/lead-qualification-quiz?utm_source=linkedin&utm_medium=cpc&utm_campaign=spring
```

`utm_source`, `utm_medium`, `utm_campaign`, `utm_term` and `utm_content` are stored with the submission. From there they travel with the answer:

* to HubSpot, through the five **UTM mappings** in [Form elements](/dforms/connect/hubspot/form-elements.md);
* to your endpoint, in the `utm` object of the [webhook payload](/dforms/connect/webhooks/payload-reference.md).

When the form is embedded with the full snippet, the UTMs of your page count too: if the iframe `src` has no `utm_` parameters, the ones on your page's address are saved. See [What your page tells the form](/dforms/share/embed.md#what-your-page-tells-the-form).

The footnote under the fields says the same: "UTM parameters are captured automatically and can be mapped to HubSpot properties in Integrations."

> **⚠️ Note:** `utm_` keys are reserved for campaign capture. A question whose field key starts with `utm_` is never prefilled from the URL. See [Hidden fields & URL prefill](/dforms/builder/hidden-fields-and-url-prefill.md).

## Embedded forms

* Tracking IDs set here load inside the iframe, on the form's own page, and fire there. The page around the form is not told: its own pixel or GTM container does not see the `Lead`, and `form_lead` lands in the frame's `dataLayer`, not in your page's.
* Some browsers, Safari among them, limit tracking inside a frame from another site, so conversions from an embedded form are measured less reliably than on the direct link.
* For HubSpot, an embedded form does not need the **HubSpot tracking ID**: the embed script passes the visit from your page. See [Landing page & HubSpot attribution](/dforms/connect/hubspot/attribution.md).

## Page paths in your triggers

Form links have the shape `https://app.dforms.ai/{account code}/f/{slug}`. Older links carried a teammate's handle in place of the `f`, and **Edit link** can change the slug. A GTM or Google Analytics trigger that matches an older path with a handle only fires for visitors who still use that old link. A trigger for a slug you changed stops firing, because the old address sends visitors to the new one before any tag loads. Match on `/f/{slug}`, or on the slug alone. See [Your public link](/dforms/share/public-link.md).

## What is collected

A form with no tracking IDs makes **no requests to third parties**, with one exception: with [spam protection](/dforms/connect/spam-protection.md) on, the Cloudflare check loads once the visitor starts answering (see its [privacy notes](/dforms/connect/spam-protection.md#privacy)).

dForms itself stores the answers, the score, the timestamps and the UTMs of a submission, plus the page it was answered on:

* the page address: the form's own address with only its `utm_` parameters on a direct link, your page's full address when the form is embedded with the full snippet, or what the browser reports as the referring page (usually just your site's domain) with a bare iframe;
* the page title;
* the visitor's HubSpot cookie, only when one arrived and the form's webhook or HubSpot integration will use it.

It does not store IP addresses, user agents, devices or countries. Read [Security & Privacy](/dforms/security-and-privacy.md) for the full picture.

## What's next

* [Analytics](/dforms/results/analytics.md): views, starts, completion rate and drop-off, measured by dForms.
* [Form elements: UTMs, score, outcome, submitted date](/dforms/connect/hubspot/form-elements.md): send the captured UTMs to HubSpot properties.
* [Landing page & HubSpot attribution](/dforms/connect/hubspot/attribution.md): link submissions to the visitor's earlier page views in HubSpot.
* [Payload & headers reference](/dforms/connect/webhooks/payload-reference.md): where the UTMs and the page sit in the webhook body.
* [Autosave, drafts & publishing](/dforms/builder/autosave-and-publishing.md): why the IDs wait for **Publish**.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.dapta.ai/dforms/connect/tracking-and-pixels.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
