Why do leads show as Direct?
Leads show as Direct when the campaign that brought them was lost between the click and the contact record. The usual causes are forms that don't keep UTMs, UTMs lost between pages, untagged links, apps that strip the referrer, redirects that drop parameters and broken CRM field mapping. Tools like Trakt store UTMs in the browser and record each submission with them.
Open your CRM, group your leads by source, and look at the pile marked "Direct." For most B2B teams it's the second- or third-biggest "channel" in the whole database.
Here's the uncomfortable truth: almost none of those people typed your URL from memory. Real direct traffic, someone keying in yourcompany.com unprompted, is rare, and it's mostly people who already know you. What's actually in that bucket is leads from your ads, your emails, your LinkedIn posts, and your content, whose original source got stripped away before it reached the contact record. "Direct" isn't a channel. It's the label your CRM uses when the trail went cold.
And it's expensive, because it distorts every budget decision you make. Your paid campaigns look worse than they are (their conversions leaked into "Direct"), "Direct" looks like a mysteriously productive channel you can't invest in, and you end up cutting the wrong things. The classic version of this: a team kills a paid campaign for "low ROI," not realizing half its conversions were sitting in the Direct pile the whole time.
What Direct actually means in your CRM (and why the source can be blank)
In most CRMs (HubSpot, Salesforce, GoHighLevel), "Direct" is a fallback value. It appears when no UTMs were present at submission, when UTMs were in the URL but no hidden field captured them, when the hidden fields captured them but the CRM mapping dropped them, or when the lead came through a channel that passes no referrer, such as email clients, Slack and messaging apps. A blank lead source has the same root cause; whether you see a blank or "Direct" depends on how your CRM handles missing values.
Google Analytics uses "direct" in a similar way, but it measures sessions, while your CRM's Direct reflects what the form submitted. A large share of Direct leads doesn't mean people typed your URL. It means your forms aren't capturing source data.
Where is your attribution breaking?
Work down this list in order. The first "no" is the link in the chain to fix:
| Check | If the answer is no | Fix |
|---|---|---|
| Do your ad and email links have UTMs? | Nothing exists to capture | Tag the links (reason 3) |
| Do the UTMs survive the redirect to your landing page? | The redirect strips them | Fix the redirect (reason 5) |
| Does your form page have hidden UTM fields? | The form can't submit UTMs | Add hidden fields (reason 1) |
| Do UTMs survive a page change or return visit? | Only single-page visits keep a source | Persist them in a cookie (reason 2) |
| Is UTM data in the form tool's submission log? | The fields aren't capturing it | Fix the hidden fields (reason 1) |
| Is UTM data in the submission log but not in the CRM? | The CRM is dropping it | Fix the field mapping (reason 6) |
Here are the six reasons leads get mislabelled as Direct, worst offender first, and how to fix each.
1. Your forms don't capture the campaign (the big one)
This is the single most common cause. A visitor arrives carrying their campaign in the URL, utm_source=linkedin, utm_campaign=q3-demo, maybe a gclid. They fill out your form. Unless that form has hidden fields that read those values off the URL and submit them with the form, every bit of campaign context is gone the moment they hit "Submit." The CRM gets a name and an email and nothing else, so it defaults them to Direct.
The fix: add five hidden fields to every lead form, utm_source, utm_medium, utm_campaign, utm_content, utm_term, that populate from the URL and write into the contact record. In HubSpot or Marketo, map them to contact properties so they persist. This one change moves the largest chunk of your "Direct" pile into its real channels.
2. The UTMs didn't survive the visit
Even if your form can capture UTMs, it only works if the parameters are still there when the person converts. And real buyers rarely convert on the first page. They click your ad, read a bit, leave, and come back two days later to fill out the form, by which point the URL is clean and the UTMs are long gone. The form captures nothing, and the lead lands as Direct.
The fix: persist the campaign data. On the first visit, write the UTMs into a first-party cookie that lasts around 90 days. On submit, populate the hidden fields from that cookie, not just the current URL. Now a lead who returns a week later still carries the campaign that first brought them in.
3. Untagged links you own ("dark social")
Every time someone shares your link in a Slack message, an email, a DM, or a PDF, and that link has no UTMs on it, the resulting click is invisible, it shows up as Direct. The same happens with your own owned channels if you're sloppy: an email newsletter link without UTMs, a link in your LinkedIn bio, a QR code pointing at a bare URL. You drove that traffic; you just didn't label it.
The fix: tag every link you control with UTMs, and standardise how you do it so the whole team is consistent. This is the part that quietly falls apart the moment one person shares a link the "quick" way, which is why standardised, shareable tracking links across the team matter more than any single UTM.
4. Referrer stripping from apps and secure pages
A lot of "Direct" is actually a technical quirk. When someone clicks a link inside a mobile app (LinkedIn, Instagram, a native email client) or moves from a secure page to a non-secure one, the browser often passes no referrer information at all. Analytics has nothing to attribute the visit to, so it files it under Direct. This is why so much genuinely social and email-driven traffic hides in the Direct bucket.
The fix: don't rely on the referrer, rely on UTMs you control (see #3) plus persistence (see #2). If the campaign data is riding in the URL and getting captured and stored, referrer stripping stops mattering, because you're not depending on the browser to remember where the click came from.
5. Redirects and rebuilds that drop the parameters
Sometimes the UTMs are on the link, but they get eaten in transit. A redirect chain (a shortened link, a /go/ redirect, a forced HTTP-to-HTTPS bounce, a trailing-slash rewrite) can strip query parameters before the visitor lands on the page with the form. The click was tagged; the parameters just didn't make it to the finish line.
The fix: test your actual redirect paths. Click a fully tagged link, follow it all the way to the form, and check whether the UTMs are still in the URL when you arrive. If they vanish after a redirect, fix the redirect to preserve query strings.
6. The CRM field mapping is broken
The form has hidden UTM fields, they read the URL correctly, and the values are submitted. But they never appear on the lead record, because the field isn't mapped to a CRM property, or is mapped to the wrong one.
The fix: find a recent lead that shows as Direct and open its submission in your form tool. If the UTM values are there, the break is the mapping. Map each hidden field to the right property; in HubSpot native forms, hidden fields need explicit mapping to contact properties, and in Zapier, add the UTM fields to the action step.
If you want each submission recorded with its campaign, pre-register for Trakt.
How to tell how bad yours is
You don't have to guess. Two quick checks:
First, in your CRM, pull the share of leads (and, more importantly, closed-won deals) tagged Direct, "none," or empty. A large share usually means a capture leak, not a loyal audience.
Second, audit the site itself: whether your forms capture and keep source data at all. The free attribution audit scores this for you, or run this manual checklist right now:
The 6-point attribution leak checklist
Run through these checks on your own site:
- Visit your main landing page with
?utm_source=teston the end of the URL. Are the UTMs still there after the page loads, or did a redirect strip them? - Right-click your lead form and Inspect. Look for
<input type="hidden">fields with names likeutm_source,utm_medium,utm_campaign. If they're missing, your forms aren't capturing anything. - Check if those hidden fields are reading from the URL. Fill out the form with the
?utm_source=testURL still loaded. Does "test" show up in the form submission in your CRM or form tool? - Navigate to a different page, then go back to the form. Are the UTMs gone? If yes, you're only capturing single-session conversions, most multi-day leads will show as Direct.
- Check your CRM field mapping. Open a recent lead that shows as Direct. Does your form tool's submission log show UTM values that didn't make it to the CRM? If yes, the problem is in the field mapping, not the form.
- Look for gclid and fbclid capture. These are the click IDs from Google and Meta. Without them, you can't reconcile CRM conversions back to ad platforms, and you're missing the signal that makes Smart Bidding learn from real deals.
If you failed more than two, a big part of your "Direct" bucket is misattributed traffic. The deeper mechanics are in our guide on tracking the Facebook Pixel end to end, which walks through the same hidden-field-and-cookie setup that fixes reasons #1 and #2.
Shrinking "Direct" for good
Every fix above comes down to the same principle: don't let the campaign live only in the URL, because the URL is fragile. Capture it onto the lead the moment they convert, keep it there through the visit, and tag everything you own. Do that, and "Direct" shrinks back down to what it should be, a small slice of people who genuinely already knew you, while your ads, email, and social finally get credited for the pipeline they've been quietly producing all along.
That capture-and-keep work is exactly what Trakt automates. It scans your site, injects the hidden source fields into your existing forms, persists the UTMs in a first-party cookie, and writes the campaign onto the lead at submit. With CRM sync, leads arrive in your CRM attributed instead of defaulting to Direct, and the leads-by-source overview shows the result. No per-form developer tickets.
Manual fixes vs. Trakt, by requirement
| Requirement | Manual | Trakt |
|---|---|---|
| Hidden UTM fields on forms | Configured by hand, one form at a time | Injected into every form it finds |
| UTMs across pages and return visits | Your own cookie logic | First-party cookie |
| Source in the CRM | Map each field | CRM sync |
| UTMs on the links you send | Same either way | Same either way |
The tagging part starts earlier: every tracking link your team creates. Standardise your naming conventions so one person's utm_source=facebook doesn't split from another's utm_source=fb in your reports. Consistent tracking links mean consistent attribution in your CRM.
FAQ
Does Direct traffic mean someone typed my URL directly?
Rarely. A small amount is genuine, but most "Direct" is misattributed traffic, leads from ads, email, or social whose source was stripped before it reached your CRM, usually because the form didn't capture it or the UTMs didn't persist.
Why are my paid leads showing up as Direct?
Almost always because the campaign data didn't make it onto the contact record: no hidden UTM fields on the form, UTMs that don't persist across the visit, or a redirect that drops the parameters. The click was tagged; the capture failed.
How do I reduce Direct traffic in HubSpot or Salesforce?
Add hidden UTM fields to your forms and map them to contact properties, persist UTMs in a first-party cookie so returning visitors keep their source, and tag every link you own. That combination moves most of the "Direct" pile into its real channels.
Why is the lead source blank in my CRM?
A blank lead source has the same cause as a Direct one: the form submitted no source data. Check whether your links carry UTMs, whether the form has hidden fields that read them, and whether those fields are mapped to CRM properties. The submission log in your form tool shows whether the break is before or after the form.
Do redirects and URL shorteners strip UTM parameters?
They can. A redirect that preserves the query string keeps UTMs intact, but some shorteners and custom Apache or Nginx rules drop them. Click your real ad link and watch the full URL through every redirect to confirm.


