Trace every hop before changing analytics
A campaign link can look correct in your spreadsheet and still arrive at a landing page without its UTM values. A short-link service, a canonical-host redirect, a locale router, or custom application code may change the URL before the analytics tracker runs. The useful question is not whether the first link contains tags; it is whether the final page has the intended tags when its first tracked event is created.
Start with one synthetic campaign link and follow it from the exact place visitors click. Inspect each HTTP Location response and the final browser address. Do this in a private test profile, and use labels with no customer or personal information. Do not paste real recipient-specific email links into public debugging services.
curl -sS -L -D /tmp/redirect-headers.txt -o /dev/null \
-w 'final_url=%{url_effective}\nstatus=%{http_code}\n' \
'https://example.com/go?utm_source=launch-email&utm_medium=email&utm_campaign=november-release'
cat /tmp/redirect-headers.txtThe headers show the redirect chain and the final_url line shows where the request ended. Repeat the check from a browser too: a JavaScript redirect, a client-side router, or a click-tracking page may not behave like a simple server redirect. Keep the output private if the URL contains anything sensitive.
Know which URL WhoVisited actually measures
The current WhoVisited tracker reads utm_source, utm_medium, and utm_campaign from the page URL when it creates a tracked event. It sends the page origin and path, not the query string. The ingestion code extracts the path and stores it as the session landing path; a new session takes its acquisition values from its first accepted event. Later events update last-seen activity but do not replace that session's original landing path, referrer, or campaign fields.
That creates two important cases. If a server redirect reaches the final landing page before the tracker runs, make sure the final URL still has the three campaign values. If the tracker runs on an intermediate page first, it may establish the session there before a later navigation. Do not assume that adding UTM values on a subsequent page will relabel an already-created session.
WhoVisited accepts nonempty values up to 100 characters containing letters, numbers, spaces, underscores, periods, and hyphens. It collects only those three campaign fields. The source report uses utm_source and, when present, utm_medium; campaign is a grouping label. Other UTM parameters are not extra dimensions in this integration.
Preserve approved campaign values deliberately
Next.js has several redirect mechanisms. Its next.config.js redirects pass incoming query values through to the destination by default. Custom code that builds a fresh destination URL must make its query behavior explicit. If you need to retain campaign tags while moving to a known same-site path, allowlist just the supported keys rather than copying every parameter.
const campaignKeys = ["utm_source", "utm_medium", "utm_campaign"];
function campaignDestination(requestUrl) {
const incoming = new URL(requestUrl);
const destination = new URL("/pricing", incoming.origin);
for (const key of campaignKeys) {
const value = incoming.searchParams.get(key);
if (value) destination.searchParams.set(key, value);
}
return destination;
}This helper is only for a destination on the same origin. Validate the incoming request and your redirect rules in the surrounding route; never turn an untrusted query parameter into an arbitrary redirect target. If the page is meant to have a clean URL, you may instead keep the tags only until the tracker has recorded the first event, then remove them. Test that ordering in the real browser before adding cleanup code.
Verify the complete path in a fresh browser session
- Use a new private window or a separate browser profile so an older session cannot supply previous acquisition data.
- Open the exact link visitors will click, including any directory, email, or short-link redirect. Confirm the final page and its query values before the tracker initializes.
- In DevTools Network, check that tracker.js loads and that the bootstrap and event requests are permitted. Consent settings, browser privacy signals, extensions, and CSP can prevent collection independently of redirect behavior.
- Complete one test visit and inspect the corresponding session in WhoVisited. Confirm the landing path and source/campaign values match the synthetic link; do not treat a click on the campaign URL as a conversion.
- Repeat after any redirect or canonical-host change. Test both the tagged route and a normal untagged visit so the fix does not rewrite unrelated navigation.
If the test session already existed, discard it and repeat from a clean context. The Growth source report counts sessions and configured goal sessions; it does not reconstruct every redirect hop or prove that a campaign caused a conversion. Small samples are directional evidence, not a reliable ranking of channels.
Keep campaign tags useful and privacy-safe
Campaign parameters are visible in shared links, browser history, and systems that handle those URLs. Never put names, email addresses, account IDs, access tokens, or other private data in UTM values. WhoVisited strips query strings from stored page paths, but the campaign labels you deliberately add are stored as session attribution fields. Use broad, non-identifying labels such as newsletter or launch-directory.
A clean final URL does not guarantee that every browser records a session: consent choices, privacy signals, blockers, network failures, and the configured origin still matter. Conversely, a missing campaign label does not prove that no one clicked the tagged link; it means the tracker did not record that campaign value on the session's first accepted event.
For the redirect behavior, see the official [Next.js redirects documentation](https://nextjs.org/docs/app/api-reference/config/next-config-js/redirects). For safe query parsing, see MDN's [URLSearchParams reference](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams). The WhoVisited [UTM naming guide](/blog/utm-naming-for-saas-launches) covers consistent labels, while [Unknown source troubleshooting](/blog/why-traffic-source-shows-unknown) explains the limits of referrer data.