DEV Community

Cover image for I built a Chrome extension that lets you blow up any webpage
Yuiko Koyanagi
Yuiko Koyanagi

Posted on

I built a Chrome extension that lets you blow up any webpage

I built a Chrome extension called Site Bomb. It does exactly one thing: you drop little bombs anywhere on a webpage, and the text near the blast gets physically blown apart, letter by letter.

It is completely useless. It is also genuinely satisfying when you're stressed.

Here's how it works, and the three things I had the most fun figuring out.

1. Turning page text into something you can blow up

You can't apply physics to a plain text node — a paragraph is one indivisible blob as far as the DOM is concerned. So before anything explodes, Site Bomb walks the page and rewrites every visible text node, wrapping each individual character in its own element:

string.split("").map((char) =>
  /\s/.test(char)
    ? " "
    : `<particle style="display:inline-block;">${char}</particle>`
);
Enter fullscreen mode Exit fullscreen mode

Now every letter is its own inline-block box that can be moved, rotated, and flung around independently — while the page still reads normally until a bomb goes off. Whitespace is preserved so the layout doesn't collapse.

2. The blast: a little bit of fake physics

When a bomb explodes, each particle (letter) looks at its distance from the blast center and gets pushed away with a force that falls off with distance — roughly an inverse-square feel, capped so close letters don't fly off to infinity:

const distX = this.x - blast.x;
const distY = this.y - blast.y;
const distance = distX * distX + distY * distY;

let force = 150000 / distance; // closer = stronger
if (force > 40) force = 40;    // clamp so it doesn't explode *too* hard

const rad = Math.asin((distY * distY) / distance);
this.velocityX = Math.cos(rad) * force * (distX < 0 ? -1 : 1);
this.velocityY = Math.sin(rad) * force * (distY < 0 ? -1 : 1);
Enter fullscreen mode Exit fullscreen mode

Then every frame each letter drifts by its velocity, slowly bleeding off speed (a crude friction) and rotating as it goes, all driven through a CSS transform inside a requestAnimationFrame loop. It's not real physics — it just has to feel explosive, and a distance-based force plus some decay gets you there surprisingly cheaply.

3. The bug that annoyed me for years: clicks getting eaten

The most satisfying fix had nothing to do with explosions.

Originally the click handler lived on document.body.onclick. That relies on the click event bubbling up to <body>. The problem: tons of sites call event.stopPropagation() on their own click handlers, so the event dies before it ever reaches body. The symptom was maddening — on some sites bombs only dropped intermittently, and you'd click five times and then all five would go off at once.

The fix was to stop relying on bubbling and listen on the way down instead,
using the capture phase:

document.addEventListener(
  "click",
  (event) => dropBomb(event),
  true // useCapture — fires before any element can stopPropagation()
);
Enter fullscreen mode Exit fullscreen mode

Capture-phase listeners run as the event travels from the root down to the target, before the bubbling phase where stopPropagation() usually lives. One true and clicks now register instantly, everywhere.

Keeping it well-behaved

Actually I released this a few years ago but then one day it got pulled from the Chrome Web Store because it didn't follow Chrome extension best practice.

So, whilst updating Manifest from V2 to V3 this time, I also made corrections to the following minor details.

A couple of small things that matter for an extension that injects into any site:

  • Minimal permissions. It only needs activeTab — temporary access to the current tab, granted when you click the toolbar icon. No "read all your data on every website" scare. (It's also Manifest V3, with the script injected via chrome.scripting.)
  • One click to toggle. Clicking the icon turns bomb mode on for that tab (with an ON badge), and clicking again turns it off — state is tracked per tab.
  • Don't break the page. A re-injection guard stops it from running twice, and elements like <script>, <input>, and <video> are skipped so the page stays usable.

Try it

If you ever want to blow up a webpage:

🔗 https://chromewebstore.google.com/detail/site-bomb/hnnabnffilimfgdcinlijkjkdemdonea?authuser=0&hl=ja

Top comments (1)

Collapse
 
frank_signorini profile image
Frank

This sounds like a fun project! Did you consider