UTM Link Builder — JavaScript source
Build campaign tracking URLs with utm_source, utm_medium and utm_campaign parameters. Bulk mode processes a whole list, presets and import round-trip existing tracking URLs, and a validator flags attribution-breaking values — runs entirely in your browser.
This is the JavaScript implementation — the same logic the interactive tool runs, in a shareable, citable form.
/**
* utm-link-builder - campaign URL builder with canonical utm_* ordering.
*
* Display snippet: ports the core build(baseUrl, params) from the
* TypeScript lib (src/lib/utm.ts). The lint/bulk/preset helpers live in
* the TypeScript/Go sources.
*
* Semantics: strip any stale utm_* params from the base URL, keep every
* unrelated query param in place, then append the given params in
* canonical order. Empty-string params are omitted. Returns null for an
* unparseable base. Uses the standard WHATWG URL class only.
*/
const CANONICAL = [
['source', 'utm_source'],
['medium', 'utm_medium'],
['campaign', 'utm_campaign'],
['term', 'utm_term'],
['content', 'utm_content'],
];
/** Parse a base URL, coercing a scheme-less host into https. null when hopeless. */
function parseUrl(base) {
try {
return new URL(base);
} catch {
try {
return new URL('https://' + base);
} catch {
return null;
}
}
}
function build(baseUrl, params = {}) {
const url = parseUrl(baseUrl);
if (!url) return null;
// Collect first, delete after — mutating searchParams during iteration skips entries.
const stale = [];
for (const key of url.searchParams.keys()) {
if (key.startsWith('utm_')) stale.push(key);
}
for (const key of stale) url.searchParams.delete(key);
for (const [field, queryKey] of CANONICAL) {
const value = params[field];
if (value !== undefined && value !== '') url.searchParams.set(queryKey, value);
}
return url.toString();
}
// Example:
// build('example.com/page?utm_source=stale&id=7', { source: 'twitter', medium: 'social' })
// -> 'https://example.com/page?id=7&utm_source=twitter&utm_medium=social'
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →