Skip to content

Instantly share code, notes, and snippets.

@examosa
Last active September 26, 2025 16:57
Show Gist options
  • Save examosa/50eb28bc16a006b62b3f43893ab457e7 to your computer and use it in GitHub Desktop.
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://jsonblob.com/api/jsonBlob/1392945386074857472',
'https://api.npoint.io/6ee2cb1b5a1aa6f10be5',
'https://api.pastes.dev/VSjbFP63yq',
'https://corsmirror.com/v1?url=https%3A%2F%2Fstarb.in%2Fraw%2FMgDjym',
'https://bytebin.lucko.me/bDAxqrUNqD',
];
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.4.4
// @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 hashPath = (...urls) =>
urls.map((href) => (url) => {
const { pathname } = url;
url.href = href;
url.hash = pathname.slice(1);
});
const instances = {
anonymousoverflow: [
'https://code.whatever.social',
'https://ao.vern.cc',
'https://overflow.lunar.icu',
'https://overflow.adminforge.de',
'https://overflow.hostux.net',
'https://ao.bloat.cat',
'https://ao.owo.si',
'https://overflow.freedit.eu',
'https://anonoverflow.hyperreal.coffee',
'https://overflow.r4fo.com',
'https://overflow.ducks.party',
'https://overflow.snine.nl',
'https://anonymousoverflow.privacyredirect.com',
'https://soflow.nerdvpn.de',
'https://overflow.einfachzocken.eu',
'https://overflow.seasi.dev',
'https://anonymousoverflow.catsarch.com',
'https://overflow.darkness.services',
'https://anonflow.aketawi.space',
'https://overflow.canine.tools',
'https://ao.bloat.cat',
],
breezewiki: [
'https://breezewiki.com',
'https://antifandom.com',
'https://breezewiki.pussthecat.org',
'https://bw.projectsegfau.lt',
'https://breeze.hostux.net',
'https://bw.artemislena.eu',
'https://breeze.nohost.network',
'https://breeze.whateveritworks.org',
'https://z.opnxng.com',
'https://breezewiki.hyperreal.coffee',
'https://breezewiki.catsarch.com',
'https://breeze.mint.lgbt',
'https://breezewiki.nadeko.net',
'https://fandom.reallyaweso.me',
'https://breezewiki.r4fo.com',
'https://breezewiki.private.coffee',
'https://fan.blitzw.in',
'https://antifandom.com',
'https://breezewiki.com',
'https://breezewiki.nadeko.net',
'https://breezewiki.pussthecat.org',
'https://bw.projectsegfau.lt',
],
ducksforducks: ['https://ducksforducks.private.coffee'],
dumb: [
'https://dm.vern.cc',
'https://dumb.lunar.icu',
'https://dumb.ducks.party',
'https://dumb.hyperreal.coffee',
'https://dumb.bloat.cat',
'https://dumb.jeikobu.net',
'https://dumb.canine.tools',
'https://lyr.dc09.ru',
'https://db.kuuro.net',
'https://dumb.ducks.party',
'https://dumb.lunar.icu',
],
eddrit: ['https://eddrit.com'],
imginn: [
function imginn(url) {
const { pathname } = url;
url.href = 'https://imginn.com';
url.pathname = pathname.replace('/reel/', '/p/');
},
],
intellectual: [
'https://in.bloat.cat',
'https://intellectual.catsarch.com',
'https://intellectual.insprill.net',
],
invidious: [
'https://inv.nadeko.net',
'https://invidious.nerdvpn.de',
'https://invidious.f5.si',
'https://yewtu.be',
'https://invidious.snopyta.org',
],
ledit: hashPath('https://ledit.lol'),
libmedium: [
'https://libmedium.batsense.net',
'https://md.vern.cc',
'https://medium.hostux.net',
'https://libmedium.batsense.net',
],
nerdsfornerds: ['https://nn.vern.cc'],
neuters: ['https://neuters.de', 'https://nu.vern.cc'],
nitter: [
'https://xcancel.com',
'https://nitter.privacyredirect.com',
'https://lightbrd.com',
'https://nitter.space',
'https://nitter.tiekoetter.com',
'https://nuku.trabun.org',
'https://nitter.net',
],
'photon-reddit': ['https://photon-reddit.com'],
priviblur: [
'https://pb.bloat.cat',
'https://tb.opnxng.com',
'https://priviblur.pussthecat.org',
'https://priviblur.thebunny.zone',
'https://priviblur.canine.tools',
'https://pb.cleberg.net',
'https://tumblr.nerdvpn.de',
],
quetre: [
'https://quetre.iket.me',
'https://qr.vern.cc',
'https://quetre.pussthecat.org',
'https://ask.habedieeh.re',
'https://quetre.blackdrgn.nl',
'https://quetre.lunar.icu',
'https://quetre.drgns.space',
'https://quetre.r4fo.com',
'https://quetre.ducks.party',
'https://quetre.private.coffee',
'https://quetre.canine.tools',
'https://qt.bloat.cat',
'https://quetre.jeikobu.net',
'https://q.307200.xyz',
'https://quora.nerdvpn.de',
'https://quetre.privacyredirect.com',
'https://quora.vern.cc',
'https://quetre.pufe.org',
'https://questions.whateveritworks.org',
'https://quetre.odyssey346.dev',
'https://quetre.pussthecat.org',
],
reddiculous: hashPath(
'https://ashish-um.github.io/reddiculous',
'https://mescalito.github.io/Reddiculous',
),
rdx: [
function 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';
},
],
reditr: ['https://reditr.com/'],
redlib: [
'https://redlib.catsarch.com',
'https://redlib.perennialte.ch',
'https://redlib.privacyredirect.com',
'https://redlib.private.coffee',
'https://reddit.nerdvpn.de',
'https://reddit.adminforge.de',
'https://rl.blitzw.in',
'https://redlib.orangenet.cc',
'https://redlib.privadency.com',
'https://l.opnxng.com',
'https://red.artemislena.eu',
'https://redlib.nadeko.net',
'https://rl.bloat.cat',
'https://safereddit.com',
'https://redlib.freedit.eu',
],
rf: hashPath('https://rf.alexkoen.com'),
ruraldictionary: [
'https://rd.vern.cc',
'https://rd.bloat.cat',
'https://rd.thirtysix.pw',
],
scribe: [
'https://scribe.rip',
'https://scribe.nixnet.services',
'https://scribe.citizen4.eu',
'https://scribe.froth.zone',
'https://scribe.rawbit.ninja',
'https://sc.vern.cc',
'https://scribe.r4fo.com',
'https://scribe.privacyredirect.com',
'https://scribe.privacyredirect.com',
'https://scribe.rawbit.ninja',
'https://scribe.rip',
],
small: ['https://small.private.coffee'],
skipvids: [
function skipVids(url) {
const { href } = url;
url.href = 'https://skipvids.com';
url.searchParams.set('search_query', href);
},
],
};
const replacements = Object.entries({
fandom: ['breezewiki'],
geeksforgeeks: ['ducksforducks', 'nerdsfornerds'],
genius: ['dumb', 'intellectual'],
instagram: ['imginn'],
medium: ['libmedium', 'scribe', 'small'],
quora: ['quetre'],
reddit: [
'eddrit',
'ledit',
'photon-reddit',
'rdx',
'reddiculous',
'reditr',
'redlib',
'rf',
],
reuters: ['neuters'],
stackoverflow: ['anonymousoverflow'],
tumblr: ['priviblur'],
twitter: ['nitter'],
urbandictionary: ['ruraldictionary'],
'x.com': ['nitter'],
youtube: ['invidious', 'skipvids'],
});
const redirect = new URL(location);
const replacement = replacements.find(([host]) =>
redirect.hostname.includes(host),
);
if (replacement) {
const isFunction = (input) => typeof input === 'function';
const chooseRandom = (list) =>
list.at(Math.floor(Math.random() * list.length));
const [, options] = replacement;
const type = chooseRandom(options);
const instancesForType = instances[type];
if (instancesForType?.length > 0) {
const instance = chooseRandom(instancesForType);
if (isFunction(instance)) {
instance(redirect);
} else {
redirect.href = instance;
redirect.pathname = location.pathname;
}
return redirect;
}
}
redirect.href = 'https://farside.link';
redirect.pathname = `/_/${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