Link Cleaner: remove UTM tags from URLs
Remove UTM tags, ad click IDs, and common tracking parameters from shared URLs while keeping the real destination intact.
Status: Live · Processing: local/browser-side only. Paste one URL per line, clean the tracking junk, then copy the result. The tool preserves unknown query parameters by default so useful links do not break.
Use it as a URL cleaner for UTM tags, ad click IDs, newsletter IDs, and common social share parameters. It does not open links, fetch destinations, or decide whether a URL is safe. It only rewrites the text you pasted.
Privacy note: this tool runs locally in your browser. URLs you paste here are not sent to CyganLabs, stored in WordPress, or submitted to a server by this page. It only rewrites the text in your browser; it does not open, fetch, scan, or validate the destination.
Paste one URL per line. Fully qualified URLs work best. If something looks like a normal domain without a protocol, the tool will try an https:// fallback and say so. Relative paths such as /page?utm_source=x are treated as invalid because there is no safe destination context.
No URL cleaned yet.
Nothing to clean yet.
(function () { var tool = document.getElementById(‘link-cleaner-tool’); if (!tool) return; var input = tool.querySelector(‘#link-cleaner-input’); var output = tool.querySelector(‘#link-cleaner-output’); var stripHash = tool.querySelector(‘#link-cleaner-strip-hash’); var cleanButton = tool.querySelector(‘#link-cleaner-clean’); var copyButton = tool.querySelector(‘#link-cleaner-copy’); var clearButton = tool.querySelector(‘#link-cleaner-clear’); var removedBox = tool.querySelector(‘#link-cleaner-removed’); var status = tool.querySelector(‘#link-cleaner-status’); var trackingParams = new Set([ ‘utm_source’, ‘utm_medium’, ‘utm_campaign’, ‘utm_term’, ‘utm_content’, ‘utm_id’, ‘fbclid’, ‘gclid’, ‘gbraid’, ‘wbraid’, ‘msclkid’, ‘mc_cid’, ‘mc_eid’, ‘igshid’, ‘mibextid’, ‘si’, ‘yclid’, ‘twclid’, ‘li_fat_id’, ‘_hsenc’, ‘_hsmi’ ]); function shouldRemoveParam(key, value) { var normalizedKey = String(key).toLowerCase(); if (trackingParams.has(normalizedKey)) { return true; } if (normalizedKey === ‘feature’) { var normalizedValue = String(value || ”).toLowerCase(); return normalizedValue === ‘share’ || normalizedValue === ‘shared’ || normalizedValue === ‘sharebutton’; } return false; } function setStatus(message, state) { status.textContent = message; status.setAttribute(‘data-state’, state || ’empty’); } function escapeHtml(value) { return String(value).replace(/[&”]/g, function (char) { return ({ ‘&’: ‘&’, ”: ‘>’, ‘”‘: ‘"’ })[char]; }); } function resetRemovedBox(message) { removedBox.innerHTML = ‘Removed parameters‘ + escapeHtml(message) + ‘
‘; } function looksLikeBareDomain(value) { return /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+(?::d{2,5})?(?:[/?#].*)?$/i.test(value); } function parseInputUrl(value) { var trimmed = value.trim(); if (!trimmed || /^//.test(trimmed)) { return { ok: false, reason: ‘Use a full web URL, not a relative path.’ }; } try { return { ok: true, url: new URL(trimmed), fallback: false }; } catch (error) { if (!looksLikeBareDomain(trimmed)) { return { ok: false, reason: ‘Not a valid URL or bare domain.’ }; } try { return { ok: true, url: new URL(‘https://’ + trimmed), fallback: true }; } catch (fallbackError) { return { ok: false, reason: ‘Could not parse this as a web URL.’ }; } } } function cleanOne(rawValue, lineNumber, shouldStripHash) { var parsed = parseInputUrl(rawValue); if (!parsed.ok) { return { ok: false, line: lineNumber, raw: rawValue, reason: parsed.reason }; } var url = parsed.url; if (url.protocol !== ‘http:’ && url.protocol !== ‘https:’) { return { ok: false, line: lineNumber, raw: rawValue, reason: ‘Only http and https URLs are supported.’ }; } var keptParams = new URLSearchParams(); var removed = []; url.searchParams.forEach(function (value, key) { if (shouldRemoveParam(key, value)) { removed.push({ key: key, value: value }); } else { keptParams.append(key, value); } }); var nextSearch = keptParams.toString(); url.search = nextSearch ? ‘?’ + nextSearch : ”; if (shouldStripHash) { url.hash = ”; } return { ok: true, line: lineNumber, raw: rawValue, cleaned: url.toString(), removed: removed, fallback: parsed.fallback }; } function renderRemoved(results, invalidResults, fallbackResults) { var removedItems = []; results.forEach(function (result) { result.removed.forEach(function (param) { removedItems.push(‘Line ‘ + result.line + ‘: ‘ + param.key + (param.value ? ‘=’ + param.value : ”)); }); }); var html = ‘Removed parameters‘; if (!removedItems.length && !invalidResults.length && !fallbackResults.length) { html += ‘No known tracking parameters removed.
‘; removedBox.innerHTML = html; return; } if (removedItems.length) { html += ‘- ‘ + removedItems.map(function (item) {
return ‘
- ‘ + escapeHtml(item) + ‘ ‘; }).join(”) + ‘
No known tracking parameters removed.
‘; } if (fallbackResults.length) { html += ‘Protocol fallback: added https:// on line’ + (fallbackResults.length === 1 ? ” : ‘s’) + ‘ ‘ + fallbackResults.map(function (item) { return item.line; }).join(‘, ‘) + ‘.
Invalid line’ + (invalidResults.length === 1 ? ” : ‘s’) + ‘: ‘ + invalidResults.map(function (item) { return ‘line ‘ + item.line + ‘ (‘ + item.reason + ‘)’; }).map(escapeHtml).join(‘; ‘) + ‘.
‘; } removedBox.innerHTML = html; } function runCleaner() { var raw = input.value; var lines = raw.split(/r?n/); var hasContent = lines.some(function (line) { return line.trim().length > 0; }); if (!hasContent) { output.value = ”; resetRemovedBox(‘No URL cleaned yet.’); setStatus(‘Nothing to clean yet.’, ’empty’); return; } var validResults = []; var invalidResults = []; var fallbackResults = []; var cleanedLines = []; var removedCount = 0; lines.forEach(function (line, index) { var lineNumber = index + 1; if (!line.trim()) { cleanedLines.push(”); return; } var result = cleanOne(line, lineNumber, stripHash.checked); if (!result.ok) { invalidResults.push(result); cleanedLines.push(”); return; } validResults.push(result); cleanedLines.push(result.cleaned); removedCount += result.removed.length; if (result.fallback) fallbackResults.push(result); }); output.value = cleanedLines.join(‘n’).replace(/n+$/g, ”); renderRemoved(validResults, invalidResults, fallbackResults); if (!validResults.length && invalidResults.length) { setStatus(‘Invalid URL on line ‘ + invalidResults.map(function (item) { return item.line; }).join(‘, ‘) + ‘.’, ‘error’); return; } if (invalidResults.length) { setStatus(‘Cleaned ‘ + validResults.length + ‘ URL(s), but line ‘ + invalidResults.map(function (item) { return item.line; }).join(‘, ‘) + ‘ needs a valid web URL.’, ‘error’); return; } if (!removedCount) { setStatus(fallbackResults.length ? ‘No known tracking parameters found. Added https:// where needed.’ : ‘No known tracking parameters found.’, ‘success’); return; } setStatus(‘Cleaned ‘ + validResults.length + ‘ URL(s) — removed ‘ + removedCount + ‘ tracking parameter(s).’, ‘success’); } function copyOutput() { if (!output.value.trim()) { setStatus(‘Nothing to copy yet.’, ‘error’); return; } function fallbackCopy() { output.focus(); output.select(); try { if (document.execCommand && document.execCommand(‘copy’)) { setStatus(‘Copied cleaned URL(s).’, ‘success’); } else { setStatus(‘Copy blocked by the browser. Select the output and copy it manually.’, ‘error’); } } catch (error) { setStatus(‘Copy blocked by the browser. Select the output and copy it manually.’, ‘error’); } } if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(output.value).then(function () { setStatus(‘Copied cleaned URL(s).’, ‘success’); }).catch(fallbackCopy); } else { fallbackCopy(); } } function clearTool() { input.value = ”; output.value = ”; stripHash.checked = false; resetRemovedBox(‘No URL cleaned yet.’); setStatus(‘Nothing to clean yet.’, ’empty’); input.focus(); } cleanButton.addEventListener(‘click’, runCleaner); copyButton.addEventListener(‘click’, copyOutput); clearButton.addEventListener(‘click’, clearTool); }());This tool needs JavaScript enabled because the cleanup runs in your browser.
When to use this URL cleaner
- Cleaning links before sharing them in docs, tickets, chat, notes, or posts.
- Removing common UTM, campaign, ad-click, newsletter, and social-share identifiers.
- Cleaning a small batch of pasted URLs without sending them to a server.
- Keeping useful query parameters such as IDs, searches, filters, and affiliate tags unless they are known tracking junk.
- Preserving hash fragments like
#sectionby default, with an option to strip them when you mean to.
What it does not do
- It does not check whether a URL is safe, legitimate, reachable, or worth opening.
- It does not fetch destination pages or follow redirects.
- It does not bypass paywalls, logins, affiliate rules, region gates, or content protections.
- It does not remove every query parameter. Unknown parameters stay because many IDs, searches, filters, and affiliate values actually matter.
- It does not store URL history, use third-party scripts, or send pasted URLs to CyganLabs by this page.
Related: Tools, SimpleQR, and Markdown Cleaner.