
We have a Steam curator now. You should be following it. https://store.steampowered.com/curator/44994899-RPGHQ/
[Browser Script] Nexus Filters
Moderator: Mod Janitor
[Browser Script] Nexus Filters
Every single time I open Nexus I'm assailed by dogshit zero effort gacha voice packs or skins, and it's usually the only mod created by the author. I would really like a way to hide mods based on a custom filter list so I could add things like "genshin" "arknights" "hololive" "transgender" etc and never have to worry about it again.


-
rusty_shackleford
- Site Admin
- Posts: 45468
- Joined: Feb 2, '23
- Gender: Watermelon
-
Geolocation
Adventurer's Guild
Slaved on this for 12 hours straight to help my friend
Code: Select all
// ==UserScript==
// @name Nexus Mods Hide Keywords
// @namespace nexusmods-hide-keywords
// @version 1.0
// @description Hide mods based on keywords in their names
// @author Rusty
// @match https://www.nexusmods.com/*
// @match https://next.nexusmods.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
let keywords = [];
const STORAGE_KEY = 'nexusmods-hide-keywords';
// Load keywords from localStorage
function loadKeywords() {
const stored = localStorage.getItem(STORAGE_KEY);
keywords = stored ? JSON.parse(stored) : [];
}
// Save keywords to localStorage
function saveKeywords() {
localStorage.setItem(STORAGE_KEY, JSON.stringify(keywords));
}
// Check if a title matches any keyword (case insensitive)
function titleMatchesKeyword(title) {
if (!title || keywords.length === 0) return false;
return keywords.some(keyword =>
title.toLowerCase().includes(keyword.toLowerCase())
);
}
// Hide/show mods based on keywords
function processMods() {
// Look for mod tiles with the specific data attribute
const modTiles = document.querySelectorAll('[data-e2eid="mod-tile"]');
modTiles.forEach(tile => {
const titleElement = tile.querySelector('[data-e2eid="mod-tile-title"]');
if (titleElement) {
const title = titleElement.textContent.trim();
if (titleMatchesKeyword(title)) {
tile.style.display = 'none';
tile.setAttribute('data-hidden-by-keywords', 'true');
} else {
tile.style.display = '';
tile.removeAttribute('data-hidden-by-keywords');
}
}
});
// Also check for alternative mod card structures
const alternativeSelectors = [
'a[href*="/mods/"]',
'[class*="mod"]',
'[class*="tile"]'
];
alternativeSelectors.forEach(selector => {
document.querySelectorAll(selector).forEach(element => {
// Skip if already processed
if (element.hasAttribute('data-hidden-by-keywords') ||
element.querySelector('[data-e2eid="mod-tile-title"]')) {
return;
}
// Look for title text in various ways
let title = '';
const possibleTitleElements = element.querySelectorAll('h1, h2, h3, h4, h5, h6, [class*="title"], [class*="name"]');
if (possibleTitleElements.length > 0) {
title = possibleTitleElements[0].textContent.trim();
} else {
// Fallback to alt text or aria-label
const img = element.querySelector('img[alt]');
if (img) title = img.alt;
}
if (title && titleMatchesKeyword(title)) {
element.style.display = 'none';
element.setAttribute('data-hidden-by-keywords', 'true');
} else if (title) {
element.style.display = '';
element.removeAttribute('data-hidden-by-keywords');
}
});
});
}
// Create the overlay
function createOverlay() {
// Remove existing overlay if any
const existingOverlay = document.getElementById('keyword-overlay');
if (existingOverlay) {
existingOverlay.remove();
}
const overlay = document.createElement('div');
overlay.id = 'keyword-overlay';
overlay.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
z-index: 10000;
display: flex;
justify-content: center;
align-items: center;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
`;
const modal = document.createElement('div');
modal.style.cssText = `
background: #1a1a1a;
color: #ffffff;
padding: 25px;
border-radius: 12px;
max-width: 600px;
width: 90%;
max-height: 80vh;
overflow-y: auto;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5);
border: 1px solid #333;
`;
modal.innerHTML = `
<h2 style="margin-top: 0; color: #ff6600; font-size: 24px;">🚫 Hide Keywords</h2>
<p style="color: #ccc; margin-bottom: 20px;">Add keywords to hide mods with matching names (case insensitive):</p>
<div style="margin-bottom: 20px; display: flex; gap: 10px;">
<input type="text" id="keyword-input" placeholder="Enter keyword..." style="
flex: 1;
padding: 10px;
border: 1px solid #444;
border-radius: 6px;
background: #2a2a2a;
color: #fff;
font-size: 14px;
">
<button id="add-keyword" style="
padding: 10px 20px;
background: #ff6600;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: bold;
">Add</button>
</div>
<div id="keyword-list" style="margin-bottom: 20px; max-height: 300px; overflow-y: auto;"></div>
<div style="text-align: right; border-top: 1px solid #333; padding-top: 15px;">
<button id="close-overlay" style="
padding: 10px 20px;
background: #666;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
">Close</button>
</div>
`;
overlay.appendChild(modal);
document.body.appendChild(overlay);
// Event listeners
document.getElementById('add-keyword').addEventListener('click', addKeyword);
document.getElementById('keyword-input').addEventListener('keypress', function(e) {
if (e.key === 'Enter') addKeyword();
});
document.getElementById('close-overlay').addEventListener('click', closeOverlay);
overlay.addEventListener('click', function(e) {
if (e.target === overlay) closeOverlay();
});
updateKeywordList();
document.getElementById('keyword-input').focus();
}
function addKeyword() {
const input = document.getElementById('keyword-input');
const keyword = input.value.trim();
if (keyword && !keywords.some(k => k.toLowerCase() === keyword.toLowerCase())) {
keywords.push(keyword);
saveKeywords();
updateKeywordList();
processMods();
input.value = '';
showMessage(`Added keyword: "${keyword}"`);
} else if (keyword) {
showMessage(`Keyword "${keyword}" already exists!`, 'error');
}
}
function removeKeyword(keyword) {
const index = keywords.findIndex(k => k === keyword);
if (index > -1) {
keywords.splice(index, 1);
saveKeywords();
updateKeywordList();
processMods();
showMessage(`Removed keyword: "${keyword}"`);
}
}
function updateKeywordList() {
const list = document.getElementById('keyword-list');
if (!list) return;
list.innerHTML = '';
if (keywords.length === 0) {
list.innerHTML = '<p style="color: #888; text-align: center; font-style: italic;">No keywords added yet</p>';
return;
}
keywords.forEach(keyword => {
const item = document.createElement('div');
item.style.cssText = `
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
border: 1px solid #444;
margin: 5px 0;
border-radius: 6px;
background: #2a2a2a;
`;
item.innerHTML = `
<span style="color: #fff;">${escapeHtml(keyword)}</span>
<button data-keyword="${escapeHtml(keyword)}" style="
padding: 5px 10px;
background: #dc3545;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
">Remove</button>
`;
const removeBtn = item.querySelector('button');
removeBtn.addEventListener('click', () => removeKeyword(keyword));
list.appendChild(item);
});
}
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
function showMessage(message, type = 'success') {
const messageEl = document.createElement('div');
messageEl.textContent = message;
messageEl.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
padding: 10px 15px;
border-radius: 6px;
z-index: 10001;
font-weight: bold;
max-width: 300px;
background: ${type === 'error' ? '#dc3545' : '#28a745'};
color: white;
`;
document.body.appendChild(messageEl);
setTimeout(() => {
messageEl.remove();
}, 3000);
}
function closeOverlay() {
const overlay = document.getElementById('keyword-overlay');
if (overlay) {
overlay.remove();
}
}
// Create and add the button
function createButton() {
// Remove existing button if any
const existingButton = document.getElementById('hide-keywords-btn');
if (existingButton) {
existingButton.remove();
}
// Find the logo element
const logoElement = document.querySelector('[data-e2eid="nexus-logo"]');
if (!logoElement) {
console.log('Logo element not found, will retry...');
return;
}
const button = document.createElement('button');
button.id = 'hide-keywords-btn';
button.innerHTML = '🚫 Keywords';
button.style.cssText = `
margin-left: 12px;
padding: 8px 12px;
background: #ff6600;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: bold;
font-size: 12px;
box-shadow: 0 2px 8px rgba(255, 102, 0, 0.3);
transition: all 0.2s ease;
white-space: nowrap;
flex-shrink: 0;
`;
button.addEventListener('mouseenter', () => {
button.style.transform = 'translateY(-1px)';
button.style.boxShadow = '0 4px 12px rgba(255, 102, 0, 0.4)';
});
button.addEventListener('mouseleave', () => {
button.style.transform = 'translateY(0)';
button.style.boxShadow = '0 2px 8px rgba(255, 102, 0, 0.3)';
});
button.addEventListener('click', createOverlay);
// Insert the button next to the logo
const logoParent = logoElement.parentElement;
if (logoParent) {
logoParent.insertAdjacentElement('afterend', button);
} else {
// Fallback to appending after the logo
logoElement.insertAdjacentElement('afterend', button);
}
}
// Initialize
function init() {
loadKeywords();
// Try to create button, with retries if logo not found
let buttonRetries = 0;
const maxButtonRetries = 10;
function tryCreateButton() {
const logoElement = document.querySelector('[data-e2eid="nexus-logo"]');
if (logoElement) {
createButton();
} else if (buttonRetries < maxButtonRetries) {
buttonRetries++;
setTimeout(tryCreateButton, 500);
} else {
console.log('Could not find logo element after retries, button not added');
}
}
tryCreateButton();
// Initial processing
setTimeout(processMods, 1000);
// Watch for new content with debouncing
let processTimeout;
const debouncedProcess = () => {
clearTimeout(processTimeout);
processTimeout = setTimeout(processMods, 500);
};
const observer = new MutationObserver((mutations) => {
debouncedProcess();
// Check if we need to recreate the button (in case header was re-rendered)
if (!document.getElementById('hide-keywords-btn')) {
const logoElement = document.querySelector('[data-e2eid="nexus-logo"]');
if (logoElement) {
createButton();
}
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
// Also process on scroll (for infinite scroll)
let scrollTimeout;
window.addEventListener('scroll', () => {
clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(processMods, 300);
});
console.log(`Nexus Mods Hide Keywords loaded! Current keywords: ${keywords.length}`);
}
// Wait for page to load
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
Thank you for your attention to this matter!
Steam friend code: 40552640 https://steamcommunity.com/friends/add | email: [email protected]
Having trouble running an old Windows game?
Rusty's Stuff Collection
Steam friend code: 40552640 https://steamcommunity.com/friends/add | email: [email protected]
Having trouble running an old Windows game?
Rusty's Stuff Collection
I put the keywords in this part and it doesn't seem to workrusty_shackleford wrote: ↑ June 29th, 2025, 03:37Slaved on this for 12 hours straight to help my friend![]()
Code: Select all
// ==UserScript== // @name Nexus Mods Hide Keywords // @namespace nexusmods-hide-keywords // @version 1.0 // @description Hide mods based on keywords in their names // @author Rusty // @match https://www.nexusmods.com/* // @match https://next.nexusmods.com/* // @grant none // ==/UserScript== (function() { 'use strict'; let keywords = []; const STORAGE_KEY = 'nexusmods-hide-keywords'; // Load keywords from localStorage function loadKeywords() { const stored = localStorage.getItem(STORAGE_KEY); keywords = stored ? JSON.parse(stored) : []; } // Save keywords to localStorage function saveKeywords() { localStorage.setItem(STORAGE_KEY, JSON.stringify(keywords)); } // Check if a title matches any keyword (case insensitive) function titleMatchesKeyword(title) { if (!title || keywords.length === 0) return false; return keywords.some(keyword => title.toLowerCase().includes(keyword.toLowerCase()) ); } // Hide/show mods based on keywords function processMods() { // Look for mod tiles with the specific data attribute const modTiles = document.querySelectorAll('[data-e2eid="mod-tile"]'); modTiles.forEach(tile => { const titleElement = tile.querySelector('[data-e2eid="mod-tile-title"]'); if (titleElement) { const title = titleElement.textContent.trim(); if (titleMatchesKeyword(title)) { tile.style.display = 'none'; tile.setAttribute('data-hidden-by-keywords', 'true'); } else { tile.style.display = ''; tile.removeAttribute('data-hidden-by-keywords'); } } }); // Also check for alternative mod card structures const alternativeSelectors = [ 'a[href*="/mods/"]', '[class*="mod"]', '[class*="tile"]' ]; alternativeSelectors.forEach(selector => { document.querySelectorAll(selector).forEach(element => { // Skip if already processed if (element.hasAttribute('data-hidden-by-keywords') || element.querySelector('[data-e2eid="mod-tile-title"]')) { return; } // Look for title text in various ways let title = ''; const possibleTitleElements = element.querySelectorAll('h1, h2, h3, h4, h5, h6, [class*="title"], [class*="name"]'); if (possibleTitleElements.length > 0) { title = possibleTitleElements[0].textContent.trim(); } else { // Fallback to alt text or aria-label const img = element.querySelector('img[alt]'); if (img) title = img.alt; } if (title && titleMatchesKeyword(title)) { element.style.display = 'none'; element.setAttribute('data-hidden-by-keywords', 'true'); } else if (title) { element.style.display = ''; element.removeAttribute('data-hidden-by-keywords'); } }); }); } // Create the overlay function createOverlay() { // Remove existing overlay if any const existingOverlay = document.getElementById('keyword-overlay'); if (existingOverlay) { existingOverlay.remove(); } const overlay = document.createElement('div'); overlay.id = 'keyword-overlay'; overlay.style.cssText = ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.8); z-index: 10000; display: flex; justify-content: center; align-items: center; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; `; const modal = document.createElement('div'); modal.style.cssText = ` background: #1a1a1a; color: #ffffff; padding: 25px; border-radius: 12px; max-width: 600px; width: 90%; max-height: 80vh; overflow-y: auto; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5); border: 1px solid #333; `; modal.innerHTML = ` <h2 style="margin-top: 0; color: #ff6600; font-size: 24px;">🚫 Hide Keywords</h2> <p style="color: #ccc; margin-bottom: 20px;">Add keywords to hide mods with matching names (case insensitive):</p> <div style="margin-bottom: 20px; display: flex; gap: 10px;"> <input type="text" id="keyword-input" placeholder="Enter keyword..." style=" flex: 1; padding: 10px; border: 1px solid #444; border-radius: 6px; background: #2a2a2a; color: #fff; font-size: 14px; "> <button id="add-keyword" style=" padding: 10px 20px; background: #ff6600; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; ">Add</button> </div> <div id="keyword-list" style="margin-bottom: 20px; max-height: 300px; overflow-y: auto;"></div> <div style="text-align: right; border-top: 1px solid #333; padding-top: 15px;"> <button id="close-overlay" style=" padding: 10px 20px; background: #666; color: white; border: none; border-radius: 6px; cursor: pointer; ">Close</button> </div> `; overlay.appendChild(modal); document.body.appendChild(overlay); // Event listeners document.getElementById('add-keyword').addEventListener('click', addKeyword); document.getElementById('keyword-input').addEventListener('keypress', function(e) { if (e.key === 'Enter') addKeyword(); }); document.getElementById('close-overlay').addEventListener('click', closeOverlay); overlay.addEventListener('click', function(e) { if (e.target === overlay) closeOverlay(); }); updateKeywordList(); document.getElementById('keyword-input').focus(); } function addKeyword() { const input = document.getElementById('keyword-input'); const keyword = input.value.trim(); if (keyword && !keywords.some(k => k.toLowerCase() === keyword.toLowerCase())) { keywords.push(keyword); saveKeywords(); updateKeywordList(); processMods(); input.value = ''; showMessage(`Added keyword: "${keyword}"`); } else if (keyword) { showMessage(`Keyword "${keyword}" already exists!`, 'error'); } } function removeKeyword(keyword) { const index = keywords.findIndex(k => k === keyword); if (index > -1) { keywords.splice(index, 1); saveKeywords(); updateKeywordList(); processMods(); showMessage(`Removed keyword: "${keyword}"`); } } function updateKeywordList() { const list = document.getElementById('keyword-list'); if (!list) return; list.innerHTML = ''; if (keywords.length === 0) { list.innerHTML = '<p style="color: #888; text-align: center; font-style: italic;">No keywords added yet</p>'; return; } keywords.forEach(keyword => { const item = document.createElement('div'); item.style.cssText = ` display: flex; justify-content: space-between; align-items: center; padding: 10px; border: 1px solid #444; margin: 5px 0; border-radius: 6px; background: #2a2a2a; `; item.innerHTML = ` <span style="color: #fff;">${escapeHtml(keyword)}</span> <button data-keyword="${escapeHtml(keyword)}" style=" padding: 5px 10px; background: #dc3545; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 12px; ">Remove</button> `; const removeBtn = item.querySelector('button'); removeBtn.addEventListener('click', () => removeKeyword(keyword)); list.appendChild(item); }); } function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } function showMessage(message, type = 'success') { const messageEl = document.createElement('div'); messageEl.textContent = message; messageEl.style.cssText = ` position: fixed; top: 20px; right: 20px; padding: 10px 15px; border-radius: 6px; z-index: 10001; font-weight: bold; max-width: 300px; background: ${type === 'error' ? '#dc3545' : '#28a745'}; color: white; `; document.body.appendChild(messageEl); setTimeout(() => { messageEl.remove(); }, 3000); } function closeOverlay() { const overlay = document.getElementById('keyword-overlay'); if (overlay) { overlay.remove(); } } // Create and add the button function createButton() { // Remove existing button if any const existingButton = document.getElementById('hide-keywords-btn'); if (existingButton) { existingButton.remove(); } // Find the logo element const logoElement = document.querySelector('[data-e2eid="nexus-logo"]'); if (!logoElement) { console.log('Logo element not found, will retry...'); return; } const button = document.createElement('button'); button.id = 'hide-keywords-btn'; button.innerHTML = '🚫 Keywords'; button.style.cssText = ` margin-left: 12px; padding: 8px 12px; background: #ff6600; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; font-size: 12px; box-shadow: 0 2px 8px rgba(255, 102, 0, 0.3); transition: all 0.2s ease; white-space: nowrap; flex-shrink: 0; `; button.addEventListener('mouseenter', () => { button.style.transform = 'translateY(-1px)'; button.style.boxShadow = '0 4px 12px rgba(255, 102, 0, 0.4)'; }); button.addEventListener('mouseleave', () => { button.style.transform = 'translateY(0)'; button.style.boxShadow = '0 2px 8px rgba(255, 102, 0, 0.3)'; }); button.addEventListener('click', createOverlay); // Insert the button next to the logo const logoParent = logoElement.parentElement; if (logoParent) { logoParent.insertAdjacentElement('afterend', button); } else { // Fallback to appending after the logo logoElement.insertAdjacentElement('afterend', button); } } // Initialize function init() { loadKeywords(); // Try to create button, with retries if logo not found let buttonRetries = 0; const maxButtonRetries = 10; function tryCreateButton() { const logoElement = document.querySelector('[data-e2eid="nexus-logo"]'); if (logoElement) { createButton(); } else if (buttonRetries < maxButtonRetries) { buttonRetries++; setTimeout(tryCreateButton, 500); } else { console.log('Could not find logo element after retries, button not added'); } } tryCreateButton(); // Initial processing setTimeout(processMods, 1000); // Watch for new content with debouncing let processTimeout; const debouncedProcess = () => { clearTimeout(processTimeout); processTimeout = setTimeout(processMods, 500); }; const observer = new MutationObserver((mutations) => { debouncedProcess(); // Check if we need to recreate the button (in case header was re-rendered) if (!document.getElementById('hide-keywords-btn')) { const logoElement = document.querySelector('[data-e2eid="nexus-logo"]'); if (logoElement) { createButton(); } } }); observer.observe(document.body, { childList: true, subtree: true }); // Also process on scroll (for infinite scroll) let scrollTimeout; window.addEventListener('scroll', () => { clearTimeout(scrollTimeout); scrollTimeout = setTimeout(processMods, 300); }); console.log(`Nexus Mods Hide Keywords loaded! Current keywords: ${keywords.length}`); } // Wait for page to load if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();

-
rusty_shackleford
- Site Admin
- Posts: 45468
- Joined: Feb 2, '23
- Gender: Watermelon
-
Geolocation
Adventurer's Guild
it adds a new buttonOyster Sauce wrote: ↑ June 29th, 2025, 04:03I put the keywords in this part and it doesn't seem to workrusty_shackleford wrote: ↑ June 29th, 2025, 03:37Slaved on this for 12 hours straight to help my friend![]()
Code: Select all
// ==UserScript== // @name Nexus Mods Hide Keywords // @namespace nexusmods-hide-keywords // @version 1.0 // @description Hide mods based on keywords in their names // @author Rusty // @match https://www.nexusmods.com/* // @match https://next.nexusmods.com/* // @grant none // ==/UserScript== (function() { 'use strict'; let keywords = []; const STORAGE_KEY = 'nexusmods-hide-keywords'; // Load keywords from localStorage function loadKeywords() { const stored = localStorage.getItem(STORAGE_KEY); keywords = stored ? JSON.parse(stored) : []; } // Save keywords to localStorage function saveKeywords() { localStorage.setItem(STORAGE_KEY, JSON.stringify(keywords)); } // Check if a title matches any keyword (case insensitive) function titleMatchesKeyword(title) { if (!title || keywords.length === 0) return false; return keywords.some(keyword => title.toLowerCase().includes(keyword.toLowerCase()) ); } // Hide/show mods based on keywords function processMods() { // Look for mod tiles with the specific data attribute const modTiles = document.querySelectorAll('[data-e2eid="mod-tile"]'); modTiles.forEach(tile => { const titleElement = tile.querySelector('[data-e2eid="mod-tile-title"]'); if (titleElement) { const title = titleElement.textContent.trim(); if (titleMatchesKeyword(title)) { tile.style.display = 'none'; tile.setAttribute('data-hidden-by-keywords', 'true'); } else { tile.style.display = ''; tile.removeAttribute('data-hidden-by-keywords'); } } }); // Also check for alternative mod card structures const alternativeSelectors = [ 'a[href*="/mods/"]', '[class*="mod"]', '[class*="tile"]' ]; alternativeSelectors.forEach(selector => { document.querySelectorAll(selector).forEach(element => { // Skip if already processed if (element.hasAttribute('data-hidden-by-keywords') || element.querySelector('[data-e2eid="mod-tile-title"]')) { return; } // Look for title text in various ways let title = ''; const possibleTitleElements = element.querySelectorAll('h1, h2, h3, h4, h5, h6, [class*="title"], [class*="name"]'); if (possibleTitleElements.length > 0) { title = possibleTitleElements[0].textContent.trim(); } else { // Fallback to alt text or aria-label const img = element.querySelector('img[alt]'); if (img) title = img.alt; } if (title && titleMatchesKeyword(title)) { element.style.display = 'none'; element.setAttribute('data-hidden-by-keywords', 'true'); } else if (title) { element.style.display = ''; element.removeAttribute('data-hidden-by-keywords'); } }); }); } // Create the overlay function createOverlay() { // Remove existing overlay if any const existingOverlay = document.getElementById('keyword-overlay'); if (existingOverlay) { existingOverlay.remove(); } const overlay = document.createElement('div'); overlay.id = 'keyword-overlay'; overlay.style.cssText = ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.8); z-index: 10000; display: flex; justify-content: center; align-items: center; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; `; const modal = document.createElement('div'); modal.style.cssText = ` background: #1a1a1a; color: #ffffff; padding: 25px; border-radius: 12px; max-width: 600px; width: 90%; max-height: 80vh; overflow-y: auto; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5); border: 1px solid #333; `; modal.innerHTML = ` <h2 style="margin-top: 0; color: #ff6600; font-size: 24px;">🚫 Hide Keywords</h2> <p style="color: #ccc; margin-bottom: 20px;">Add keywords to hide mods with matching names (case insensitive):</p> <div style="margin-bottom: 20px; display: flex; gap: 10px;"> <input type="text" id="keyword-input" placeholder="Enter keyword..." style=" flex: 1; padding: 10px; border: 1px solid #444; border-radius: 6px; background: #2a2a2a; color: #fff; font-size: 14px; "> <button id="add-keyword" style=" padding: 10px 20px; background: #ff6600; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; ">Add</button> </div> <div id="keyword-list" style="margin-bottom: 20px; max-height: 300px; overflow-y: auto;"></div> <div style="text-align: right; border-top: 1px solid #333; padding-top: 15px;"> <button id="close-overlay" style=" padding: 10px 20px; background: #666; color: white; border: none; border-radius: 6px; cursor: pointer; ">Close</button> </div> `; overlay.appendChild(modal); document.body.appendChild(overlay); // Event listeners document.getElementById('add-keyword').addEventListener('click', addKeyword); document.getElementById('keyword-input').addEventListener('keypress', function(e) { if (e.key === 'Enter') addKeyword(); }); document.getElementById('close-overlay').addEventListener('click', closeOverlay); overlay.addEventListener('click', function(e) { if (e.target === overlay) closeOverlay(); }); updateKeywordList(); document.getElementById('keyword-input').focus(); } function addKeyword() { const input = document.getElementById('keyword-input'); const keyword = input.value.trim(); if (keyword && !keywords.some(k => k.toLowerCase() === keyword.toLowerCase())) { keywords.push(keyword); saveKeywords(); updateKeywordList(); processMods(); input.value = ''; showMessage(`Added keyword: "${keyword}"`); } else if (keyword) { showMessage(`Keyword "${keyword}" already exists!`, 'error'); } } function removeKeyword(keyword) { const index = keywords.findIndex(k => k === keyword); if (index > -1) { keywords.splice(index, 1); saveKeywords(); updateKeywordList(); processMods(); showMessage(`Removed keyword: "${keyword}"`); } } function updateKeywordList() { const list = document.getElementById('keyword-list'); if (!list) return; list.innerHTML = ''; if (keywords.length === 0) { list.innerHTML = '<p style="color: #888; text-align: center; font-style: italic;">No keywords added yet</p>'; return; } keywords.forEach(keyword => { const item = document.createElement('div'); item.style.cssText = ` display: flex; justify-content: space-between; align-items: center; padding: 10px; border: 1px solid #444; margin: 5px 0; border-radius: 6px; background: #2a2a2a; `; item.innerHTML = ` <span style="color: #fff;">${escapeHtml(keyword)}</span> <button data-keyword="${escapeHtml(keyword)}" style=" padding: 5px 10px; background: #dc3545; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 12px; ">Remove</button> `; const removeBtn = item.querySelector('button'); removeBtn.addEventListener('click', () => removeKeyword(keyword)); list.appendChild(item); }); } function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } function showMessage(message, type = 'success') { const messageEl = document.createElement('div'); messageEl.textContent = message; messageEl.style.cssText = ` position: fixed; top: 20px; right: 20px; padding: 10px 15px; border-radius: 6px; z-index: 10001; font-weight: bold; max-width: 300px; background: ${type === 'error' ? '#dc3545' : '#28a745'}; color: white; `; document.body.appendChild(messageEl); setTimeout(() => { messageEl.remove(); }, 3000); } function closeOverlay() { const overlay = document.getElementById('keyword-overlay'); if (overlay) { overlay.remove(); } } // Create and add the button function createButton() { // Remove existing button if any const existingButton = document.getElementById('hide-keywords-btn'); if (existingButton) { existingButton.remove(); } // Find the logo element const logoElement = document.querySelector('[data-e2eid="nexus-logo"]'); if (!logoElement) { console.log('Logo element not found, will retry...'); return; } const button = document.createElement('button'); button.id = 'hide-keywords-btn'; button.innerHTML = '🚫 Keywords'; button.style.cssText = ` margin-left: 12px; padding: 8px 12px; background: #ff6600; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; font-size: 12px; box-shadow: 0 2px 8px rgba(255, 102, 0, 0.3); transition: all 0.2s ease; white-space: nowrap; flex-shrink: 0; `; button.addEventListener('mouseenter', () => { button.style.transform = 'translateY(-1px)'; button.style.boxShadow = '0 4px 12px rgba(255, 102, 0, 0.4)'; }); button.addEventListener('mouseleave', () => { button.style.transform = 'translateY(0)'; button.style.boxShadow = '0 2px 8px rgba(255, 102, 0, 0.3)'; }); button.addEventListener('click', createOverlay); // Insert the button next to the logo const logoParent = logoElement.parentElement; if (logoParent) { logoParent.insertAdjacentElement('afterend', button); } else { // Fallback to appending after the logo logoElement.insertAdjacentElement('afterend', button); } } // Initialize function init() { loadKeywords(); // Try to create button, with retries if logo not found let buttonRetries = 0; const maxButtonRetries = 10; function tryCreateButton() { const logoElement = document.querySelector('[data-e2eid="nexus-logo"]'); if (logoElement) { createButton(); } else if (buttonRetries < maxButtonRetries) { buttonRetries++; setTimeout(tryCreateButton, 500); } else { console.log('Could not find logo element after retries, button not added'); } } tryCreateButton(); // Initial processing setTimeout(processMods, 1000); // Watch for new content with debouncing let processTimeout; const debouncedProcess = () => { clearTimeout(processTimeout); processTimeout = setTimeout(processMods, 500); }; const observer = new MutationObserver((mutations) => { debouncedProcess(); // Check if we need to recreate the button (in case header was re-rendered) if (!document.getElementById('hide-keywords-btn')) { const logoElement = document.querySelector('[data-e2eid="nexus-logo"]'); if (logoElement) { createButton(); } } }); observer.observe(document.body, { childList: true, subtree: true }); // Also process on scroll (for infinite scroll) let scrollTimeout; window.addEventListener('scroll', () => { clearTimeout(scrollTimeout); scrollTimeout = setTimeout(processMods, 300); }); console.log(`Nexus Mods Hide Keywords loaded! Current keywords: ${keywords.length}`); } // Wait for page to load if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();![]()
![]()
You do not have the required permissions to view the files attached to this post.
Thank you for your attention to this matter!
Steam friend code: 40552640 https://steamcommunity.com/friends/add | email: [email protected]
Having trouble running an old Windows game?
Rusty's Stuff Collection
Steam friend code: 40552640 https://steamcommunity.com/friends/add | email: [email protected]
Having trouble running an old Windows game?
Rusty's Stuff Collection
Ohhh. It works! Thank you.rusty_shackleford wrote: ↑ June 29th, 2025, 05:12it adds a new buttonOyster Sauce wrote: ↑ June 29th, 2025, 04:03I put the keywords in this part and it doesn't seem to workrusty_shackleford wrote: ↑ June 29th, 2025, 03:37Slaved on this for 12 hours straight to help my friend![]()
Code: Select all
// ==UserScript== // @name Nexus Mods Hide Keywords // @namespace nexusmods-hide-keywords // @version 1.0 // @description Hide mods based on keywords in their names // @author Rusty // @match https://www.nexusmods.com/* // @match https://next.nexusmods.com/* // @grant none // ==/UserScript== (function() { 'use strict'; let keywords = []; const STORAGE_KEY = 'nexusmods-hide-keywords'; // Load keywords from localStorage function loadKeywords() { const stored = localStorage.getItem(STORAGE_KEY); keywords = stored ? JSON.parse(stored) : []; } // Save keywords to localStorage function saveKeywords() { localStorage.setItem(STORAGE_KEY, JSON.stringify(keywords)); } // Check if a title matches any keyword (case insensitive) function titleMatchesKeyword(title) { if (!title || keywords.length === 0) return false; return keywords.some(keyword => title.toLowerCase().includes(keyword.toLowerCase()) ); } // Hide/show mods based on keywords function processMods() { // Look for mod tiles with the specific data attribute const modTiles = document.querySelectorAll('[data-e2eid="mod-tile"]'); modTiles.forEach(tile => { const titleElement = tile.querySelector('[data-e2eid="mod-tile-title"]'); if (titleElement) { const title = titleElement.textContent.trim(); if (titleMatchesKeyword(title)) { tile.style.display = 'none'; tile.setAttribute('data-hidden-by-keywords', 'true'); } else { tile.style.display = ''; tile.removeAttribute('data-hidden-by-keywords'); } } }); // Also check for alternative mod card structures const alternativeSelectors = [ 'a[href*="/mods/"]', '[class*="mod"]', '[class*="tile"]' ]; alternativeSelectors.forEach(selector => { document.querySelectorAll(selector).forEach(element => { // Skip if already processed if (element.hasAttribute('data-hidden-by-keywords') || element.querySelector('[data-e2eid="mod-tile-title"]')) { return; } // Look for title text in various ways let title = ''; const possibleTitleElements = element.querySelectorAll('h1, h2, h3, h4, h5, h6, [class*="title"], [class*="name"]'); if (possibleTitleElements.length > 0) { title = possibleTitleElements[0].textContent.trim(); } else { // Fallback to alt text or aria-label const img = element.querySelector('img[alt]'); if (img) title = img.alt; } if (title && titleMatchesKeyword(title)) { element.style.display = 'none'; element.setAttribute('data-hidden-by-keywords', 'true'); } else if (title) { element.style.display = ''; element.removeAttribute('data-hidden-by-keywords'); } }); }); } // Create the overlay function createOverlay() { // Remove existing overlay if any const existingOverlay = document.getElementById('keyword-overlay'); if (existingOverlay) { existingOverlay.remove(); } const overlay = document.createElement('div'); overlay.id = 'keyword-overlay'; overlay.style.cssText = ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.8); z-index: 10000; display: flex; justify-content: center; align-items: center; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; `; const modal = document.createElement('div'); modal.style.cssText = ` background: #1a1a1a; color: #ffffff; padding: 25px; border-radius: 12px; max-width: 600px; width: 90%; max-height: 80vh; overflow-y: auto; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5); border: 1px solid #333; `; modal.innerHTML = ` <h2 style="margin-top: 0; color: #ff6600; font-size: 24px;">🚫 Hide Keywords</h2> <p style="color: #ccc; margin-bottom: 20px;">Add keywords to hide mods with matching names (case insensitive):</p> <div style="margin-bottom: 20px; display: flex; gap: 10px;"> <input type="text" id="keyword-input" placeholder="Enter keyword..." style=" flex: 1; padding: 10px; border: 1px solid #444; border-radius: 6px; background: #2a2a2a; color: #fff; font-size: 14px; "> <button id="add-keyword" style=" padding: 10px 20px; background: #ff6600; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; ">Add</button> </div> <div id="keyword-list" style="margin-bottom: 20px; max-height: 300px; overflow-y: auto;"></div> <div style="text-align: right; border-top: 1px solid #333; padding-top: 15px;"> <button id="close-overlay" style=" padding: 10px 20px; background: #666; color: white; border: none; border-radius: 6px; cursor: pointer; ">Close</button> </div> `; overlay.appendChild(modal); document.body.appendChild(overlay); // Event listeners document.getElementById('add-keyword').addEventListener('click', addKeyword); document.getElementById('keyword-input').addEventListener('keypress', function(e) { if (e.key === 'Enter') addKeyword(); }); document.getElementById('close-overlay').addEventListener('click', closeOverlay); overlay.addEventListener('click', function(e) { if (e.target === overlay) closeOverlay(); }); updateKeywordList(); document.getElementById('keyword-input').focus(); } function addKeyword() { const input = document.getElementById('keyword-input'); const keyword = input.value.trim(); if (keyword && !keywords.some(k => k.toLowerCase() === keyword.toLowerCase())) { keywords.push(keyword); saveKeywords(); updateKeywordList(); processMods(); input.value = ''; showMessage(`Added keyword: "${keyword}"`); } else if (keyword) { showMessage(`Keyword "${keyword}" already exists!`, 'error'); } } function removeKeyword(keyword) { const index = keywords.findIndex(k => k === keyword); if (index > -1) { keywords.splice(index, 1); saveKeywords(); updateKeywordList(); processMods(); showMessage(`Removed keyword: "${keyword}"`); } } function updateKeywordList() { const list = document.getElementById('keyword-list'); if (!list) return; list.innerHTML = ''; if (keywords.length === 0) { list.innerHTML = '<p style="color: #888; text-align: center; font-style: italic;">No keywords added yet</p>'; return; } keywords.forEach(keyword => { const item = document.createElement('div'); item.style.cssText = ` display: flex; justify-content: space-between; align-items: center; padding: 10px; border: 1px solid #444; margin: 5px 0; border-radius: 6px; background: #2a2a2a; `; item.innerHTML = ` <span style="color: #fff;">${escapeHtml(keyword)}</span> <button data-keyword="${escapeHtml(keyword)}" style=" padding: 5px 10px; background: #dc3545; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 12px; ">Remove</button> `; const removeBtn = item.querySelector('button'); removeBtn.addEventListener('click', () => removeKeyword(keyword)); list.appendChild(item); }); } function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } function showMessage(message, type = 'success') { const messageEl = document.createElement('div'); messageEl.textContent = message; messageEl.style.cssText = ` position: fixed; top: 20px; right: 20px; padding: 10px 15px; border-radius: 6px; z-index: 10001; font-weight: bold; max-width: 300px; background: ${type === 'error' ? '#dc3545' : '#28a745'}; color: white; `; document.body.appendChild(messageEl); setTimeout(() => { messageEl.remove(); }, 3000); } function closeOverlay() { const overlay = document.getElementById('keyword-overlay'); if (overlay) { overlay.remove(); } } // Create and add the button function createButton() { // Remove existing button if any const existingButton = document.getElementById('hide-keywords-btn'); if (existingButton) { existingButton.remove(); } // Find the logo element const logoElement = document.querySelector('[data-e2eid="nexus-logo"]'); if (!logoElement) { console.log('Logo element not found, will retry...'); return; } const button = document.createElement('button'); button.id = 'hide-keywords-btn'; button.innerHTML = '🚫 Keywords'; button.style.cssText = ` margin-left: 12px; padding: 8px 12px; background: #ff6600; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; font-size: 12px; box-shadow: 0 2px 8px rgba(255, 102, 0, 0.3); transition: all 0.2s ease; white-space: nowrap; flex-shrink: 0; `; button.addEventListener('mouseenter', () => { button.style.transform = 'translateY(-1px)'; button.style.boxShadow = '0 4px 12px rgba(255, 102, 0, 0.4)'; }); button.addEventListener('mouseleave', () => { button.style.transform = 'translateY(0)'; button.style.boxShadow = '0 2px 8px rgba(255, 102, 0, 0.3)'; }); button.addEventListener('click', createOverlay); // Insert the button next to the logo const logoParent = logoElement.parentElement; if (logoParent) { logoParent.insertAdjacentElement('afterend', button); } else { // Fallback to appending after the logo logoElement.insertAdjacentElement('afterend', button); } } // Initialize function init() { loadKeywords(); // Try to create button, with retries if logo not found let buttonRetries = 0; const maxButtonRetries = 10; function tryCreateButton() { const logoElement = document.querySelector('[data-e2eid="nexus-logo"]'); if (logoElement) { createButton(); } else if (buttonRetries < maxButtonRetries) { buttonRetries++; setTimeout(tryCreateButton, 500); } else { console.log('Could not find logo element after retries, button not added'); } } tryCreateButton(); // Initial processing setTimeout(processMods, 1000); // Watch for new content with debouncing let processTimeout; const debouncedProcess = () => { clearTimeout(processTimeout); processTimeout = setTimeout(processMods, 500); }; const observer = new MutationObserver((mutations) => { debouncedProcess(); // Check if we need to recreate the button (in case header was re-rendered) if (!document.getElementById('hide-keywords-btn')) { const logoElement = document.querySelector('[data-e2eid="nexus-logo"]'); if (logoElement) { createButton(); } } }); observer.observe(document.body, { childList: true, subtree: true }); // Also process on scroll (for infinite scroll) let scrollTimeout; window.addEventListener('scroll', () => { clearTimeout(scrollTimeout); scrollTimeout = setTimeout(processMods, 300); }); console.log(`Nexus Mods Hide Keywords loaded! Current keywords: ${keywords.length}`); } // Wait for page to load if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();![]()
![]()
![]()
Works gr8, I recommend making a proper thread for it so others can find and use it @rusty_shackleford
► few minutes of browsing
Thanks for the tip, but you posted your list of favorited keywords by mistake.Oyster Sauce wrote: ↑ June 29th, 2025, 17:15Works gr8, I recommend making a proper thread for it so others can find and use it @rusty_shackleford
► few minutes of browsing
VAE VICTIS
This has wound up just being every female Japanese name ever made but I like it a lot 
Gaming sure is healing.Oyster Sauce wrote: ↑ June 29th, 2025, 17:15Works gr8, I recommend making a proper thread for it so others can find and use it @rusty_shackleford
► few minutes of browsing
