JavaScript bookmarklets get far less use than they deserve. The default answer to any small browser task is now “there’s an extension for that,” and that answer costs time. I have watched senior engineers spend twenty minutes configuring a browser extension or a local proxy just to toggle a CSS class or read a hidden input, when a bookmarklet, a trick that has worked since the late 90s, would have done it in one click.
I thought I had seen every workflow trick going until I ended up debugging a broken WooCommerce checkout on a client’s iPad. No dev tools, no console, just me and a store owner losing patience. I wrote a bookmarklet on the spot to dump the cart transients into an alert box. Crude, old school, and it saved the project. Bookmarklets are tactical tools for the moments when the good tooling is not there.
Writing bookmarklets that hold up
The idea is simple enough: you save a script where a URL should go. Get the wrapping wrong, though, and you introduce scope conflicts that break the page you were trying to fix. Wrap the whole thing in an Immediately Invoked Function Expression (IIFE) so nothing leaks into the global namespace.
The gap between a naive script and one you would actually keep around is worth a look. An arrow function inside the IIFE keeps it short.
/* The Naive Approach: Likely to cause a Race Condition or Global Conflict */
javascript:var x = document.querySelectorAll('div'); console.log(x);
/* The Senior Approach: Encapsulated and Encoded */
javascript:(()=>{const%20elements=document.querySelectorAll('div');console.log(elements);})();
URL-encode the script. Browsers are fussy about special characters in the address bar, and I have had a single unescaped semicolon fail silently in Safari while Chrome ran the same thing without complaint. For anything complex, push it through encodeURIComponent() or a dedicated tool so one awkward character does not kill it.
A better way to manipulate CSS
The usual move is injecting a <style> tag. It works, but it is blunt. For finer control, talk to the CSSStyleSheet API directly and edit the CSS Object Model without adding nodes to the DOM tree.
javascript:(() => {
const sheet = new CSSStyleSheet();
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
sheet.insertRule("body { border: 5px solid #663399 !important; }", 0);
console.log("CSSOM updated via Bookmarklet.");
})();
For visual debugging this is much cleaner, which is the same point I made in the guide on gamepad API visual debugging. You can update rules one at a time without the flicker you get from re-injecting style tags.
Why some sites block your bookmarklet
JavaScript bookmarklets have one serious enemy: Content Security Policy (CSP). I once spent an hour on a simple data scraper bookmarklet on a high security banking site before I worked out that the browser was killing it silently, because 'unsafe-inline' scripts were forbidden.
Under a strict CSP your bookmarklet may not be able to fetch external resources, or run inline code at all. A “Refused to execute script” message in the console means you have hit that wall. So keep the good ones self-contained, and avoid script.src injections unless you know the target site allows cross-origin requests from your domain.
If this kind of JavaScript work is eating your dev hours, hand it over. I have been doing WordPress since the 4.x days.
Worth keeping in the toolbox
Bookmarklets are simple, and that is the point of them. They will not replace a proper frontend/backend sync workflow, but they install in seconds and they keep working in locked-down environments where the usual dev tools are off the table. Build up your own collection of snippets and you will reach for it more often than you expect.