Bring civility back to the internet.
CivilityAI is a Chrome Extension that detects toxic comments on YouTube and Instagram using OpenAI's gpt-4o-mini model and automatically blurs them, overlaying a toxicity score badge so you can browse comments with peace of mind.
- Multi-platform support — works on both YouTube and Instagram out of the box.
- AI-powered toxicity detection — classifies every comment on a 0-100 scale using GPT-4o-mini.
- Automatic blurring — toxic comments (score 71-100) are blurred instantly; hover to reveal.
- Toxicity badges — color-coded badges (Safe / Mild / Toxic) show the score at a glance.
- Smart caching — scores are cached locally for 30 days to minimize API calls.
- Request deduplication — duplicate in-flight API calls are collapsed into one.
- Visibility-gated processing — only comments scrolled into view are classified (IntersectionObserver).
- Dynamic comment detection — new comments loaded via infinite scroll are picked up automatically (MutationObserver).
- SPA-aware — handles YouTube and Instagram single-page navigation seamlessly.
- Secure by design — your OpenAI API key is stored in a local file that is git-ignored.
- Enable/disable toggle — click the extension icon to turn toxicity detection on or off; state is saved and applies to all open tabs.
| Platform | Comment Types Detected |
|---|---|
| YouTube | All video comments and replies |
| Post comments, reel comments, modal/dialog comments |
| Score Range | Label | Behavior |
|---|---|---|
| 0 - 40 | Safe | No blur, green badge |
| 41 - 70 | Mild | No auto-blur, amber badge |
| 71 - 100 | Toxic | Auto-blurred, red badge |
git clone https://github.com/swapmali/CivilityAI.git
cd CivilityAICreate (or edit) the file config.local.js in the project root:
export const OPENAI_API_KEY = "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";Security note:
config.local.jsis listed in.gitignoreand must never be committed to version control.
- Open Chrome and navigate to
chrome://extensions/. - Enable Developer mode (toggle in the top-right corner).
- Click Load unpacked.
- Select the
CivilityAIproject folder. - The extension icon should appear in your toolbar.
Navigate to any YouTube video or Instagram post with comments. CivilityAI will automatically detect the platform, classify visible comments, and apply overlays.
Turning detection on or off: Click the CivilityAI icon in the toolbar to open the popup. Use the Enable on YouTube & Instagram switch to turn toxicity detection on or off. When off, existing badges and blur are removed and no new comments are classified until you turn it back on.
content.js MutationObserver + IntersectionObserver
│ detects & queues visible comments
│ (platform-aware: YouTube / Instagram)
│
▼ chrome.runtime.sendMessage
background.js Service worker — cache lookup, dedup, orchestration
│
├──► cache.js chrome.storage.local (30-day TTL)
│
└──► classifier.js OpenAI API call (gpt-4o-mini)
│
└── config.local.js API key (git-ignored)
The content script automatically detects the current platform by inspecting location.hostname:
- YouTube (
youtube.com) — uses the#content-textselector, which precisely targets comment text elements in YouTube's custom elements. - Instagram (
instagram.com) — uses structural selectors (ul li span[dir="auto"]) combined with heuristic filtering (excluding usernames, buttons, timestamps, and short UI text) since Instagram employs hashed CSS class names that change between deployments.
Both platforms share the same classification pipeline (background worker, cache, classifier) and visual treatment (blur + badge).
| File | Responsibility |
|---|---|
manifest.json |
Extension metadata, permissions, entry points |
content.js |
Platform detection, DOM observation, comment extraction, overlay application |
background.js |
Message handler, cache-first logic, request deduplication |
classifier.js |
OpenAI API integration, prompt construction, response parsing |
cache.js |
Read/write toxicity scores to chrome.storage.local |
overlay.js |
Blur and badge DOM manipulation (shared module) |
selectors.js |
YouTube and Instagram DOM selector constants |
constants.js |
App-wide configuration constants |
utils.js |
Hash generation, debounce, text normalization |
styles.css |
Blur transition and badge styling (platform-aware) |
config.local.js |
Local-only — your OpenAI API key |
popup.html / popup.js |
Extension popup — enable/disable toggle and stored state |
- The OpenAI API key is stored only in
config.local.js, which is excluded from version control via.gitignore. - No API key appears in any committed source file.
- The extension requests only the minimal permissions needed (
storage, YouTube host, Instagram host, OpenAI host). - All API communication uses HTTPS.
Instagram uses React with CSS modules, meaning class names are auto-generated hashes that change between builds. CivilityAI avoids relying on class names entirely.
Instead, the extension uses structural selectors (ul li span[dir="auto"]) to find candidate comment elements, then applies heuristic filtering to exclude false positives:
- Elements inside
<a>tags are skipped (usernames, hashtag links). - Elements inside
<button>tags are skipped (Like, Reply actions). - Elements inside
<time>tags are skipped (timestamps). - Text shorter than 3 characters is skipped (emoji reactions, single chars).
- Elements that are purely link wrappers are skipped.
This approach is resilient to Instagram's frequent DOM changes while accurately targeting comment text.
MIT