Your "Direct" bucket is not people typing your URL into the address bar. It is a garbage bin for every visit where the browser declined to tell you where the click came from — and the number of situations where browsers decline has grown steadily for a decade.
This matters more now because the traffic sources people most want to measure, AI assistants and their in-app browsers, sit squarely in the worst part of that distribution. Before you build a dashboard for "AI referrals," you need to know exactly what signal you are counting and what fraction of the real thing it represents.
What the browser actually sends when someone clicks a link
One header: Referer (misspelled in the original spec, still misspelled today). It is set by the client, not by the linking server, and its contents are governed by the Referrer-Policy of the page containing the link — a page you do not control.
Chrome changed its default policy to strict-origin-when-cross-origin in 2020, and other major browsers converged on the same or stricter behavior. That default produces three distinct outcomes:
| Navigation | What you receive in Referer |
|---|---|
| Same-origin link | Full URL including path and query |
| Cross-origin, HTTPS → HTTPS | Origin only: https://example.com/ |
| Cross-origin, HTTPS → HTTP | Nothing |
So for any external referral, the default is origin only. You learn the domain. You do not learn the page, the search query, or the conversation. That is not a bug or a tracking blocker — it is the shipped default in every mainstream browser.
On top of the default, the linking site can tighten further:
Referrer-Policy: no-referreras a response header or<meta name="referrer" content="no-referrer">suppresses the header entirely for every outbound link.rel="noreferrer"on an individual anchor does the same for that link. (rel="noopener"does not affect the referrer; they are commonly confused.)- A redirect hop through the linker's own domain replaces the referrer with the redirector's origin, collapsing many distinct sources into one.
Nothing you deploy on your own site changes any of this. Your Referrer-Policy controls what your pages leak outward, not what arrives.
Where the referrer disappears completely
Origin-only is survivable. Total absence is what wrecks channel reporting, and it happens in predictable places:
- Native apps and in-app webviews. When a link is opened by an app rather than a page, whether a
Refereris attached depends on how that app constructs the navigation. Some assistants' mobile apps pass their domain; some pass nothing; the behavior changes between versions without announcement. - Copy-paste and shared links. A user who copies a cited URL out of an answer and pastes it elsewhere produces a referrer-free hit by definition.
- Protocol downgrade. Still relevant if any part of your site answers on HTTP before redirecting.
- Privacy-hardened browsers and extensions that strip the header outright.
- Server-side fetches that are not visits at all. An assistant retrieving your page to compose an answer is a bot request, not a human, and belongs in a different analysis entirely.
The practical consequence: the gap between "AI assistant sessions" and "sessions where an AI assistant domain appeared in Referer" is real, one-directional, and unknown in size for your site unless you measure it.
Why GA4 and your server logs disagree on the same visit
GA4 does not read the HTTP header at request time. It reads document.referrer in the browser after the tag fires, then applies its own classification. Four things go wrong:
- Tag timing. A client-side router or a consent gate can fire the first event after a same-site navigation, at which point
document.referreris your own domain or empty. - Consent mode and blocking. No tag, no row — but your access log still has the request.
- Channel grouping is a managed list. Google maintains source categories that decide whether a domain counts as Organic Search, Referral, or something else. When a domain is added to or moved within that list, your channel trend shifts with no change in user behavior. Always check Source/Medium before you interpret a channel-level chart.
- Sessionization. A referrer attaches to a session; subsequent direct returns inherit or reset attribution depending on timeout and campaign rules.
Server logs have the opposite failure mode: they see bots, prefetches, and asset requests that are not sessions. Neither is "truth." They answer different questions, and you need both.
Build the measurement from the request, not the report
Capture the raw fields at the edge so you can reclassify later without re-collecting. In nginx:
log_format ref '$time_iso8601 $status $request_uri '
'"$http_referer" "$http_user_agent" '
'"$http_sec_ch_ua" $http_x_forwarded_for';
Then classify each human-looking hit into four buckets rather than two:
- Known origin —
Refererpresent and external. You know the domain, nothing more. - Tagged — a campaign parameter is present on the landing URL. Some assistants and aggregators append one; do not assume which, just inventory the parameters that actually appear in your logs over a month.
- Referrer-free, deep landing — no referrer, landing URL is a deep article or product page with a long path. Humans rarely type these. This is your best proxy for stripped-referrer referrals.
- Referrer-free, shallow landing — homepage or short branded path. Plausibly genuine direct or brand navigation.
The ratio of the third bucket to the second, tracked over time, is the useful number. Its absolute level is noisy; its trend is informative, and it moves when a new no-referrer source starts sending you people.
One more constraint worth stating plainly: Google has said AI Overview performance is included in Search Console's overall Search totals rather than broken out separately. There is no filter that isolates it. Anyone selling you an "AI Overview clicks" number from Search Console is inferring, not reading.
What to do this week
- Pull 30 days of access logs and compute the share of HTML, human-agent hits with an empty
Referer. That is your attribution blind spot, measured rather than guessed. - Split that share by landing-path depth. Deep + referrer-free is the segment to watch.
- Inventory every distinct external referrer origin you received, sorted by volume. Origin-only means the list is short and stable — review it monthly for new entrants.
- Catalogue which campaign parameters arrive unsolicited on your URLs, and make sure your analytics does not discard them.
- Before explaining any channel-level change, confirm the underlying Source/Medium rows moved too. If they did not, the classification changed, not the traffic.
Treat referrer data as a floor on external referrals, never an estimate of them. The distinction decides whether your AI-traffic reporting is a measurement or a story.