What gets hidden
| Signal | How it is detected |
|---|---|
| Sponsored / Ads | The reconstructed visible "Ad" / "Sponsored" label, or an ad call-to-action button such as "Shop now". |
| People you may know, Suggested, Reels, Pages for you | The module header's aria-label. |
| Accounts you don't follow | A Follow / Add friend / Join button in the post header. |
Everything else, meaning friends, Pages and people you already follow, groups you are in and your own posts, is kept. It also switches the home feed to Most recent (chronological) by redirecting facebook.com/ to facebook.com/?sk=h_chr, once per tab session so it can never loop; that can be turned off in the popup.
Why Facebook is the hard one
Facebook actively fights feed filtering, so naive text matching fails. Three specific tricks are worked around:
- No stable anchors. Class names are randomised and there is no
role="feed". The feed list is found heuristically as the element whose children are post cards, each containing an "Actions for this post" menu. - Decoy text and a scrambled "Sponsored". Hidden spans repeating "Facebook" poison
textContent, and the Sponsored label is rendered as dozens of single-character spans, real letters plus ~50 decoys, CSS-reordered and pushed outside the clip box. It even seeds decoy letters into non-ads as a honeypot. So the extension never trusts raw text: it keeps only the characters whose box lies inside the label's box, reads them left to right, and gets the true label ("Ad", "Sponsored", or a timestamp like "52m"). - Clean accessibility labels. Facebook keeps
aria-labels honest for screen readers, so those carry the reliable signals: ad buttons, module headers, and Follow / Add friend / Join buttons.
Options (toolbar popup)
- Filter feed: master on/off.
- Hide Sponsored / Ads, Hide Suggested & Reels, Hide accounts I don't follow: each independently.
- Dim instead of remove: fade and collapse hidden posts, hover to peek, so you can check what is being filtered.
- A live count of posts hidden on the current page.
What it can touch
| Manifest entry | Why it is there |
|---|---|
permissions: ["storage"] | Your popup settings, kept in chrome.storage.sync. That is the only permission requested. |
host_permissions | None. Not requested, not needed. |
content_scripts.matches: ["https://www.facebook.com/*"] | HTTPS only, and only facebook.com. No other site is touched. |
content_scripts.all_frames: false | Top-level document only; nothing is injected into embedded iframes. |
run_at: "document_start" | So the page is filtered as it renders rather than flashing unfiltered first. |
content_security_policy | script-src 'self': no remote code, no eval, no inline script. |
chrome.storage.sync (so they follow your Chrome profile) and nothing else is stored.What it does not do
- Does not post, react, comment, click or follow anything on your behalf.
- Does not read messages, your friends list, cookies, tokens or credentials.
- Does not touch the right-rail "Sponsored" boxes; they sit outside the main feed and are left alone.
- Does not load anything from the network, ever.
Honest caveats
- Facebook's ad obfuscation is a moving target. The visible-label reconstruction is robust today; if Facebook changes the technique,
renderedLabel()/hasSponsoredLabel()incontent.jsare where to adjust. For bullet-proof ad blocking a dedicated blocker with maintained filter lists is still the gold standard. - A friend who is also shown as a suggested follow is an edge case: relationship is read from the header buttons, so turn "Hide accounts I don't follow" off if it feels too aggressive.
Security
Follows the repo's shared security guidelines (the OWASP Browser Extension Vulnerabilities Cheat Sheet): storage is the only permission, the content script runs HTTPS-only in the top frame, a strict CSP forbids remote code, no innerHTML or eval, no network calls, and popup↔page messaging checks sender.id. A static audit (tests/owasp-audit.mjs) enforces all of that on every extension in the repo.
Install
- Download or clone the repo.
- Open
chrome://extensionsand turn on Developer mode (top right). - Click Load unpacked and choose the
chrome-extensions/facebook-remove-anything-i-dont-followfolder.