Skip to content

Instantly share code, notes, and snippets.

@htsign
Last active February 24, 2023 10:05
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?
remove tracking parameters from current url
// ==UserScript==
// @name TrackingParameterRemover
// @namespace https://htsign.hateblo.jp
// @version 20220317-rev1
// @description remove tracking parameters
// @author htsign
// @match *://*/*
// @run-at document-start
// @grant none
// @updateURL https://gist.github.com/htsign/455bd76d107be1f810c5caa4072c8275/raw/TrackingParameterRemover.user.js
// @downloadURL https://gist.github.com/htsign/455bd76d107be1f810c5caa4072c8275/raw/TrackingParameterRemover.user.js
// ==/UserScript==
(function() {
'use strict';
const TRACKING_TAGS = [
'#?utm_campaign',
'#?utm_content',
'#?utm_int',
'#?utm_medium',
'#?utm_source',
'_hsmi',
'_openstat',
'action_object_map',
'action_ref_map',
'action_type_map',
'fb_action_ids',
'fb_action_types',
'fb_ref',
'fb_source',
'ga_campaign',
'ga_content',
'ga_medium',
'ga_place',
'ga_source',
'ga_term',
'gs_l',
'guccounter',
'guce_referrer',
'guce_referrer_sig',
'gws_rd',
'hmb_campaign',
'hmb_medium',
'hmb_source',
'ref_src',
'ref_url',
'utm_campaign',
'utm_cid',
'utm_content',
'utm_int',
'utm_medium',
'utm_name',
'utm_place',
'utm_pubreferrer',
'utm_reader',
'utm_source',
'utm_swu',
'utm_term',
'utm_userid',
'utm_viz_id',
'yclid',
'cx_part@www.afpbb.com',
'pd_rd_*@amazon.*',
'_encoding@amazon.*',
'psc@amazon.*',
'rm@digital.asahi.com',
'iref@www.asahi.com',
'ref@www.asahi.com',
'spJobID@www.asahi.com',
'spMailingID@www.asahi.com',
'spReportId@www.asahi.com',
'spUserID@www.asahi.com',
'callback@bilibili.com',
'cvid@bing.com',
'form@bing.com',
'pq@bing.com',
'qs@bing.com',
'sc@bing.com',
'sk@bing.com',
'sp@bing.com',
'algorithm@www.change.org',
'grid_position@www.change.org',
'algorithm@www.change.org',
'grid_position@www.change.org',
'j@www.change.org',
'jb@www.change.org',
'l@www.change.org',
'mid@www.change.org',
'original_footer_petition_id@www.change.org',
'placement@www.change.org',
'pt@www.change.org',
'sfmc_sub@www.change.org',
'source_location@www.change.org',
'u@www.change.org',
'bi?@google.*',
'client@google.*',
'dpr@google.*',
'ei@google.*',
'gws_rd@google.*',
'oq@google.*',
'sa@google.*',
'sei@google.*',
'source@google.*',
'tbm@google.*',
'ved@google.*',
'ncid@huffingtonpost.jp',
'fbclid@itmedia.co.jp',
'word_result@nhk.or.jp',
'ref@*.nicovideo.jp',
'news_ref@news.nicovideo.jp',
'n_cid@nikkeibp.co.jp',
'n_cid@nikkei.com',
'position@sourceforge.net',
'source@sourceforge.net',
'feature@youtube.com',
'gclid@youtube.com',
'kw@youtube.com',
];
const removeTracking = loc => {
let locationChanged = false;
const escapables = Object.freeze({
'.': '\.',
});
const wildcardCharacters = Object.freeze({
'*': '.*',
'?': '.',
});
const wildcardKeys = Object.keys(wildcardCharacters);
const toRegExp = pattern => {
const replace = (table, s) => Object.entries(table).reduce((acc, [f, t]) => acc.split(f).join(t), s);
const sanitized = replace(escapables, pattern);
const inner = replace(wildcardCharacters, sanitized);
return new RegExp('^' + inner + '$', 'i');
};
const match = (pattern, s) => {
if (wildcardKeys.some(c => pattern.includes(c))) {
return toRegExp(pattern).test(s);
}
return pattern === s;
};
const deleteKeys = (domain, params, pattern) => {
if (!domain || loc.hostname.split('.').some((_, i, arr) => match(arr.slice(i).join('.'), domain))) {
for (const key of params.keys()) {
if (match(pattern, key)) {
params.delete(key);
locationChanged = true;
}
}
}
return params.toString().split('%25').join('%');
};
const proc = (search, callback) => {
const params = new URLSearchParams(search);
if ([...params.values()].join('') === '') return;
callback(params);
};
const url = new URL(loc);
url.search = url.search.split('%25').join('\0'); // avoid to escape of original '%25'
TRACKING_TAGS.forEach(tag => {
const [t, domain] = tag.split('@');
if (t.startsWith('#?')) {
proc(url.hash.slice(1), params => {
url.hash = deleteKeys(domain, params, t.slice(2));
});
}
else {
if (!url.search) return;
proc(url.search.slice(1).replace(/%(?!25)/g, '%25'), params => {
url.search = deleteKeys(domain, params, t);
});
}
});
url.search = url.search.split('%00').join('%25'); // restore original '%25'
return { url: url.href, locationChanged };
};
const { url, locationChanged } = removeTracking(location);
if (locationChanged) {
console.info(`TrackingParameterRemover: {${location.href}} => {${url}}`);
location.replace(url);
}
}());
@Korb
Copy link

Korb commented Feb 24, 2023

The script does not work with links pasted by the Augmented Steam add-on. Links like https://steamdb.info/app/.../?utm_source=Steam&utm_medium=Steam&utm_campaign=SteamDB%20Extension and https://pcgamingwiki.com/api/appid.php?appid=...&utm_source=Steam&utm_medium=Steam&utm_campaign=SteamDB%20Extension remain unchanged. Mozilla Firefox 111.0b5 (64-bit), Tampermonkey 4.18.1 (January 17, 2023).

@htsign
Copy link
Author

htsign commented Feb 24, 2023

@Korb Thanks for your report.
I tried that, but not working as you said. It seems not other userscripts with @include * don't work in this situation too, so probrems are on AugmentedSteam or TamperMonkey side, maybe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment