Cover photo

cln: strip the tracking, keep the link

Strip the Tracking: Simplifying URLs for a Cleaner Web Experience

Every link you copy is a little dossier. Paste a product URL into a chat and you often ship along utm_source, fbclid, gclid, mc_eid: a trail of who sent what, from which campaign, to whom. None of it is needed for the page to load. All of it follows the click.

cln is a tiny command-line tool that removes that trail. You give it a URL, it strips the known tracking parameters, prints the clean version, and copies it to your clipboard. One word, one clean link.

$ cln 'https://example.com/page?utm_source=nl&utm_medium=email&id=42'
https://example.com/page?id=42
removed: utm_source, utm_medium

The cleaned URL goes to stdout (so it stays pipeable) and to your clipboard (with no stray trailing newline). Anything it stripped is reported on stderr as removed: …, so you can see exactly what was taken out.

Strip the tracking, keep the attribution

The interesting decision in cln is what it doesn't touch.

It removes tracking only: the whole UTM family (anything starting utm_), click IDs (fbclid, gclid, msclkid, igshid, …), email/campaign tokens (mc_eid, mkt_tok, _hsenc, …) and analytics/session junk (_ga, _gl, …).

It deliberately preserves affiliate and referral parameters like tag, ref, partner, irclickid, the Rakuten ran* set, and so on:

$ cln 'https://www.amazon.com/dp/B0XXXX?tag=metaend-21&utm_source=x'
https://www.amazon.com/dp/B0XXXX?tag=metaend-21
removed: utm_source

The tag=metaend-21 affiliate credit survives; the campaign tracker does not. This is intentional. A privacy tool that quietly rewrote or dropped affiliate tags would be doing the Honey thing, siphoning credit behind the user's back. cln never injects, alters, or substitutes attribution. It only ever preserves what's already there. And the default is conservative: anything not explicitly known to be tracking is kept, so a functional or revenue-bearing parameter is never stripped by accident.

Built small on purpose

cln is a single static Go binary with a deliberately minimal trust surface:

  • Standard library only. Zero third-party dependencies. The binary parses the URL with net/url and does string filtering. It links no clipboard, GUI, or networking libraries.

  • No network, ever. It reads a string, cleans it, writes a string. That's it.

  • Clipboard by shell-out. Instead of linking a clipboard library, it shells out to the tool already on your system, detected at runtime: wl-copy / wl-paste on Wayland, xclip or xsel on X11. The same binary works on both.

  • Safe by construction. The clipboard utility is always invoked with an explicit argument vector (never a shell, never string interpolation) and the URL content travels over stdin, never as a command argument. Untrusted clipboard content can't be reinterpreted as a command.

The realistic failure mode for a tool like this is parsing a URL wrong (leaking a param that should be stripped, or mangling a working link), so kept-parameter order and original encoding are preserved exactly, and the behavior is pinned by a table-driven test suite.

Using it

cln <url>     # clean the given URL
cln           # read the URL from the clipboard, clean it, write the result back
cln -h        # usage

Bare cln is the everyday path: copy a messy link from your browser, run cln, paste the clean one.

Install needs a clipboard backend for your display server (wl-clipboard on Wayland, xclip on X11) and a one-line build:

CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o cln .
cp cln ~/.local/bin/cln

…or just make install. The denylist of what counts as "tracking" is a single compiled-in extension point in clean.go: add a param if you decide it's pure tracking, rebuild, done. No config files, no remote rulesets, no daemon.

Source

gourl-cleaner on gitworkshop.dev - MIT licensed.


Built by metaend - verifiable, privacy-first infrastructure.