Skip to content

Instantly share code, notes, and snippets.

@digiwombat
Last active March 20, 2025 05:27
Show Gist options
  • Save digiwombat/1d3a7b2b38ab6cd198b8714458550215 to your computer and use it in GitHub Desktop.
Save digiwombat/1d3a7b2b38ab6cd198b8714458550215 to your computer and use it in GitHub Desktop.
YouTube Subscription Redirect
// ==UserScript==
// @name YouTube Subscription Redirect
// @description Automatically load the videos you actually care about
// @namespace B492B7DC-4C33-4E72-8316-49A425788F86
// @version 3.1
// @match *://www.youtube.com/*
// @match *://m.youtube.com/*
// @match *://youtu.be/*
// @run-at document-end
// @grant none
// @license MIT
// ==/UserScript==
// Adapted from: https://openuserjs.org/meta/rctdude2/YouTube_Subscription_Redirect.meta.js
(function() {
"use strict";
const CHANNEL_PATTERNS = {
pathname: /^\/(?:artist|channel|show|user|c)\/[A-Za-z0-9_-]+\/?$/,
atHandle: /^\/(?:@[^\/]+)\/?$/,
youtuBe: /^\/[A-Za-z0-9_-]+$/
};
// Parameters that should be removed
const CLEAR_PARAMS = new Set([
'annotation_id',
'app',
'feature',
'noredirect',
'reload',
'tab',
'si', // Session ID
't', // Timestamp
'v' // Video ID when in description
]);
function cleanURL(url) {
const params = new URLSearchParams(url.search);
let paramsChanged = false;
// Remove known problematic parameters
for (const param of CLEAR_PARAMS) {
if (params.has(param)) {
params.delete(param);
paramsChanged = true;
}
}
// Only update URL if parameters were actually removed
if (paramsChanged) {
const cleanSearch = params.toString();
const newPath = url.pathname + (cleanSearch ? `?${cleanSearch}` : '') + url.hash;
history.replaceState(null, '', newPath);
}
return url;
}
function handleYouTuBeRedirect() {
if (CHANNEL_PATTERNS.youtuBe.test(location.pathname)) {
const videoId = location.pathname.slice(1);
location.replace(`https://www.youtube.com/watch?v=${videoId}`);
return true;
}
return false;
}
function processRedirects(url) {
// Handle various redirect cases
if (url.pathname === '/') {
location.replace('/feed/subscriptions');
} else if (CHANNEL_PATTERNS.pathname.test(url.pathname) ||
CHANNEL_PATTERNS.atHandle.test(url.pathname)) {
// Only append /videos if it's not already there
if (!url.pathname.endsWith('/videos')) {
location.replace(url.pathname + '/videos' + url.search + url.hash);
}
}
}
function main() {
// Handle youtu.be links first
if (location.hostname === 'youtu.be') {
if (handleYouTuBeRedirect()) return;
}
// Clean URL without triggering reloads
const url = cleanURL(new URL(location.href));
// Process redirects
processRedirects(url);
}
// Listen for YouTube's SPA navigation events
window.addEventListener('yt-navigate-start', main);
// Initial run
main();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment