Le Cache Misère (LCM) is a browser extension that filters car listings on supported websites containing problematic engines (PureTech, BlueHDi 1.5, etc.). Two hiding modes:
- Grey-out mode β listings are dimmed, grayscaled, and struck through; still visible but clearly marked
- Hide completely β listings are fully removed and replaced by a slim placeholder bar showing the vehicle title; clicking the bar reveals the listing in a faded "reviewed" state with a re-hide button
- Toggle filtering per website (on/off)
- Toggle filtering per motor type independently (PureTech, BlueHDi 1.5, THP, etc.)
- Hide completely β remove listings entirely and show a placeholder (default: on)
- Show placeholder icon β display the extension icon inside the placeholder bar
This is a Manifest V3 browser extension built with Vite + @crxjs/vite-plugin, React 18, MUI v6, and SCSS.
- Node.js 18+
- npm
npm install| Command | Description |
|---|---|
npm run dev |
Chrome dev mode β Vite with HMR on port 5173 |
npm run start:ff |
Firefox dev mode β watch build + auto-launch Firefox with reload |
npm run watch |
Watch build β updates dist/ on every save (no browser launch) |
npm run build |
TypeScript check + Vite build β dist/ |
npm run lint |
ESLint (TypeScript + React rules) |
npm run deploy |
Build + zip β le-cache-misere.zip |
npm run release |
Bump version, build, zip, push GitHub release |
| Context | Entry point | Purpose |
|---|---|---|
| Popup | src/main.tsx β App.tsx |
Settings UI β reads/writes chrome.storage.sync, sends messages to content scripts |
| Content script | src/content.tsx |
Runs on supported sites β applies/removes .lcm-disabled CSS class on matched listings |
The popup communicates with live tabs via browser.tabs.sendMessage. The content script also reads browser.storage.sync directly on page load for its initial state.
{
websites: {
title: string;
url: string;
active: boolean;
}
[];
motors: {
title: string;
active: boolean;
pattern: string;
}
[];
hideCompletely: boolean; // default: true
showPlaceholderIcon: boolean; // default: false
}All keys are initialised on first load from src/store/initialState.ts if missing. pattern is a case-insensitive regex string compiled at runtime.
Default motors:
PureTechβ pattern:puretech|pure[- ]techBlueHDi 1.5β pattern:(?=.*1\.5)(?=.*blue[- ]?hdi)(matches any order)
- On page load, the content script reads all storage keys and uses
initialState.tsdefaults for any that are missing - If the current URL matches an active website, active motor patterns are compiled into regexes
- Vendor-specific selectors identify listing card containers; each card's full text + ARIA attributes are tested against the regexes
- Matched cards either get
.lcm-disabled(grey-out) or.lcm-hide-completely+ a placeholder bar (hide mode), depending on thehideCompletelysetting - Clicking a placeholder sets
data-lcm-user-show="true"on the card β it reappears dimmed with a "Re-hide" button overlay - The popup sends partial state updates via
browser.tabs.sendMessage; the content script also stays in sync viabrowser.storage.onChangedfor cross-tab reactivity - A debounced
MutationObserverre-runs filtering automatically when the page DOM changes (e.g. infinite scroll)
- Run
npm run build - Open
chrome://extensions/ - Enable Developer mode (top right)
- Click Load unpacked β select the
dist/folder - After code changes, run
npm run buildagain and click the refresh icon on the extension card
Run npm run start:ff β this concurrently starts the watch build and launches Firefox with the extension auto-loaded and auto-reloaded on every dist/ change.
- Chrome:
chrome://extensions/β click Inspect views: popup.html under the extension - Firefox:
about:debuggingβ click Inspect next to the extension β open popup manually
Open DevTools on any supported site (F12) β Console tab. The content script runs in the page context, not the extension background.
In the extension's DevTools console (popup inspector):
chrome.storage.sync.get(null, console.log);To reset storage to defaults:
chrome.storage.sync.clear();This project is licensed under the PolyForm Noncommercial License 1.0.0.
Important
Commercial use is strictly prohibited without prior written permission from the author. This includes using this code in any project intended for commercial advantage or monetary compensation.
For more details, see the LICENSE file.