# cln: strip the tracking, keep the link

*Strip the Tracking: Simplifying URLs for a Cleaner Web Experience*

By [MetaEnd](https://paragraph.com/@metaend) · 2026-06-18

privacy, go, cli, gourl-cleaner, cln

---

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](https://gitworkshop.dev/ngmi@zaps.lol/gourl-cleaner) [gitworkshop.dev](http://gitworkshop.dev) - MIT licensed.

* * *

_Built by_ [_metaend_](https://metaend.qstorage.quilibrium.com/) _- verifiable, privacy-first infrastructure._

---

*Originally published on [MetaEnd](https://paragraph.com/@metaend/cln-strip-tracking-keep-the-link)*
