A small browser extension (Chrome MV3, also Firefox MV3) that strips tracking parameters and other URL clutter from shopping, travel, and social-media pages — so the URL you copy or share is the clean canonical form.
No analytics. No telemetry. No remote calls.
Four ways to get a clean link: URLs on supported sites are rewritten in place as you browse; right-click any link or page and choose "Copy clean URL"; press Ctrl+Shift+L (Cmd+Shift+L on Mac) to copy a clean URL of the current page; and clicking a link wrapped by a click-tracker, social outbound wrapper, affiliate wrapper, or AMP viewer lands straight on the real destination ("Skip redirect pages", on by default — Outlook SafeLinks is deliberately left alone so corporate click-time scanning keeps working). The toolbar popup also previews the current page's cleaned URL with a one-click copy button, and has a filter box for finding a site among the 266 toggles.
Two hundred eighty-four (266 toggles), organized by world region and type in the popup:
- Global — Search & productivity: Google Search, Google Maps, Google Drive/Docs, Bing, DuckDuckGo, Weather.com, AccuWeather, Weather Underground, Ecosia, Startpage, Brave Search, Kagi · Academic: PubMed, Google Scholar, ResearchGate · App stores: Google Play, Apple App Store · Package tracking: UPS, FedEx, USPS, DHL · Shopping: Amazon, eBay, Etsy, AliExpress, Temu, Wayfair, SHEIN, Samsung, Costco, Home Depot, Lowe's, IKEA, Nike, Adidas, Shopify stores (myshopify.com), Noon, Jumia, Poshmark, Depop, StockX, GOAT, Grailed · Local: Yelp · Real estate & jobs: Zillow, Redfin, Realtor.com, Indeed, Glassdoor · Travel & navigation: Booking.com, Expedia, Airbnb, Agoda, Trip.com, Hotels.com, Vrbo, Tripadvisor, Waze · Flights: Kayak, Skyscanner, Google Flights, FlightAware, Flightradar24, plus one Airlines toggle covering 12 carriers (Delta, United, American, Southwest, JetBlue, Alaska, Ryanair, easyJet, Lufthansa, British Airways, Emirates, Qatar) · Social: Facebook, Instagram, Threads, LinkedIn, Twitter/X, TikTok, Reddit, Bluesky, Pinterest · Media & entertainment: YouTube, Spotify, Twitch, SoundCloud, Apple Music, Steam, IMDb, Goodreads, Wikipedia, Stack Overflow, GitHub, Medium, Quora, Substack, Bandcamp, Letterboxd, Netflix, Prime Video, Roblox, Fandom, Bilibili, Epic Games, GOG, Humble Bundle, itch.io, Product Hunt, Vimeo, Dailymotion, Rotten Tomatoes, Metacritic, Genius, Discogs, Deezer, TIDAL, Pandora, Rumble, Kick, Crunchyroll, Odysee, MyAnimeList, BitChute, Newgrounds · Design & creative: Behance, Dribbble, ArtStation, Flickr, Unsplash, Pexels, DeviantArt, pixiv, Pixabay, Shutterstock, Getty Images, Freepik, GIPHY, Tenor, VSCO, SmugMug, Adobe Stock, Alamy, Vecteezy, iStock, Dreamstime, Imgur · Work tools: NetSuite, Jira & Confluence, Notion, Loom, Figma, GoDaddy, GitLab, Bitbucket, npm, PyPI, Docker Hub, Hugging Face, Kaggle, Dropbox, Box, WeTransfer, MediaFire · Learning: Coursera, Udemy, Khan Academy, edX, Skillshare, Brilliant · Community & events: Kickstarter, GoFundMe, Patreon, Meetup, Eventbrite, Change.org · Food & recipes: AllRecipes, Serious Eats, Food Network, BBC Good Food · Sports: ESPN, Flashscore, Sofascore
- Americas — Shopping: Walmart, Target, Mercado Libre, Best Buy, Americanas, Magalu
- Asia-Pacific — Shopping: Shopee, Lazada, Tokopedia, Coupang, Flipkart, Mercari, Rakuten, Meesho, Carousell, Taobao/Tmall, JD.com · Search & portals: Naver, Yahoo! Japan Search, Daum · Social & knowledge: Zhihu, Weibo, Niconico · More shopping: Gmarket, 11st, Myntra, Daraz · Food: Zomato, Swiggy
- Europe — Shopping: Vinted, Allegro, Leboncoin, OLX, Wallapop, Marktplaats, Kleinanzeigen, Zalando, Bol.com, OTTO, MediaMarkt, Cdiscount, Fnac, Trendyol, Hepsiburada, Wildberries, Ozon, Avito
- News outlets (52, each with its own toggle) — grouped Americas / Europe / Asia-Pacific / Middle East & Africa / Global agencies in the popup; includes the major dailies, broadcasters, and wire services of every region plus Japan's biggest news portal
Plus an opt-in Universal tracking strip mode that strips well-known
tracking parameters (utm_*, gclid, fbclid, mc_cid, igshid,
msclkid, etc.) from URLs on every site you visit, and an opt-in
Active strip ("Block trackers before they load") that removes the
same parameters from page navigations at the network layer — before the
request leaves the browser, so the destination never receives them.
Both off by default.
Long product URLs become the canonical short form the moment the page loads:
https://www.amazon.com/Some-Long-Title-Slug/dp/B08N5WRWNW/ref=sr_1_3?keywords=...&qid=1234
↓
https://www.amazon.com/dp/B08N5WRWNW
Right-click any product link on the page and "Copy link address" — you
get the clean URL too, because in-page anchor hrefs are also rewritten
in place (a MutationObserver keeps up with carousels, search pagination,
and SPA transitions). The reviews list (/product-reviews/<ASIN>) and
third-party sellers (/gp/offer-listing/<ASIN>) keep their path and
preserve filter/sort/pagination params so links like "See 5-star
reviews" still work. Optional toggle to keep the human-readable title
slug in URLs (/<slug>/dp/<ASIN> instead of bare /dp/<ASIN>). All 21
regional storefronts are supported.
Item / listing URLs collapse to the canonical short form. eBay's ?var=
variation selector is preserved (a var=0 "no variation" sentinel is
dropped). Etsy preserves the slug and locale prefix.
Address-bar URLs are auto-cleaned on listing pages — dates + occupancy are kept, everything else (tracking, session, search-id, impression params) is stripped. A small floating toolbar appears in the top-left with two copy buttons:
- Share Property / Share Listing — copies the bare listing URL.
- With Dates — copies the listing URL with check-in/check-out preserved. Disabled until you pick dates.
The toolbar lives in a closed Shadow DOM so the host site's CSS can't touch it. It auto-hides on phone-sized viewports (under 600px wide) and can be hidden entirely via a popup toggle.
Facebook, Instagram, Threads, LinkedIn, YouTube, Twitter/X, TikTok, Reddit, Pinterest, Spotify, Bluesky, GitHub, Medium, Quora, Substack
Address-bar URLs cleaned in place. Each site has its own rules for which query parameters are meaningful and which are tracking:
- YouTube keeps
?v=,?t=(timestamp),?list=and?index=(playlist context + position); dropssi,pp,feature,ab_channel,utm_*. - Spotify keeps
?t=(podcast moment-share) and?context=(queue continuity) on/track/and/episode/, and?theme=on/embed/forms; strips everything else. - Medium keeps
?sk=— the Friend Link share key that lets non-members read a paywalled story — and strips thesource=attribution junk. - GitHub cleans issue / PR / discussion / commit / release-tag
permalinks (dropping
notification_referrer_idand friends) while leaving functional routes like file views and?tab=pages alone. Hash deep-links (#issuecomment-...) are preserved. - Reddit cleans post permalinks, the new
/r/<sub>/s/<short>form, user-profile permalinks, and subreddit front pages (keeping?sort=and?t=); preservesold.reddit.com,np.reddit.com, and other intentional subdomains. - Facebook handles posts, photos, videos, reels, groups, events,
marketplace items,
/watch?v=,/photo.php,/permalink.php,fb.watchshort links. - TikTok handles
/@user/video/,/@user/photo/,/t/,/share/video/, plusvm.tiktok.comandvt.tiktok.comshorts. - And so on — see each site's module in
src/for the full rules.
URL hash fragments (#customerReviews, #aplus, #section, etc.) are
preserved across all sites so in-page anchor links keep working as
intended.
The popup shows the current page's cleaned URL with a diff of what was
removed (strikethrough chips per parameter; "Copy original URL" brings
the pre-rewrite form back), copies in rich formats (Markdown, HTML link
with both clipboard flavors, title + URL), and renders the clean link as
a QR code -- generated by a dependency-free offline encoder pinned by
tests to the python-qrcode reference implementation's output. A footer
link opens the bulk cleaner: paste any text and every URL inside is
unwrapped and cleaned in one pass. A local stats line (URLs cleaned,
characters removed) is counted in chrome.storage.local only -- never
synced, never sent. Advanced settings adds stats detail with reset, and
settings export/import as JSON. The whole UI ships in ten languages
(en, de, fr, es, pt-BR, tr, ru, ja, ko, zh-CN) via _locales.
A single toggle in the popup. When you turn it on, the browser asks you
to grant access to all websites — this is the standard MV3 permission
prompt for a content script that runs on every page. Once granted, the
extension strips a fixed allowlist of cross-site tracking parameters
(see src/utm.js for the full list) from URLs on every http(s) page.
It still reads only the URL — never page content — and still makes zero
network requests.
A second toggle beneath it. The Universal strip cleans the address bar
after the page arrives; this one removes the same parameters from the
navigation before the request is sent, via a declarativeNetRequest
dynamic rule (src/dnr.js builds it from the same src/utm.js
denylist). The destination site never receives the tracking params at
all. It rides the same optional all-sites permission (requested when you
enable either strip, handed back when both are off), honors the same
skip-domains and keep-params lists, and applies only to top-level
navigations — never subframes, API calls, or other subresources. When it
fires, the popup credits it ("Blocked N trackers before this page
loaded") and a counter appears under Advanced → Stats.
Both strips are gated on the master "Shorten All Links" toggle, so flipping the master off stops them too. You can revoke the broad permission at any time from your browser's extension management page; the toggle will auto-untoggle in sync.
Rather's Link Shortener on the Chrome Web Store.
Rather's Link Shortener on AMO.
- Clone or download this repo.
- Open
chrome://extensions(orabout:debuggingin Firefox). - Toggle Developer mode in the top right (Chrome) or click This Firefox (Firefox).
- Click Load unpacked (Chrome) / Load Temporary Add-on…
(Firefox) and pick this folder (Chrome) or the .xpi file from
dist/(Firefox).
Each supported site has a pure-function URL module under src/
(asin.js, ebay.js, youtube.js, …). Each exports is<Site>Host(),
shortenUrl(), needsShortening(), and a STORAGE_KEY constant.
Dependency-free, runs in three contexts: classic content script,
service-worker importScripts, and Node require() for unit tests.
For Amazon, a dedicated content script (src/content.js) handles both
address-bar rewriting and in-page anchor href rewriting, with a
MutationObserver for SPA carousels and pagination. For the four hotel
sites, a shared site-toolbar.js handles the floating-toolbar UI in a
closed Shadow DOM. For all twelve other sites, a shared
src/social-content.js dispatcher picks up whichever per-site
*LinkShortener global is loaded and uses its STORAGE_KEY to gate
the cleanup.
src/utm.js is a pure function that takes a URL and returns the same
URL with universal tracking parameters stripped. src/utm-content.js
is the content script that uses it, registered dynamically by
background.js (chrome.scripting.registerContentScripts) when the
enabledUtmStrip storage flag is true AND the *://*/* host permission
is granted.
src/background.js runs as a service worker in Chrome (and as an
event-page script in Firefox via the background.scripts fallback the
build script injects). It watches chrome.webNavigation events on every
per-site host and pings the content script on history-state updates so
SPA transitions get picked up. It also keeps the toolbar badge in sync
with the master toggle (empty when on, red "OFF" when off), reloads
matching tabs on extension update, and handles the dynamic UTM content
script registration described above.
2902 unit tests across 77 modules, runnable with plain Node. From the repo root:
node tests/asin.test.js
node tests/agoda.test.js
# ...etc
Or loop them:
for f in tests/*.test.js; do node "$f"; doneA Web-Store / AMO ready zip + xpi:
# macOS / Linux
bash package.sh
# Windows
.\package.ps1Both scripts parse-check every src/*.js with node --check before
staging — a truncated or malformed source file aborts the build. The
output goes to dist/link-shortener-<version>.zip (Chrome) and
dist/link-shortener-<version>.xpi (Firefox).
A pre-commit hook mirroring CI (parse-check + NUL-byte scan + full test
run) lives at scripts/pre-commit. Install it once per clone:
cp scripts/pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit| Permission | Why |
|---|---|
| Host access on supported sites | For per-site content scripts to read and rewrite the page's URL, and on hotel sites, inject the toolbar. |
webNavigation |
Detect in-page navigations (pushState) so SPA transitions also get handled. |
storage |
Remember your toggle preferences across browser restarts (chrome.storage.sync). |
scripting |
Dynamically register the Universal tracking strip content script when you enable it. |
declarativeNetRequestWithHostAccess |
The Active strip's dynamic rule (strip params before the request goes out). Acts only on hosts covered by the optional grant below, so it is inert until you opt in. |
Optional: access to all sites (*://*/*) |
Only requested if you enable the Universal tracking strip or "Block trackers before they load" in the popup; handed back when both are off. |
The extension does not request tabs, cookies, webRequest, or any
broader permission.
MIT — see LICENSE.