Skip to content

Instantly share code, notes, and snippets.

@examosa
Last active January 8, 2026 15:42
Show Gist options
  • Select an option

  • Save examosa/50eb28bc16a006b62b3f43893ab457e7 to your computer and use it in GitHub Desktop.

Select an option

Save examosa/50eb28bc16a006b62b3f43893ab457e7 to your computer and use it in GitHub Desktop.
Userscripts
const gh = (path) => new URL(path, 'https://nobsdelivr.private.coffee/gh');
const getJson = (url) =>
fetch(url, { headers: { Accept: "application/json" } })
.then((response) => response.json())
.catch((error) => {
console.error(error);
});
async function fetchInstances() {
const targetTypes = [
'anonymousoverflow',
'breezewiki',
'dumb',
'eddrit',
'intellectual',
'invidious',
'libmedium',
'nerdsfornerds',
'neuters',
'nitter',
'photon-reddit',
'priviblur',
'quetre',
'redlib',
'ruraldictionary',
'scribe',
];
const instances = targetTypes.reduce((out, type) => {
out[type] = [];
return out;
}, Object.create(null));
const providers = {
libredirect: {
source: 'libredirect/instances/data.json',
normalize: (result) =>
Object.entries(result).map(([name, instances]) => ({
type: name.toLowerCase(),
instances: instances.clearnet,
})),
},
farside: {
source: 'benbusby/farside/services.json',
normalize: (result) =>
result.map((service) => ({
type: service.type,
instances: service.instances
.filter((instance) => !instance.endsWith('.onion'))
.concat(service.fallback),
})),
},
fastside: {
source: 'cofob/fastside/services.json',
normalize: (result) =>
result.services.map((service) => ({
type: service.type,
instances: service.instances
.filter((instance) => instance.tags.includes('clearnet'))
.map((instance) => instance.url),
})),
},
};
const promises = Object.values(providers).map(async (provider) => {
const result = await getJson(gh(provider.source));
if (!result) {
return [];
}
return provider.normalize(result);
});
const sources = await Promise.all(promises);
for (const source of sources.flat()) {
if (!(source.type in instances)) continue;
const list = instances[source.type];
for (const instance of source.instances) {
const { href } = new URL(instance);
if (!list.includes(href)) {
list.push(href);
list.sort();
}
}
}
return instances;
}
async function testBackups() {
const backups = [
'https://api.npoint.io/6ee2cb1b5a1aa6f10be5',
];
const results = await Promise.all(backups.map((backup) => getJson(backup)));
for (const index of results.keys()) {
const result = results[index];
if (!result) {
const backup = backups[index];
console.warn(`Stale backup: ${backup}`);
}
}
}
// ==UserScript==
// @name Shortside
// @version 1.5.1
// @description Redirects the configured websites to third-party privacy-respecting front ends.
// @author examosa
// @license AGPLv3-or-later
// @homepageURL https://gist.github.com/examosa/50eb28bc16a006b62b3f43893ab457e7/
// @updateURL https://gist.github.com/examosa/50eb28bc16a006b62b3f43893ab457e7/raw/shortside.user.js
// @downloadURL https://gist.github.com/examosa/50eb28bc16a006b62b3f43893ab457e7/raw/shortside.user.js
// @icon https://nobsdelivr.private.coffee/gh/webalys-hq/streamline-vectors/plump/gradient/interface-essential/shuffle.svg
// @match https://www.fandom.com/*
// @match https://www.geeksforgeeks.org/*
// @match https://genius.com/*
// @match https://www.instagram.com/*
// @match https://www.medium.com/*
// @match https://medium.com/*
// @match https://stackoverflow.com/*
// @match https://www.reddit.com/*
// @match https://*.youtube.com/*
// @match https://www.quora.com/*
// @match https://www.reuters.com/*
// @match https://www.tumblr.com/*
// @match https://twitter.com/*
// @match https://www.urbandictionary.com/*
// @match https://x.com/*
// @run-at document-start
// @allFrames false
// @noframes
// ==/UserScript==
stop();
function getRedirect() {
const assignUrl = (url, updates) =>
Object.assign(url, {
pathname: '/',
search: '',
...updates,
});
const chooseRandom = (target) => {
const list = Array.isArray(target) ? target : Object.values(target);
return list.at(Math.floor(Math.random() * list.length));
};
const hashPath =
(...hostnames) =>
(url) => {
const [hostname, pathname = '/'] = chooseRandom(hostnames).split('/');
assignUrl(url, {
hostname,
pathname,
hash: url.pathname.slice(1),
});
};
const isFunction = (input) => typeof input === 'function';
const replacements = {
fandom: {
breezewiki: [
'breezewiki.com',
'antifandom.com',
'breezewiki.pussthecat.org',
'bw.projectsegfau.lt',
'breeze.hostux.net',
'bw.artemislena.eu',
'breeze.nohost.network',
'breeze.whateveritworks.org',
'z.opnxng.com',
'breezewiki.hyperreal.coffee',
'breezewiki.catsarch.com',
'breeze.mint.lgbt',
'breezewiki.nadeko.net',
'fandom.reallyaweso.me',
'breezewiki.r4fo.com',
'breezewiki.private.coffee',
'fan.blitzw.in',
'antifandom.com',
'breezewiki.com',
'breezewiki.nadeko.net',
'breezewiki.pussthecat.org',
'bw.projectsegfau.lt',
],
},
geeksforgeeks: {
ducksforducks: ['ducksforducks.private.coffee'],
nerdsfornerds: ['nn.vern.cc'],
},
genius: {
dumb: [
'dm.vern.cc',
'dumb.lunar.icu',
'dumb.ducks.party',
'dumb.hyperreal.coffee',
'dumb.bloat.cat',
'dumb.jeikobu.net',
'dumb.canine.tools',
'lyr.dc09.ru',
'db.kuuro.net',
'dumb.ducks.party',
'dumb.lunar.icu',
],
intellectual: [
'in.bloat.cat',
'intellectual.catsarch.com',
'intellectual.insprill.net',
],
},
instagram: {
kittygram(url) {
assignUrl(url, {
hostname: 'kittygram.fsky.io',
pathname: url.pathname.replace('/reel/', '/p/'),
});
},
},
medium: {
libmedium: [
'libmedium.batsense.net',
'md.vern.cc',
'medium.hostux.net',
'libmedium.batsense.net',
],
scribe: [
'scribe.rip',
'scribe.nixnet.services',
'scribe.citizen4.eu',
'scribe.froth.zone',
'scribe.rawbit.ninja',
'sc.vern.cc',
'scribe.r4fo.com',
'scribe.privacyredirect.com',
'scribe.privacyredirect.com',
'scribe.rawbit.ninja',
'scribe.rip',
],
small: ['small.private.coffee'],
},
quora: {
quetre: [
'quetre.iket.me',
'qr.vern.cc',
'quetre.pussthecat.org',
'ask.habedieeh.re',
'quetre.blackdrgn.nl',
'quetre.lunar.icu',
'quetre.drgns.space',
'quetre.r4fo.com',
'quetre.ducks.party',
'quetre.private.coffee',
'quetre.canine.tools',
'qt.bloat.cat',
'quetre.jeikobu.net',
'q.307200.xyz',
'quora.nerdvpn.de',
'quetre.privacyredirect.com',
'quora.vern.cc',
'quetre.pufe.org',
'questions.whateveritworks.org',
'quetre.odyssey346.dev',
'quetre.pussthecat.org',
],
},
reddit: {
eddrit: ['eddrit.com'],
ledit: hashPath('ledit.lol'),
'photon-reddit': ['photon-reddit.com'],
rdx(url) {
const path = url.pathname;
const user = path.replace(/^\/u(?:ser)?\/([^/]+)/, '$1');
const subreddit = path.replace(/^\/r\/([^/]+)/, '$1');
if (path.includes('/comments/')) {
url.searchParams.set('url', url.href);
url.pathname = '/comments.html';
} else if (user !== path) {
url.searchParams.set('u', user);
url.pathname = '/user.html';
} else if (subreddit !== path) {
url.searchParams.set('r', subreddit);
url.pathname = '/subreddit.html';
}
url.hostname = 'rdx.overdevs.com';
},
reddiculous: hashPath(
'ashish-um.github.io/reddiculous',
'mescalito.github.io/Reddiculous',
),
reditr: ['reditr.com'],
redlib: [
'redlib.catsarch.com',
'redlib.perennialte.ch',
'redlib.privacyredirect.com',
'redlib.private.coffee',
'reddit.nerdvpn.de',
'reddit.adminforge.de',
'rl.blitzw.in',
'redlib.orangenet.cc',
'redlib.privadency.com',
'l.opnxng.com',
'red.artemislena.eu',
'redlib.nadeko.net',
'rl.bloat.cat',
'safereddit.com',
'redlib.freedit.eu',
],
rf: hashPath('rf.alexkoen.com'),
},
reuters: {
neuters: ['neuters.de', 'nu.vern.cc'],
},
stackoverflow: {
anonymousoverflow: [
'code.whatever.social',
'ao.vern.cc',
'overflow.lunar.icu',
'overflow.adminforge.de',
'overflow.hostux.net',
'ao.bloat.cat',
'ao.owo.si',
'overflow.freedit.eu',
'anonoverflow.hyperreal.coffee',
'overflow.r4fo.com',
'overflow.ducks.party',
'anonymousoverflow.privacyredirect.com',
'soflow.nerdvpn.de',
'overflow.einfachzocken.eu',
'overflow.seasi.dev',
'anonymousoverflow.catsarch.com',
'overflow.darkness.services',
'anonflow.aketawi.space',
'overflow.canine.tools',
'ao.bloat.cat',
],
},
tumblr: {
priviblur: [
'pb.bloat.cat',
'tb.opnxng.com',
'priviblur.pussthecat.org',
'priviblur.thebunny.zone',
'priviblur.canine.tools',
'pb.cleberg.net',
'tumblr.nerdvpn.de',
],
},
twitter: {
nitter: [
'xcancel.com',
'nitter.privacyredirect.com',
'lightbrd.com',
'nitter.space',
'nitter.tiekoetter.com',
'nuku.trabun.org',
'nitter.net',
],
},
urbandictionary: {
ruraldictionary: ['rd.vern.cc', 'rd.bloat.cat', 'rd.thirtysix.pw'],
},
get 'x.com'() {
return replacements.twitter;
},
youtube: {
invidious: [
'inv.nadeko.net',
'invidious.nerdvpn.de',
'invidious.f5.si',
'yewtu.be',
'invidious.snopyta.org',
],
skipvids(url) {
url.hostname = 'skipvids.com';
url.pathname = '/';
},
},
};
const redirect = new URL(location);
const replacement = Object.entries(replacements).find(([host]) =>
location.hostname.includes(host),
);
if (replacement) {
const [, options] = replacement;
const option = chooseRandom(options);
if (isFunction(option)) {
option(redirect);
} else if (Array.isArray(option)) {
redirect.hostname = chooseRandom(option);
}
} else {
redirect.href = `https://farside.link/_/${location}`;
}
return redirect;
}
function main() {
const redirect = getRedirect();
location.replace(redirect);
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment