Removes the terrible sponsored products from Amazon.
// ==UserScript==
// @name Amazon Sponsored Products remover
// @namespace https://greasyfork.org/en/users/2755-robotoilinc
// @author RobotOilInc
// @version 0.5.3
// @license MIT
// @description Removes the terrible sponsored products from Amazon.
// @include http*://www.amazon.*/*
// @icon https://i.imgur.com/LGHKHEs.png
// @run-at document-body
// @grant GM_registerMenuCommand
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
// ------------------------------------------------------------
// Persistent Settings
// ------------------------------------------------------------
const SETTINGS = {
logging: GM_getValue("logging", false),
showStats: GM_getValue("showStats", false),
forceAllResults: GM_getValue("forceAllResults", false)
};
const toggleSetting = (key, { reload = false, after } = {}) => {
SETTINGS[key] = !SETTINGS[key];
GM_setValue(key, SETTINGS[key]);
after?.();
if (reload) location.reload();
};
// ------------------------------------------------------------
// Menu System
// ------------------------------------------------------------
const registerMenu = () => {
GM_registerMenuCommand(`Logging: ${SETTINGS.logging ? "✔" : "✘"}`, () => {
toggleSetting("logging", { reload: true });
});
GM_registerMenuCommand(`Stats: ${SETTINGS.showStats ? "✔" : "✘"}`, () => {
toggleSetting("showStats", { after: updateStatsVisibility });
});
GM_registerMenuCommand(`Force all results: ${SETTINGS.forceAllResults ? "✔" : "✘"}`, () => {
toggleSetting("forceAllResults", { reload: true });
});
};
// ------------------------------------------------------------
// Stats Counter UI
// ------------------------------------------------------------
let stats = {
total: 0,
rules: {}
};
const createStatsBox = () => {
if (document.getElementById("amazon-remover-stats")) return;
const box = document.createElement("div");
box.id = "amazon-remover-stats";
box.innerHTML = `
<strong>Amazon Remover</strong><br>
Removed: <span id="ars-total">0</span>
<hr id="ars-divider" style="margin:6px 0; border:0; border-top:1px solid rgba(255,255,255,0.25); display:none;">
<div id="ars-breakdown"></div>
`;
// Add some CSS
Object.assign(box.style, {
position: "fixed",
bottom: "10px",
right: "10px",
background: "rgba(0,0,0,0.75)",
color: "white",
padding: "10px 14px",
fontSize: "12px",
borderRadius: "6px",
zIndex: "999999",
maxWidth: "220px",
lineHeight: "1.4",
display: "none",
contain: "layout style"
});
document.body.appendChild(box);
};
const updateStatsVisibility = () => {
const box = document.getElementById("amazon-remover-stats");
if (box) box.style.display = SETTINGS.showStats ? "block" : "none";
};
const updateStats = reason => {
stats.total++;
stats.rules[reason] = (stats.rules[reason] || 0) + 1;
const totalEl = document.getElementById("ars-total");
if (!totalEl) return;
totalEl.textContent = stats.total;
// Show divider only after first removal
if (stats.total === 1) {
document.getElementById("ars-divider").style.display = "block";
}
document.getElementById("ars-breakdown").innerHTML = Object.entries(stats.rules)
.map(([k, v]) => `${k}: ${v}`)
.join("<br>");
};
// ------------------------------------------------------------
// Logging Helper
// ------------------------------------------------------------
const log = (reason, el) => {
if (SETTINGS.logging) {
console.log(`[AmazonRemover] ${reason}`, el);
}
};
// ------------------------------------------------------------
// Force all results (browse → search)
// ------------------------------------------------------------
const redirectToAllResults = () => {
if (!SETTINGS.forceAllResults) return false;
// Already on a real search results list
if (document.querySelector("#search .s-result-list.s-search-results")) return false;
const link = document.querySelector("#apb-desktop-browse-search-see-all, a.apb-desktop-browse-search-see-all");
if (link?.href && link.href !== location.href) {
location.replace(link.href);
return true;
}
return false;
};
// ------------------------------------------------------------
// Rufus early CSS (hide + kill dock layout vars before paint settles)
// ------------------------------------------------------------
const injectRufusStyle = () => {
if (document.getElementById("amazon-remover-rufus-css")) return;
const style = document.createElement("style");
style.id = "amazon-remover-rufus-css";
style.textContent = `
[id*="rufus" i]:not(body):not(html),
[class*="rufus" i]:not(body):not(html) {
display: none !important;
}
body {
padding-left: 0 !important;
padding-right: 0 !important;
--rufus-docked-panel-width: 0px !important;
--total-rufus-panel-full-width: 0px !important;
--total-rufus-panel-half-width: 0px !important;
}
`;
(document.head || document.documentElement).appendChild(style);
};
// ------------------------------------------------------------
// Rule Engine
// ------------------------------------------------------------
const RULES = [
// Search
{ selector: '[data-component-type="sp-sponsored-result"]', parent: '[data-asin]', reason: 'Sponsored search result' },
{ selector: '.puis-sponsored-label-text', parent: '[class*="apbSearchResultItem"], [data-asin], .s-result-item', reason: 'Sponsored product' },
{ selector: '.s-widget-sponsored-label-text', parent: '[data-asin], .s-result-item, .a-carousel-container', reason: 'Sponsored product' },
{ selector: '.AdHolder', reason: 'Sponsored product' },
{ selector: '[data-adfeedbackdetails]', parent: '.celwidget', reason: 'Sponsored product' },
{ selector: '[data-video-type="sponsored"]', reason: 'Sponsored video' },
{ selector: '.sp_desktop_sponsored_label', parent: '.a-carousel-container', reason: 'Sponsored carousel' },
// Skyscraper / side rail
{ selector: '[class*="_adPlacements"]', reason: 'Skyscraper ad' },
{ selector: '[data-cel-widget*="adplacements"]', reason: 'Skyscraper ad' },
// Product page ads
{ selector: '#discovery-and-inspiration_feature_div', reason: 'Product page ad' },
{ selector: '#sims-themis-sponsored-products-2_feature_div', reason: 'Product page ad' },
{ selector: '#dp-ads-center-promo-dramabot_feature_div', reason: 'Product page ad' },
{ selector: '[data-cel-widget="desktop-dp-lpo_feature_div_0"]', reason: 'Product page ad' },
{ selector: '[data-cel-widget="dp-ads-center-promo_feature_div"]', reason: 'Product page ad' },
{ selector: '[data-cel-widget*="desktop-dp-atf_ad-placements"]', reason: 'Product page ad' },
{ selector: '[data-cel-widget="p13n-desktop-carousel_desktop-rhf_1"]', reason: 'Product page ad' },
{ selector: '[data-feature-name="amsDetailRight-dramabot"]', reason: 'Product page ad' },
{ selector: '[data-feature-name="dp-ads-center-promo-top-dramabot"]', reason: 'Product page ad' },
{ selector: '[data-feature-name="ad-endcap-1-dramabot"]', reason: 'Product page ad' },
{ selector: '[data-feature-name="sponsoredProducts2-2"]', reason: 'Product page ad' },
{ selector: '[data-feature-name="sims-sponsoredProducts2"]', reason: 'Product page ad' },
{ selector: '[id^="sponsoredProducts2"]', reason: 'Product page ad' },
{ selector: '#percolate-ui-ilm_div', reason: 'Product page ad' },
{ selector: '#rhf-shoveler', reason: 'Product page ad' },
{ selector: '[data-feature-name="desktop-dp-ilm"]', reason: 'Product page ad' },
// Product page promos / upsells
{ selector: '[data-feature-name="valuePick"]', reason: 'Product page promo' },
{ selector: '[data-feature-name="heroQuickPromoContainer"]', reason: 'Product page promo' },
{ selector: '[data-feature-name*="primeDPUpsell"], [id*="primeDPUpsell"]', reason: 'Prime upsell' },
// Brand / SIMS blocks
{ selector: '[data-feature-name="sims-discoveryAndInspiration"]', reason: 'Brand promotion' },
{ selector: '[data-feature-name="sims-simsContainer"]', reason: 'Brand promotion' },
{ selector: '[data-feature-name="sims-productBundle"]', reason: 'Brand promotion' },
// Reviews / Live
{ selector: '[data-csa-c-owner="CustomerReviews"]', reason: 'AI review insights' },
{ selector: '[data-id*="AmazonLiveDram"]', reason: 'Amazon Live' },
// Tracking page
{ selector: '[class*="spSponsored"]', parent: '#recsWidget', reason: 'Tracking page ad' },
{ selector: '[class*="dynamic-sponsored-behaviour-container"]', parent: '.a-carousel-container', reason: 'Tracking page ad' },
// Category / browse
{ selector: '[data-csa-c-painter="OctopusDramAsinPainter"]', reason: 'Category promo carousel' },
{ selector: '[data-csa-c-painter="content-grid-card-cards"]', parent: '.apb-default-slot', reason: 'Category brand banner' },
// Homepage
{ selector: '[class*="asin-sponsored-badge-container"]', parent: '[data-card-metrics-id]', reason: 'Homepage ad' },
{ selector: '[class*="widget-sponsored-badge-container"]', parent: '[data-card-metrics-id]', reason: 'Homepage ad' },
{ selector: '[class*="windowDisplaySponsoredBadgeContainer"]', parent: '[data-card-metrics-id]', reason: 'Homepage ad' },
{ selector: '[class*="sponsoredBadgeContainer"]', parent: '[data-card-metrics-id]', reason: 'Homepage ad' },
{ selector: '[cel_widget_id="desktop-hero-order"]', reason: 'Homepage hero' },
// Rufus
{ selector: '#nav-rufus-disco', reason: 'Rufus' },
{ selector: '#nav-flyout-rufus', reason: 'Rufus' },
{ selector: '.rufus-panel-container', reason: 'Rufus' },
{ selector: '.rufus-teaser-cx-container', reason: 'Rufus' },
{ selector: '#nile-inline_feature_div', reason: 'Rufus' },
{ selector: '[data-feature-name="nile-inline"]', reason: 'Rufus' },
{ selector: '[id^="nile-inline"]', reason: 'Rufus' },
{ selector: '[data-feature-name^="nile-inline"]', reason: 'Rufus' },
{ selector: '[id*="rufus"]:not(body):not(html)', reason: 'Rufus' },
{ selector: '[class*="rufus"]:not(body):not(html)', reason: 'Rufus' },
{ selector: '[data-component-type*="rufus"]', reason: 'Rufus' },
{ selector: '[data-action*="rufus"]', reason: 'Rufus' },
{ selector: '[data-csa-c-content-id*="rufus"]', reason: 'Rufus' },
{ selector: '[data-csa-c-slot-id*="rufus"]', reason: 'Rufus' },
];
const removeTarget = (target, reason) => {
// Already gone / not in document (prevents double-count across overlapping rules)
if (!target?.isConnected) return;
log(reason, target);
target.remove();
updateStats(reason);
};
const applyRule = rule => {
document.querySelectorAll(rule.selector).forEach(el => {
removeTarget(rule.parent ? el.closest(rule.parent) : el, rule.reason);
});
};
const cleanSearchClutter = () => {
// Special case: search clutter
document.querySelectorAll('#search .s-result-list.s-search-results > div:not([data-component-type="s-search-result"])').forEach(el => {
if (el.querySelector(".s-pagination-strip")) return;
removeTarget(el, "Search clutter");
});
};
const clearRufusDock = () => {
if (!document.body) return;
// Strip any rufus-* class Amazon re-applies for dock layout
const kept = [...document.body.classList].filter(c => !/rufus/i.test(c));
if (kept.length !== document.body.classList.length) {
document.body.className = kept.join(" ");
}
// Rufus sets inline padding when docked
document.body.style.paddingLeft = "";
document.body.style.paddingRight = "";
};
const sweep = () => {
// Skip DOM work if we're about to navigate away
if (redirectToAllResults()) return;
// Apply all rules
RULES.forEach(applyRule);
cleanSearchClutter();
clearRufusDock();
};
// ------------------------------------------------------------
// Mutation Observer
// ------------------------------------------------------------
let scheduled = 0;
let sweeping = false;
const scheduleSweep = () => {
// Coalesce bursts of Amazon DOM mutations into one rAF tick (keeps INP healthier)
if (sweeping || scheduled) return;
scheduled = requestAnimationFrame(() => {
scheduled = 0;
sweeping = true;
try {
sweep();
} finally {
sweeping = false;
}
});
};
// Initialize everything else
injectRufusStyle();
registerMenu();
createStatsBox();
updateStatsVisibility();
new MutationObserver(scheduleSweep).observe(document.body, { childList: true, subtree: true });
// Catch ads already in the initial HTML
sweep();