YouTube Quick Not Interested | Cododel
CODODELDEV
EN / RU
Back to Deck
[userscript]

YouTube Quick Not Interested

INSTALL
SOURCE YouTube
VERSION 2.4
AUTHOR Cododel

Target Match:

  • https://www.youtube.com/
  • https://www.youtube.com/?*

Eliminate the friction of teaching the YouTube algorithm. This script adds a one-click button to immediately dismiss unwanted content from your homepage feed.

Features

  • Homepage Only: Works exclusively on the YouTube homepage
  • One-Click Action: Instantly marks content as “Not interested”
  • Bilingual: Detects the menu item by its label (English & Russian)
  • Smart Detection: Automatically finds menu buttons via MutationObserver
  • Native Look: A compact button placed under the three-dot menu, styled to match YouTube

How it works

When clicked, the button automatically:

  1. Opens the video’s three-dot menu
  2. Finds the “Not interested” option by its label
  3. Clicks it to dismiss the video

The menu item is matched by text, so the English and Russian YouTube interfaces are supported.

Installation

  1. Install a UserScript extension (Tampermonkey/Violentmonkey)
  2. Install the script
  3. Visit YouTube homepage and enjoy cleaner feed!

Source Code

// ==UserScript==
// @name YouTube Quick Not Interested
// @namespace https://cododel.dev/
// @version 2.4
// @description Adds a small, centered "Not interested" button under the 3-dot menu (Only Homepage)
// @author Cododel
// @match https://www.youtube.com/
// @match https://www.youtube.com/?*
// @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// @updateURL https://cododel.dev/mods/youtube-quick-not-interested/install.user.js
// @downloadURL https://cododel.dev/mods/youtube-quick-not-interested/install.user.js
// @grant none
// ==/UserScript==
;(function () {
'use strict'
const CONFIG = {
sel: {
container: 'yt-lockup-metadata-view-model',
menuWrapper: 'button-view-model',
menuItem: 'yt-list-item-view-model, ytd-menu-service-item-renderer, tp-yt-paper-item',
popupContainer: 'ytd-popup-container',
},
keywords: ['Не интересует', 'Not interested'],
customSvgPath:
'M 12 1C5.925 1 1 5.925 1 12s4.925 11 11 11 11-4.925 11-11S18.075 1 12 1Zm0 2a9 9 0 018.246 12.605L4.755 6.661A8.99 8.99 0 0112 3ZM3.754 8.393l15.491 8.944A9 9 0 013.754 8.393Z',
cls: 'custom-ni-btn',
boxWidth: 40, // match the 3-dot button box so it centers identically
boxHeight: 20, // half height
iconSize: 12, // half-size icon
}
const isHomePage = () => window.location.pathname === '/'
const h = (tag, props = {}, ...children) => {
const el = document.createElementNS(props.xmlns || 'http://www.w3.org/1999/xhtml', tag)
Object.entries(props).forEach(([k, v]) =>
k === 'style'
? Object.assign(el.style, v)
: k.startsWith('on')
? el.addEventListener(k.slice(2).toLowerCase(), v)
: el.setAttribute(k, v),
)
children.forEach((c) => el.appendChild(c))
return el
}
const performAction = async (container) => {
const wrapper = container.querySelector(CONFIG.sel.menuWrapper)
const menuBtn = wrapper && wrapper.querySelector('button')
if (!menuBtn) {
console.warn('YouTube Quick Not Interested: Menu button not found')
return
}
menuBtn.click()
await new Promise((r) => setTimeout(r, 200))
const popup = document.querySelector(CONFIG.sel.popupContainer)
if (!popup) return
const items = Array.from(popup.querySelectorAll(CONFIG.sel.menuItem))
const target = items.find((item) =>
CONFIG.keywords.some((txt) => (item.textContent || '').includes(txt)),
)
if (target) {
target.click()
} else {
document.body.click()
console.warn('YouTube Quick Not Interested: "Not interested" item not found')
}
}
const createButton = (container) =>
h(
'button',
{
class: CONFIG.cls,
title: 'Не интересует / Not interested',
onClick: (e) => {
e.preventDefault()
e.stopPropagation()
performAction(container)
},
style: {
background: 'transparent',
border: 'none',
cursor: 'pointer',
padding: '0',
borderRadius: '50%',
width: CONFIG.boxWidth + 'px',
height: CONFIG.boxHeight + 'px',
color: '#fff',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
boxSizing: 'border-box',
transition: 'background 0.2s',
},
onMouseEnter: (e) => (e.currentTarget.style.background = 'rgba(255,255,255,0.1)'),
onMouseLeave: (e) => (e.currentTarget.style.background = 'transparent'),
},
h(
'svg',
{
xmlns: 'http://www.w3.org/2000/svg',
viewBox: '0 0 24 24',
width: String(CONFIG.iconSize),
height: String(CONFIG.iconSize),
style: { pointerEvents: 'none', fill: 'currentColor', display: 'block' },
},
h('path', { xmlns: 'http://www.w3.org/2000/svg', d: CONFIG.customSvgPath }),
),
)
const inject = (node) => {
if (!isHomePage()) return
if (!node || node.nodeType !== 1) return
const containers = node.matches?.(CONFIG.sel.container)
? [node]
: node.querySelectorAll(CONFIG.sel.container)
containers.forEach((c) => {
if (c.querySelector('.' + CONFIG.cls)) return
const wrapper = c.querySelector(CONFIG.sel.menuWrapper)
if (!wrapper || !wrapper.parentElement) return
wrapper.parentElement.appendChild(createButton(c))
})
}
const start = () => {
const observer = new MutationObserver((mutations) =>
mutations.forEach((m) => m.addedNodes.forEach(inject)),
)
observer.observe(document.body, { childList: true, subtree: true })
inject(document.body)
}
if (document.body) {
start()
} else {
document.addEventListener('DOMContentLoaded', start)
}
})()
[ ▲ 0 ]