A client forwards you a fresh enquiry from their Forminator form. The name and email are right there, the message is keen, and the first question out of their mouth is the one you can’t answer: “Which campaign produced this lead?” You check the submission in WordPress and there’s nothing. No source, no campaign, no clue whether it came from the Google Ads spend, the LinkedIn post, or a stranger typing the URL by hand. We’ve sat in that exact meeting more times than we’d like to admit, and it’s the reason we ended up building our own tool.
TL;DR — three ways to track lead source in Forminator
1. Native hidden fields. Add a Forminator Hidden field per UTM, set its Default value to Query Parameter. Free and built in, but it only captures what’s in the URL at the moment the form page loads, so it silently misses most of your traffic.
2. JavaScript and cookies. A script reads the UTMs on landing and stashes them in a cookie to survive navigation. More resilient, but it’s fragile, breaks under Safari/ITP, and needs custom code on every site.
3. Server-side capture with Lead Source. Captures UTMs, ad click IDs, referrer and landing page on the visitor’s very first request, stores a first-party record, and attaches it to every Forminator submission automatically — no hidden fields to configure.
Why Forminator doesn’t track lead source by default
Forminator is a genuinely excellent free form plugin from WPMU DEV, and the free version is more than capable for most lead-gen sites. But like almost every form builder, it’s designed to do one job brilliantly: collect what the visitor types into the fields you put in front of them. Nobody types their UTM parameters, and nobody knows which ad they clicked, so that data never reaches the form.
Out of the box, a Forminator submission records exactly what’s in the visible fields plus a timestamp. The campaign, channel and referrer that brought the visitor to your site live in the URL and the browser, not in the form. Unless you go out of your way to capture that context and pass it through, every lead lands in your inbox as an anonymous “someone, from somewhere”. That’s the gap this guide closes.
What “lead source” actually means
“Lead source” is shorthand for the context that explains where a lead came from. It’s made up of a few things: the UTM parameters in the URL (utm_source, utm_medium, utm_campaign, utm_term, utm_content); the ad click IDs the ad platforms append (gclid, fbclid, msclkid and friends); the referrer — the site the visitor arrived from; and the landing page they first hit. Good attribution keeps two views: first touch (the campaign that first introduced them) and last touch (whatever sent them back to convert). Capture all of it and “which campaign produced this lead?” becomes a one-glance answer.
The three methods at a glance
- Method 1 — Native Forminator hidden fields. Zero plugins, free, configured per form. Captures only URL parameters present when the form page loads.
- Method 2 — JavaScript and cookies. Custom code reads UTMs on landing, stores them in a cookie, and writes them into hidden fields. More durable across pages but brittle and ITP-vulnerable.
- Method 3 — Server-side capture with Lead Source. Captures everything on the first request, stores a first-party attribution record, and attaches it to every submission automatically.
Method 1 — Native hidden fields in Forminator
Forminator has a built-in way to pull a value from the URL into a hidden field, and for simple cases it works without a single line of code. Here’s the accurate, current process.
- In WordPress, go to Forminator → Forms and edit the form you want to track.
- Click Insert Fields and add a Hidden field to the form.
- Open the Hidden field’s settings. Find the Default value dropdown and choose Query Parameter.
- In the field that appears, enter the query string key you want to capture — for example
utm_source. Give the field a clear label such as “UTM Source” so it’s recognisable in submissions. - Repeat for each parameter: one Hidden field for
utm_medium, one forutm_campaign,utm_termandutm_content. That’s typically five fields. - If values aren’t coming through, enable Ajax loading in the form settings — several users find the Query Parameter option only fills reliably with Ajax rendering on.
- Save and publish. View captured values under Forminator → Submissions (or via View Submissions from the form’s menu).
Works when: a visitor clicks a tagged link and lands directly on the form page with the UTMs still in the URL, then submits before navigating anywhere. Breaks when: they land on a UTM-tagged blog post, browse to the contact page, and submit there — by then the URL is clean and every hidden field saves blank.
Why hidden fields lose most of your lead source data
This is the part nobody mentions until you’ve already lost a quarter of attribution data, so let’s be blunt about it. Hidden fields read the URL at the instant the form page renders. That single dependency creates four big leaks, and together they swallow the majority of real-world traffic.
- Navigation loss. Most visitors don’t convert on their landing page. They click a tagged ad, read something, then wander to your contact form. The moment they leave the landing URL, the UTMs are gone and the hidden field captures nothing. We dug into this failure in detail in why UTM parameters disappear in WordPress.
- Page caching. Cached HTML is served identically to everyone. A query parameter the field expects to read on the server side can be missing or stale once a CDN or cache plugin is in the path, so values silently fail to populate.
- Safari and ITP. Anything that leans on the browser to carry attribution across pages runs into Intelligent Tracking Prevention, which clamps client-side storage. A big slice of your audience is on Safari or iOS, and that’s exactly where this approach is weakest.
- Organic and direct show blank. Hidden fields only fire when UTMs exist. SEO traffic, a typed URL or a link in an email arrives with no parameters at all — so those leads record an empty source even though their referrer and landing page tell a clear story you never get to see.
The upshot: native hidden fields aren’t wrong, they’re just narrow. They reliably capture the one scenario where someone lands and converts on the same tagged page. For everything else — which is most of your leads — they hand you a blank. That’s the core differentiator that pushes serious advertisers towards Methods 2 and 3.
Method 2 — JavaScript and cookies
The classic fix for navigation loss is a script. On landing, it reads the UTMs from the URL and writes them into a first-party cookie. On any later page, it reads the cookie back and injects the values into Forminator’s hidden fields just before submission, so the data survives the journey from landing page to form.
It’s a real improvement over Method 1 and it’ll capture a lot more leads. But it comes with a tax. You’re maintaining custom JavaScript on every site, and Forminator validates submissions server-side — values injected by client script can be rejected unless you also hook in via PHP, which raises the technical bar considerably. Worse, the whole approach rests on browser storage, and that’s precisely what Safari/ITP is built to limit. Cookies get capped or cleared, and your durable attribution quietly degrades.
Works when: you have a developer to write and maintain the script, your audience skews non-Safari, and you accept some leakage. Breaks when: ITP clears the cookie, a script error stops execution, or the developer who built it moves on and nobody can touch it. If you want the full reasoning, we covered durable capture in how to track lead source in WordPress forms.
Method 3 — server-side capture with Lead Source
Here’s the mechanism, because the mechanism is the point. When a visitor makes their very first request to your WordPress site, the server already has everything it needs — the full URL with its query string, the referring site, and the page being requested. Lead Source reads all of that server-side, on that first request, before any caching layer, browser quirk or page navigation can interfere. It extracts the UTM parameters, the ad click IDs, the referrer and the landing page, and writes them into a first-party attribution record stored in your WordPress database.
From then on, that record follows the visitor. It survives page navigation because it’s no longer riding in the URL. It survives page caching because the capture happens server-side at request time, not in cached HTML. It sidesteps Safari/ITP because it isn’t depending on long-lived browser storage to hold your attribution. And it keeps both first touch and last touch, so you can see the campaign that introduced a lead and the one that closed them.
The part that matters for Forminator specifically: there are no hidden fields to configure. Lead Source hooks the submission save, so the lead source is attached to every Forminator submission automatically. You don’t edit each form, you don’t add five fields per form, and you don’t maintain any script. Install it, and existing forms start carrying attribution. It’s free, it was built in-house by a digital ad agency to solve our own attribution problem, and it captures organic and direct traffic too — referrer and landing page get recorded even when there are no UTMs at all.
What server-side capture still can’t fix
We promised honesty, so here it is. Server-side capture reads what reaches the server. If a parameter is stripped from the URL before the request ever arrives — by a redirect chain that drops the query string, an aggressive privacy proxy, or a link shortener that doesn’t pass parameters through — then nothing on the server can recover what was never sent. No tool can. The fix there is upstream: tag your links properly and audit your redirects so the parameters survive the trip. Once the request reaches WordPress, though, server-side capture is the most reliable option available.
Capturing ad click IDs
UTMs are only half the attribution story. The ad platforms append their own click identifiers, and these are what let you reconcile leads against ad spend and feed conversions back for optimisation. The ones worth capturing are gclid, gbraid and wbraid (Google), fbclid (Meta), msclkid (Microsoft Ads), li_fat_id (LinkedIn) and ttclid (TikTok).
The catch is that you can’t reliably tag click IDs by hand the way you can UTMs — the platforms inject them dynamically at click time, and they’re long, opaque and easy to miss. With native hidden fields you’d need a separate Hidden field for every single click ID, on every form, and they still suffer all the navigation and caching losses above. Lead Source captures the full set server-side on the first request, so a paid lead carries its click ID automatically. We go deeper on this in tracking ad click IDs in WordPress.
Comparing the three methods
| Capability | Hidden fields | JS + cookies | Lead Source (server-side) |
|---|---|---|---|
| Setup effort | Medium (per form) | High (custom code) | Low (install once) |
| Survives navigation | No | Usually | Yes |
| Survives caching | Unreliable | Partial | Yes |
| Beats Safari/ITP | No | No | Yes |
| Captures click IDs | Manual, fragile | Manual, fragile | Yes, automatic |
| First + last touch | No | Partial | Yes |
| Ongoing maintenance | Low | High | None |
| Must edit every form | Yes | Yes | No |
Which method should you use
| Your situation | Best method |
|---|---|
| One landing page, one form, visitors convert on arrival | Native hidden fields |
| You’re testing a single campaign and want a quick free check | Native hidden fields |
| You have a developer and a non-Safari-heavy audience | JavaScript + cookies |
| Multi-page site, blog traffic, leads convert after browsing | Lead Source (server-side) |
| You spend on paid ads and need click IDs reconciled | Lead Source (server-side) |
| Lots of Safari/iOS traffic, or heavy page caching | Lead Source (server-side) |
| Multiple forms and you don’t want to edit each one | Lead Source (server-side) |
| You need both first-touch and last-touch attribution | Lead Source (server-side) |
If your attribution spans more than one click, more than one page, or more than one channel, the choice is fairly clear-cut. We unpack the longer-window thinking in multi-touch attribution and conversion windows.
Setup checklist
- Decide what you actually need to capture: UTMs only, or UTMs plus ad click IDs, referrer and landing page.
- Audit your campaign links — make sure every paid and email link is tagged with consistent UTM values.
- Check your redirects so query strings aren’t being stripped before requests reach WordPress.
- Pick your method using the decision matrix above.
- If going native: add a Hidden field per parameter, set Default value to Query Parameter, and enable Ajax if values don’t fill.
- If going server-side: install Lead Source and submit a test enquiry from a tagged link, then a second from an organic-style visit.
- Verify the data in Forminator → Submissions, including organic and direct leads, before you trust it in reporting.
Frequently asked questions
Does Forminator track UTMs by default?
No. Out of the box Forminator records only what visitors type into visible fields. To capture UTMs natively you must add a Hidden field per parameter and set its Default value to Query Parameter, and even then it only reads the URL at the moment the form page loads.
How do I add a hidden field in Forminator?
Edit your form, click Insert Fields, and add a Hidden field. In its settings, set the Default value dropdown to Query Parameter and enter the URL key you want, such as utm_campaign. Repeat for each parameter, then save. Captured values appear under Forminator → Submissions.
Why are my hidden fields blank?
Almost always because the UTMs weren’t in the URL when the form page loaded. If the visitor navigated away from the tagged landing page first, the parameters are gone. Page caching and Safari/ITP cause the same blanks. Server-side capture avoids this by recording the data on the first request.
How do I track organic and direct leads?
Hidden fields can’t, because there are no UTMs to read. The signal for organic and direct traffic lives in the referrer and landing page, which server-side capture records for every visitor. That’s how Lead Source distinguishes an SEO lead from a typed-URL lead even with no parameters present.
Will this slow down my site?
Server-side capture reads request data that WordPress already has and writes a small first-party record — there’s no extra page weight or blocking script in the browser. It’s lighter than loading third-party tracking JavaScript, and because it doesn’t fight the cache it plays nicely with performance plugins.
Is this GDPR-friendly, and can I send it to my CRM?
The attribution record is first-party and stored in your own WordPress database, not shipped to a third party, which keeps you in control of the data. Because the lead source is attached to the Forminator submission, it flows through whatever integration or export you already use to push enquiries into your CRM. As always, reflect this capture in your privacy policy.
Stop losing the answer to “which campaign produced this lead?”
Native hidden fields are fine for the narrow case where someone lands and converts on the same tagged page. For everything else — browsing visitors, cached pages, Safari users, organic and direct traffic, and paid leads carrying click IDs — they hand you blanks, and a JavaScript-and-cookie workaround just trades one set of fragilities for another.
We built Lead Source because we were tired of staring at anonymous enquiries in client meetings. It captures UTMs, ad click IDs, referrer and landing page server-side on the first request, keeps first and last touch, survives navigation, caching and ITP, and attaches the lead source to every Forminator submission automatically — no hidden fields to configure. It’s free. Install it, send a test enquiry, and the next time a client asks where a lead came from, you’ll already know.

Leave a Reply