Skip to content

Instantly share code, notes, and snippets.

@htsign
Last active February 28, 2024 03:20
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save htsign/455bd76d107be1f810c5caa4072c8275 to your computer and use it in GitHub Desktop.
Save htsign/455bd76d107be1f810c5caa4072c8275 to your computer and use it in GitHub Desktop.
remove tracking parameters from current url
// ==UserScript==
// @name TrackingParameterRemover
// @namespace https://htsign.hateblo.jp
// @version 20240215-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_language',
'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',
'_encoding@amazon.*',
'linkCode@amazon.*',
'linkId@amazon.*',
'pd_rd_*@amazon.*',
'psc@amazon.*',
'qid@amazon.*',
'sbo@amazon.*',
'sprefix@amazon.*',
'sr@amazon.*',
'tag@amazon.*',
'mkt_tok@www.amd.com',
'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.*',
'ved@google.*',
'ncid@huffingtonpost.jp',
'fbclid@itmedia.co.jp',
'word_result@nhk.or.jp',
'ref@*.nicovideo.jp',
'ss_id@*.nicovideo.jp',
'ss_pos@*.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',
];
/**
* @param {Location} loc
* @returns {{ url: string, locationChanged: boolean }}
*/
const removeTracking = loc => {
let locationChanged = false;
const escapables = Object.freeze({
'.': '\.',
});
const wildcardCharacters = Object.freeze({
'*': '.*',
'?': '.',
});
const wildcardKeys = Object.keys(wildcardCharacters);
/**
* @param {string} pattern
* @returns {RegExp}
*/
const toRegExp = pattern => {
/**
*
* @param {Record<string, string>} table
* @param {string} s
* @returns {string}
*/
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');
};
/**
*
* @param {string} pattern
* @param {string} s
* @returns {boolean}
*/
const match = (pattern, s) => {
if (wildcardKeys.some(c => pattern.includes(c))) {
return toRegExp(pattern).test(s);
}
return pattern === s;
};
/**
* @param {string} domain
* @param {URLSearchParams} params
* @param {string} pattern
* @returns {string}
*/
const deleteKeys = (domain, params, pattern) => {
if (!domain || loc.hostname.split('.').some((_, i, arr) => match(domain, arr.slice(i).join('.')))) {
for (const key of params.keys()) {
if (match(pattern, key)) {
params.delete(key);
locationChanged = true;
}
}
}
return params.toString().split('%25').join('%');
};
/**
* @param {string} search
* @param {(arg: URLSearchParams) => any} callback
* @returns {void}
*/
const proc = (search, callback) => {
const params = new URLSearchParams(search);
if (params.size === 0) 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