How to Set Up UTM Tracking Without Google Analytics
Set up UTM tracking without Google Analytics using cookieless tools, short links, and lightweight analytics. A practical guide for marketers who want clean data.
UTM tracking without Google Analytics sounds like a contradiction. UTM parameters — utm_source, utm_medium, utm_campaign, utm_term, utm_content — were invented by Urchin, the company Google acquired to build Google Analytics. For two decades, the standard setup was: add UTM parameters to your links, install GA, read the campaign reports.
That setup has practical limits. Consent requirements for Google Analytics depend on the configuration and jurisdiction. Ad blockers can block its JavaScript, and Safari's ITP restricts cross-site measurement. Some teams therefore choose a smaller analytics stack.
But the underlying need has not changed: you want to know which campaign drove which traffic. You want to know whether your email newsletter outperformed your Twitter post, whether paid traffic converts better than organic. That is what UTM parameters were designed to answer. The question is how to capture that data without Google Analytics.
This guide gives you three practical approaches, ordered from simplest to most powerful.
What UTM parameters actually do
Before the alternatives, a quick refresh on what UTM parameters are and are not.
UTM parameters are query string values appended to a URL. Example:
https://example.com/landing-page?utm_source=instagram&utm_medium=social&utm_campaign=spring-launch
They do nothing on their own. They are just URL query parameters. No analytics tool invented them — they are plain HTTP. The analytics tool on the destination page reads those parameters from document.location.search (or from the server-side request) and records them.
This means UTM tracking without Google Analytics is completely feasible. You just need a different analytics tool reading those parameters.
What UTM parameters do:
- Tell your analytics tool where traffic came from (
utm_source). - Tell it the marketing channel (
utm_medium). - Tell it which specific campaign drove the visit (
utm_campaign). - Optionally identify the specific ad or link variant (
utm_content,utm_term).
What they do not do:
- Track individual users across sessions (that is cookies, not UTMs).
- Work without an analytics tool reading them.
- Show up in your data if the analytics tool is blocked.
Approach 1: Use a cookieless analytics tool that reads UTMs
The cleanest replacement for GA for UTM tracking is a privacy-first analytics tool designed to read UTM parameters without cookies. The two most widely used are Plausible and Fathom.
Both read UTM parameters from the URL on each page load and associate them with the visit event. Since they are session-based (not cookie-based), they do not track individual users across sessions — but they do record which source/medium/campaign a given visit came from.
How to set this up
Step 1: Install Plausible or Fathom
Add the tracking snippet to your site's <head>. Plausible's snippet:
<script defer data-domain="yourdomain.com" src="https://plausible.io/js/script.js"></script>
Both tools offer self-hosting options if you want full data sovereignty.
Step 2: Build UTM-tagged links as you normally would
Your UTM-tagged links work exactly the same way. Use any UTM builder — Google's own Campaign URL Builder still works for generating the query string even if you are not using GA. Or build the query string manually:
https://yoursite.com/page?utm_source=newsletter&utm_medium=email&utm_campaign=april-2026
Step 3: Read campaign data in the dashboard
Both Plausible and Fathom show UTM breakdowns in their dashboards. You can filter by utm_source, utm_campaign, and utm_medium and see pageview counts, bounce rates, and visit durations segmented by campaign.
Limitations: These tools read UTMs from the destination page's URL. If the visitor's browser strips query parameters on redirect (some do), or if your own site's JavaScript redirects before reading the URL, UTM data can be lost. Use canonical URL handling carefully.
Approach 2: Use a URL shortener to attribute campaign traffic at the link level
This is the approach to use when you want UTM-style attribution without installing any JavaScript on your site — which matters when you do not own the destination (an affiliate product, a third-party booking page, a Gumroad store) or when the destination's analytics are outside your control.
The idea: instead of appending UTM parameters to the destination URL, you create a separate short link for each campaign source. Each link has its own analytics — country, device, and click volume — so you attribute traffic at the link level rather than the page level.
How to set this up with 1URL.at
Step 1: Create a short link for each campaign channel
Say you want to track traffic from your email newsletter versus your Instagram bio versus a Twitter post. You create three short links in 1URL.at, all pointing to the same destination:
1url.at/r/email-april→ your landing page1url.at/r/ig-bio→ your landing page1url.at/r/twitter-april→ your landing page
Step 2: Use the channel-specific link in each channel
Put 1url.at/r/email-april in your newsletter. Put 1url.at/r/ig-bio in your Instagram bio. Put 1url.at/r/twitter-april in your Twitter post.
Step 3: Read the per-link analytics
Each link's analytics page shows clicks and country breakdowns independently. You can compare them directly: "email drove 340 clicks, Instagram bio drove 120, Twitter drove 580." Device reports are on the roadmap.
This works even if you do not have analytics on the destination page. The click is recorded by 1URL.at when the visitor hits the short link — before the redirect fires — so the measurement happens on infrastructure you control.
What this approach captures
The current 1URL.at analytics pipeline captures:
- Click count — total and per-day trend.
- Country — top countries by click volume.
- Device type — classified in the analytics pipeline but not yet shown in the dashboard.
- All-time total — never expires, even after the rolling window ages out.
What it does not currently capture: referrer header or UTM parameters appended to the short link's query string. Referrer and UTM capture are on the roadmap. For now, the attribution is at the link level (which link you shared), not the parameter level (which specific UTM value was passed). This distinction matters if you need sub-campaign granularity; for channel-level attribution, the link-per-channel pattern above is sufficient.
Approach 3: Capture UTMs server-side in your own application
If you run your own server-side application and you want UTM data in your own database — completely independent of any third-party analytics tool — you can read UTM parameters server-side on every request.
How to set this up (Node.js / Express example)
Step 1: Read UTMs from the query string on your landing page route
app.get('/landing', (req, res) => {
const utm = {
source: req.query.utm_source || null,
medium: req.query.utm_medium || null,
campaign: req.query.utm_campaign || null,
content: req.query.utm_content || null,
term: req.query.utm_term || null,
};
// Classify device at ingestion — never store the raw UA. Hash the IP so
// you can count unique visitors without persisting an identifier.
const device = classifyDevice(req.headers['user-agent'] || '');
const visitorHash = await hashVisitor(req.headers['cf-connecting-ip'] || '');
// Log or store the attribution event
db.insert({
page: '/landing',
utm,
country: req.headers['cf-ipcountry'] || null,
device, // 'mobile' | 'tablet' | 'desktop'
visitorHash, // rotates daily; not linkable across days
timestamp: Date.now(),
});
res.render('landing', { /* ... */ });
});
Step 2: Aggregate in your analytics queries
SELECT
utm_source,
utm_campaign,
COUNT(*) AS visits
FROM landing_events
WHERE timestamp >= strftime('%s', 'now', '-30 days') * 1000
GROUP BY utm_source, utm_campaign
ORDER BY visits DESC;
This approach gives you complete data sovereignty — nothing leaves your server. The trade-off is that you are building and maintaining the pipeline yourself.
Note on privacy: Even in a server-side approach, follow the same principles as cookieless tools. Hash the IP address before storing it. Do not store raw user-agent strings if you can derive what you need (device type) at ingestion time. A visitor who hits your landing page should not have their raw IP permanently stored in your attribution database.
Approach 4: Combine short links with UTMs on the destination
These approaches are not mutually exclusive. You can append UTM parameters to the destination URL inside a short link:
Short link: 1url.at/r/email-april
Destination: https://yoursite.com/page?utm_source=email&utm_medium=newsletter&utm_campaign=april-2026
When the visitor clicks the short link:
- 1URL.at records a click with country data; device reporting is on the roadmap.
- The visitor lands on your site with UTM parameters in the URL.
- Your destination analytics tool (Plausible, Fathom, or server-side) reads the UTM parameters.
You get two layers of attribution: link-level data from 1URL.at (no JavaScript required on the destination), and UTM-level data from your destination analytics (requires JS or server-side capture).
This is the most robust setup for serious campaign tracking — you have redundancy if one layer fails.
Choosing the right approach
| Situation | Recommended approach |
|---|---|
| You own the destination site and want UTM reports | Plausible or Fathom on the destination |
| You do not own the destination (affiliate, third-party) | Short links per campaign channel |
| You need full data sovereignty with no third-party tools | Server-side UTM capture |
| You want both link-level and UTM-level data | Short links + UTMs in the destination URL |
Common mistakes
Mistake 1: Using UTM parameters on internal links. UTM parameters should only appear on links that originate from outside your site. If you add them to internal navigation, you reset the session source and corrupt your attribution data. Internal links should never have UTM parameters.
Mistake 2: Inconsistent campaign naming. UTM values are case-sensitive in many tools. utm_source=Email and utm_source=email are two different values. Pick a naming convention (lowercase, underscores for spaces) and stick to it. Inconsistency fragments your campaign data.
Mistake 3: Trusting UTM data as exact. UTM parameters can be stripped by privacy tools, link shorteners (if you are layering multiple), or browser security policies. Treat UTM-based attribution as directional, not forensically precise.
Mistake 4: Forgetting mobile apps. Links clicked inside Instagram or other social apps often fire inside in-app browsers. In-app browsers sometimes modify or strip referrer headers and UTM parameters. Short link analytics (which capture the click before the redirect) are more reliable in this environment than destination page JavaScript.
The bottom line on UTM tracking without Google Analytics
UTM tracking without Google Analytics is not just possible — for many teams, the alternatives are actively better. Cookieless tools are simpler to comply with, harder to block, and easier to reason about.
The three-part stack that works well for most creators and small teams:
- A cookieless analytics tool (Plausible, Fathom, or 1URL.at's built-in analytics) on the destination.
- Short links per campaign channel for link-level attribution.
- UTM parameters in the destination URL for parameter-level attribution when needed.
If you are starting fresh and want the simplest possible setup, start with short links per channel. Add UTMs on the destination if you need sub-campaign granularity. Add a cookieless analytics tool on the destination if you want page-level behaviour data on top of click counts.
Further reading: the complete guide to cookieless analytics walks through fingerprinting, daily-rotating IP hashing, and session-only approaches. It also covers their measurement limits and the legal questions that still need a context-specific review. For the link creation flow end to end, see short link with analytics in under 60 seconds.