Redirect root "/" to /feed/subscriptions, including clicks on the YouTube logo (client-side navigation).
// ==UserScript==
// @name YouTube Home → Subscriptions (SPA-aware)
// @author prothales
// @license MIT
// @namespace https://github.com/prothales/no-youtube-feed
// @homepageURL https://github.com/prothales/no-youtube-feed
// @supportURL https://github.com/prothales/no-youtube-feed/issues
// @version 1.1
// @description Redirect root "/" to /feed/subscriptions, including clicks on the YouTube logo (client-side navigation).
// @match *://*.youtube.com/*
// @run-at document-start
// @grant none
// ==/UserScript==
(function() {
'use strict';
const TARGET = 'https://www.youtube.com/feed/subscriptions';
function isRoot() {
const p = location.pathname || '/';
return (p === '/' || p === '') && !location.pathname.startsWith('/feed/subscriptions');
}
function redirectIfRoot() {
try {
if (isRoot()) location.replace(TARGET);
} catch(e) {}
}
// initial attempt (covers full loads)
redirectIfRoot();
// wrap history methods so SPA navigations trigger a custom event
['pushState','replaceState'].forEach(m => {
const orig = history[m];
history[m] = function(...args) {
const res = orig.apply(this, args);
window.dispatchEvent(new Event('locationchange'));
return res;
};
});
window.addEventListener('popstate', () => window.dispatchEvent(new Event('locationchange')));
window.addEventListener('locationchange', () => setTimeout(redirectIfRoot, 60));
// listen to YouTube navigation events if present
window.addEventListener('yt-navigate-start', redirectIfRoot);
window.addEventListener('yt-navigate-finish', redirectIfRoot);
// lightweight polling fallback
let last = location.pathname + location.search + location.hash;
setInterval(() => {
const cur = location.pathname + location.search + location.hash;
if (cur !== last) { last = cur; redirectIfRoot(); }
}, 500);
})();