Introduction
Do you ever scroll through your Facebook feed only to be ambushed by those “Follow” posts that feel more like ads than updates? 😩 You’re not alone. Whether you’re a Gen Z meme lord, a social media strategist, or just someone who needs a cleaner news feed, this tutorial is for you. We’re going to walk through building a lightweight Chrome extension—no PhD in computer science required—that auto‑hides any feed post with a “Follow” button. By the end, you’ll have a slick, personalized filter that keeps your Facebook zen intact, saves you time, and might even earn you bragging rights at the next virtual hangout. Let’s get ghosting those pesky posts!
Code Block
/**
* DISCLAIMER: Use this script at your own risk. I take no responsibility for any consequences
* resulting from its use. This code is provided strictly for educational purposes and
* should not be used to violate any website’s terms of service or applicable laws.
*/
// manifest.json
{
"manifest_version": 3,
"name": "# EditThis: Your Extension Name",
"version": "0.2",
"description": "# EditThis: Brief extension description",
"permissions": ["scripting","webNavigation"],
"host_permissions": ["*://*.facebook.com/*"],
"content_scripts": [
{
"matches": ["*://*.facebook.com/*"],
"js": ["content_script.js"],
"run_at": "document_idle"
}
],
"background": { "service_worker": "background.js" }
}
// background.js
chrome.webNavigation.onHistoryStateUpdated.addListener(details => {
if (details.url.includes("facebook.com")) {
chrome.scripting.executeScript({
target: { tabId: details.tabId },
files: ["content_script.js"]
});
}
});
// content_script.js
console.log("✅ FB‑Follow blocker loaded");
const seen = new WeakSet();
function isFollowPost(post) {
return Array.from(post.querySelectorAll("span, button, a"))
.some(el => el.textContent.trim() === "Follow");
}
function findMenuButton(post) {
return post.querySelector("[data-testid='post_chevron_button']") ||
Array.from(post.querySelectorAll("[role='button']"))
.find(el => el.getAttribute("aria-label")?.toLowerCase().includes("more"));
}
async function hidePost(post) {
const menuBtn = findMenuButton(post);
if (!menuBtn) return console.warn("⋯ not found", post);
menuBtn.click();
const menu = await new Promise(resolve => {
const mo = new MutationObserver((_, obs) => {
const popup = document.querySelector("div[role='menu']");
if (popup) { obs.disconnect(); resolve(popup); }
});
mo.observe(document.body, { childList: true, subtree: true });
});
const hideItem = Array.from(menu.querySelectorAll("[role='menuitem']"))
.find(el => /Hide (all from|posts from)/i.test(el.innerText));
if (hideItem) hideItem.click();
else console.warn("Hide item not found", menu);
}
function injectHideButton(post) {
if (seen.has(post) || !isFollowPost(post)) return;
const menuBtn = findMenuButton(post);
if (!menuBtn) return;
const btn = document.createElement("button");
btn.textContent = "Hide";
Object.assign(btn.style, {
marginLeft: "4px",
padding: "2px 6px",
border: "none",
borderRadius: "3px",
background: "rgba(0,0,0,0.1)",
cursor: "pointer",
fontSize: "12px"
});
btn.title = "Hide this Follow‑style post";
btn.addEventListener("click", e => {
e.stopPropagation();
hidePost(post);
});
menuBtn.parentElement.appendChild(btn);
seen.add(post);
}
function scanPosts(root = document) {
root.querySelectorAll("div[role='article']").forEach(post => {
if (isFollowPost(post)) {
injectHideButton(post);
hidePost(post);
}
});
}
scanPosts();
new MutationObserver(records => {
records.forEach(rec => rec.addedNodes.forEach(n => {
if (n.nodeType === 1) scanPosts(n);
}));
}).observe(document.body, { childList: true, subtree: true });
window.addEventListener("scroll", () => scanPosts());
window.addEventListener("popstate", () => setTimeout(() => scanPosts(), 500));
setInterval(() => scanPosts(), 2000);
Instructions
- Create your extension folder: In your file system, make a new directory called
# EditThis: auto-block-fb-ads
. Inside it, create three files:manifest.json
,background.js
, andcontent_script.js
. - Populate
manifest.json
: Open the code block above, replace each# EditThis
placeholder with your own extension name, version number, and description. This file tells Chrome how to load and run your scripts. - Implement
background.js
: This service worker re-injects your content script on Facebook’s single-page navigation events. No tweaks needed unless you want custom URL patterns. - Customize
content_script.js
: All the magic lives here. The script finds any post with a “Follow” button, programmatically opens the post menu, and clicks the “Hide all from…” item. You can adjust text selectors or add more domains by editing the host patterns inmanifest.json
. - Load your unpacked extension: Go to
chrome://extensions
(orbrave://extensions
), toggle on Developer mode, click Load unpacked, and select your extension folder. - Test & iterate: Refresh Facebook, scroll your feed, and watch the console for “✅ FB‑Follow blocker loaded” in DevTools. If any posts slip through, open Inspector to tweak selectors in your script.
- Deploy & share: Once everything works, consider packaging and publishing on the Chrome Web Store or sharing the GitHub link. Encourage friends to try your feed-cleaning wizardry!
Elements to Consider
- 🔄 DOM Changes: Facebook’s HTML structure can shift; you may need to update selectors long‑term.
- ⚡ Performance: Multiple observers and interval scans can use CPU—adjust frequency if you notice lag.
- 🔐 Permissions: Only request the minimal host permissions you need to avoid user alarm.
- 📜 TOS Risks: Automating UI interactions could violate Facebook’s terms—deploy responsibly.
- 🌐 Cross‑Domain: If you use mobile or alternate subdomains, add them to
host_permissions
.
Conclusion
Congratulations—you’ve just built a beginner‐friendly, Gen Z‐approved Chrome extension that auto‑blocks those annoying Facebook “Follow” posts. Not only does this save time and reduce feed fatigue, but it also gives you a taste of real‑world web automation: using service workers, content scripts, and the webNavigation API. Give yourself a pat on the back—your news feed will never be the same!
If you found this tutorial helpful, drop a comment below with your favorite customization, share this post with fellow social media warriors, and don’t forget to check out more deep‑dive guides on my site. Happy coding, and may your feeds stay forever fresh! 🚀