Marketplace Lens
A Chrome/Brave extension that enforces filters on Facebook Marketplace desktop web — the location filter that FB largely ignores on desktop, plus keyword and price rules. It works entirely in your own browser: it reads the listing cards already on the page and hides the ones that don’t match your rules. Nothing is sent anywhere.
Install (unpacked)
- Unzip this folder somewhere permanent (don’t delete it later — Chrome loads it from disk).
- Go to
chrome://extensions (or brave://extensions).
- Turn on Developer mode (top right).
- Click Load unpacked and select this folder.
- Pin the extension icon and open a Marketplace search page.
Two ways to open settings
- The toolbar icon opens the popup.
- A launcher pill sits at the top-right of every Marketplace page, just under Facebook’s nav bar — click it to open the same settings panel right there in the page. It reads “Filters” at rest, shows the hidden count when active, and spins “filtering…” while geocoding.
While the strict radius is geocoding cities, the pill spins and reads “filtering…”, then settles to the hidden count — so you can always tell it’s working rather than stuck. City lookups run in parallel (up to 5 at once) and are cached, so the first filter on a new area is quick and repeats are instant.
Filtering vs. re-querying (how it works)
The extension uses both approaches, each where it’s strongest:
- Server-side re-query (Facebook narrows results before they load): Recency, sort-newest, local-pickup-only, and price are written into Facebook’s own search URL params (
daysSinceListed, sortBy=creation_time_descend, deliveryMethod=local_pick_up, minPrice/maxPrice). When you change these, the page reloads and FB returns a freshly-filtered, freshly-sorted result set — so junk isn’t just hidden, it’s never fetched. This is applied on search and category pages, and re-applied automatically when you click into a new category.
- Client-side sieve (hides already-loaded cards): Radius and keywords stay client-side on purpose. Radius especially — FB’s server-side radius is the loose, unreliable thing you’re trying to escape, so we ignore it and enforce a strict distance ourselves on what loads.
Why location can’t be a clean server-side re-query
Unlike recency/price/sort, Facebook’s web app doesn’t take a dependable location URL param:
- Appending
latitude/longitude/radius to facebook.com is unreliable — the web app tends to override geo query params with your account’s saved location.
- Actually switching the search city requires Facebook’s internal location ID (obtained only via its private GraphQL API with auth tokens) — reverse-engineering that is brittle and against FB’s terms, so this extension doesn’t.
- And FB’s radius is the loose one to begin with — re-querying with it wouldn’t enforce anything strictly.
So strict client-side radius is the correct primary tool for location, not a fallback. As an opt-in best-effort, “Also steer Facebook’s search to this center” appends your geocoded center + a padded radius to the search URL: when FB honors it you load less out-of-area junk; when it doesn’t, the strict radius still enforces. It never strips FB’s own geo params.
So: FB does the coarse server-side narrowing it’s good at; we do the strict enforcement it’s bad at.
Filters
- Location → Show only these / Always hide these — text whitelist / blacklist, one per line (case-insensitive substring).
- Hide listings with no readable location — drops cards whose city/state can’t be parsed (recommended ON).
- Radius (strict mile cutoff) — set a center (US ZIP or
City, ST) and a miles value; each city is geocoded once, cached, and anything past the cutoff is hidden. The hard radius FB won’t enforce on desktop.
- Recency → Listed within — Any time / 24 hours / 7 days / 30 days. Re-queries Facebook server-side by setting
daysSinceListed and reloading. Works on any results surface — the Browse all feed, a category, or a search — but not on item pages. The popup’s status line tells you live whether it’s active on this page, will apply here, or needs a results page. (FB still has no “older than N”, and cards carry no date, so that remains impossible.)
- Sort newest first / Local pickup only — server-side, via FB’s own params (also search/category pages).
- Keywords → Must include / Exclude — matched against the whole card text.
- Price Min / Max — pushed to FB server-side and enforced locally as a backstop.
- Display → Tidy layout — collapses the gaps left behind when cards are hidden (helps most on the masonry home feed). Best-effort layout override; toggle off if any page looks wrong.
- Display → Badge — bottom-right counter showing hidden count, radius, and recency window when active.
Changes save automatically. Server-side ones reload the page; client-side ones apply live.
How the radius works
FB doesn’t expose per-listing GPS in the feed, so the extension geocodes the city/state text on each card:
- Places are looked up via Open-Meteo geocoding; US ZIP centers via Zippopotam. Both are free and need no API key.
- Every lookup is cached in local storage, so after the first scroll through an area there are essentially no further network calls. A short queue keeps requests polite.
- Distance is a haversine from your center to the city centroid. So the cutoff is enforced at city granularity — a town whose center is 18 mi out is hidden under a 15 mi radius even if its edge is closer. For most “keep it local” use this is exactly what you want; if you need a town that straddles your line, nudge the radius up a couple miles or whitelist it by text.
- A card stays visible for the split second its city is being geocoded, then collapses if it’s out of range. Cached cities are instant.
How the rest works / limitations
- It finds listing cards via their
/marketplace/item/ links, reads the visible text, and parses price / title / location, then hides cards (collapsing the grid cell) that fail your rules.
- Location matching is text-based on the city/state shown on the card, not true GPS-radius. FB doesn’t expose per-listing coordinates in the feed, so a whitelist of towns is the reliable lever. For a strict radius, list every nearby town you’ll accept.
- Location parsing is tuned for
City, ST / City, Country formats. Unusual formats may read as “unknown.”
- Facebook’s HTML changes often. If a future FB update breaks parsing, the selectors in
content.js (the ITEM_SEL constant and parseCard) are where to adjust.
Files
| File |
Role |
manifest.json |
Extension config (MV3) |
content.js |
Reads cards + applies filters on the page |
content.css |
Hides filtered cards + styles the badge |
background.js |
Geocoding service worker (caches city → lat/lon) |
popup.html/.css/.js |
The filter control panel |
icons/ |
Toolbar icons |