Debug Websites with Bookmarklets
Professional debugging tools you can use on any website without opening DevTools.
Debugging Made Simple
While browser DevTools are powerful, sometimes you need quick debugging capabilities without the overhead. Bookmarklets provide instant debugging tools that work on any device, including mobile browsers where DevTools aren't available.
🔍 Why Use Debugging Bookmarklets?
- • Works on devices without DevTools access
- • Share debugging tools with non-developers
- • Quick access to common debugging tasks
- • Visual debugging without console knowledge
DOM and Element Inspection
🎯 Element Inspector
Click any element to see its properties
javascript:(function(){
document.body.style.cursor = 'crosshair';
function inspect(e) {
e.preventDefault();
e.stopPropagation();
var el = e.target;
var info = {
tag: el.tagName,
id: el.id || 'none',
classes: el.className || 'none',
dimensions: el.offsetWidth + 'x' + el.offsetHeight,
position: 'x:' + el.offsetLeft + ' y:' + el.offsetTop
};
alert(JSON.stringify(info, null, 2));
document.removeEventListener('click', inspect);
document.body.style.cursor = 'auto';
}
document.addEventListener('click', inspect);
})();
📐 Visual Box Model
Show margin, border, and padding for all elements
javascript:(function(){
var style = document.createElement('style');
style.innerHTML = `
* { outline: 1px solid red !important; }
*:before, *:after { outline: 1px solid blue !important; }
body * { background-color: rgba(255,0,0,0.05) !important; }
body * * { background-color: rgba(0,255,0,0.05) !important; }
body * * * { background-color: rgba(0,0,255,0.05) !important; }
`;
document.head.appendChild(style);
setTimeout(() => {
if(confirm('Remove debugging styles?')) {
style.remove();
}
}, 100);
})();
🌳 DOM Tree Visualizer
Display page structure hierarchy
javascript:(function(){
function getTree(el, depth = 0) {
var indent = ' '.repeat(depth);
var tag = el.tagName?.toLowerCase() || 'text';
var id = el.id ? '#' + el.id : '';
var classes = el.className ? '.' + el.className.split(' ').join('.') : '';
var tree = indent + tag + id + classes + '\n';
if(el.children && depth < 5) {
Array.from(el.children).forEach(child => {
tree += getTree(child, depth + 1);
});
}
return tree;
}
var tree = getTree(document.body);
var win = window.open('', 'DOM Tree', 'width=600,height=400');
win.document.write('<pre>' + tree + '</pre>');
})();
CSS and Styling Debug Tools
🎨 Computed Styles Viewer
See all computed styles for clicked element
javascript:(function(){
document.body.style.cursor = 'help';
function showStyles(e) {
e.preventDefault();
var styles = window.getComputedStyle(e.target);
var output = '';
['color', 'background-color', 'font-size', 'font-family', 'margin',
'padding', 'border', 'width', 'height', 'display', 'position'].forEach(prop => {
output += prop + ': ' + styles.getPropertyValue(prop) + '\n';
});
alert('Computed Styles:\n\n' + output);
document.removeEventListener('click', showStyles);
document.body.style.cursor = 'auto';
}
document.addEventListener('click', showStyles);
})();
🔍 CSS Rule Finder
Find which CSS rules apply to an element
javascript:(function(){
var sheets = document.styleSheets;
var rules = [];
for(var i = 0; i < sheets.length; i++) {
try {
var ruleList = sheets[i].cssRules || sheets[i].rules;
for(var j = 0; j < ruleList.length; j++) {
rules.push(ruleList[j].cssText);
}
} catch(e) {
console.log('Cannot access stylesheet:', sheets[i].href);
}
}
var search = prompt('Search CSS rules for:');
if(search) {
var matches = rules.filter(rule => rule.includes(search));
var win = window.open('', 'CSS Rules', 'width=800,height=600');
win.document.write('<pre>' + matches.join('\n\n') + '</pre>');
}
})();
📱 Responsive Breakpoint Tester
Test common viewport sizes
javascript:(function(){
var sizes = {
'Mobile': '375x667',
'Tablet': '768x1024',
'Desktop': '1920x1080',
'Custom': prompt('Enter custom size (WIDTHxHEIGHT):')
};
var choice = prompt('Choose size: ' + Object.keys(sizes).join(', '));
var size = sizes[choice];
if(size && size.includes('x')) {
var [width, height] = size.split('x');
window.resizeTo(parseInt(width), parseInt(height));
alert('Viewport resized to: ' + size);
}
})();
JavaScript and Performance Debugging
🐛 Error Monitor
Catch and display all JavaScript errors
javascript:(function(){
var errorLog = document.createElement('div');
errorLog.style = 'position:fixed;bottom:0;right:0;background:#000;color:#f00;' +
'padding:10px;max-width:400px;max-height:200px;overflow:auto;' +
'z-index:9999;font-family:monospace;font-size:12px;';
errorLog.innerHTML = '<strong>JS Error Monitor</strong><br>';
document.body.appendChild(errorLog);
window.onerror = function(msg, url, line, col, error) {
var errorInfo = new Date().toLocaleTimeString() + ' - ' + msg +
' (Line: ' + line + ')' + '<br>';
errorLog.innerHTML += errorInfo;
return true;
};
errorLog.onclick = function() {
if(confirm('Close error monitor?')) {
errorLog.remove();
window.onerror = null;
}
};
})();
⏱️ Performance Timer
Measure page load and interaction times
javascript:(function(){
var perf = window.performance;
var timing = perf.timing;
var navigation = perf.navigation;
var metrics = {
'Page Load Time': timing.loadEventEnd - timing.navigationStart,
'DOM Ready': timing.domContentLoadedEventEnd - timing.navigationStart,
'Time to First Byte': timing.responseStart - timing.navigationStart,
'DNS Lookup': timing.domainLookupEnd - timing.domainLookupStart,
'Server Response': timing.responseEnd - timing.requestStart,
'DOM Processing': timing.domComplete - timing.domLoading,
'Resources': perf.getEntriesByType('resource').length
};
var output = 'Performance Metrics (ms):\n\n';
for(var key in metrics) {
output += key + ': ' + metrics[key] + 'ms\n';
}
alert(output);
})();
📊 Memory Usage Monitor
Track memory consumption over time
javascript:(function(){
if(!performance.memory) {
alert('Memory API not available in this browser');
return;
}
var monitor = document.createElement('div');
monitor.style = 'position:fixed;top:0;right:0;background:#000;color:#0f0;' +
'padding:10px;font-family:monospace;font-size:12px;z-index:9999;';
document.body.appendChild(monitor);
var interval = setInterval(() => {
var mem = performance.memory;
var used = (mem.usedJSHeapSize / 1048576).toFixed(2);
var total = (mem.totalJSHeapSize / 1048576).toFixed(2);
monitor.innerHTML = 'Memory: ' + used + 'MB / ' + total + 'MB';
}, 1000);
monitor.onclick = () => {
clearInterval(interval);
monitor.remove();
};
})();
Network and Resource Debugging
🌐 Resource Analyzer
List all loaded resources with sizes
javascript:(function(){
var resources = performance.getEntriesByType('resource');
var byType = {};
resources.forEach(r => {
var type = r.name.split('.').pop().split('?')[0] || 'other';
if(!byType[type]) byType[type] = [];
byType[type].push({
name: r.name.split('/').pop(),
size: (r.transferSize / 1024).toFixed(2) + 'KB',
time: r.duration.toFixed(0) + 'ms'
});
});
var output = '';
for(var type in byType) {
output += '\n' + type.toUpperCase() + ' (' + byType[type].length + '):\n';
byType[type].forEach(r => {
output += ' ' + r.name + ' - ' + r.size + ' - ' + r.time + '\n';
});
}
var win = window.open('', 'Resources', 'width=800,height=600');
win.document.write('<pre>' + output + '</pre>');
})();
🔗 Broken Link Checker
Find all broken links on the page
javascript:(function(){
var links = document.querySelectorAll('a[href]');
var checked = 0;
var broken = [];
links.forEach(link => {
fetch(link.href, {method: 'HEAD', mode: 'no-cors'})
.then(response => {
checked++;
if(!response.ok && response.type !== 'opaque') {
broken.push(link.href);
link.style.backgroundColor = 'red';
}
if(checked === links.length) {
alert('Found ' + broken.length + ' potentially broken links');
}
})
.catch(() => {
checked++;
broken.push(link.href);
link.style.backgroundColor = 'red';
});
});
})();
Accessibility Debugging
♿ Accessibility Checker
Basic accessibility audit
javascript:(function(){
var issues = [];
// Check images for alt text
document.querySelectorAll('img').forEach(img => {
if(!img.alt) {
issues.push('Image missing alt text: ' + img.src);
img.style.border = '3px solid red';
}
});
// Check form labels
document.querySelectorAll('input, select, textarea').forEach(input => {
if(!input.getAttribute('aria-label') && !input.labels?.length) {
issues.push('Form input missing label: ' + (input.name || input.id));
input.style.border = '3px solid orange';
}
});
// Check heading hierarchy
var lastLevel = 0;
document.querySelectorAll('h1,h2,h3,h4,h5,h6').forEach(h => {
var level = parseInt(h.tagName[1]);
if(level > lastLevel + 1) {
issues.push('Heading skip: ' + h.tagName + ' after H' + lastLevel);
h.style.border = '3px solid yellow';
}
lastLevel = level;
});
alert('Accessibility Issues (' + issues.length + '):\n\n' + issues.join('\n'));
})();
🎯 Focus Order Visualizer
Show tab order of focusable elements
javascript:(function(){
var focusable = document.querySelectorAll(
'a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
var order = 1;
focusable.forEach(el => {
var label = document.createElement('div');
label.style = 'position:absolute;background:red;color:white;' +
'padding:2px 6px;font-size:12px;z-index:9999;' +
'border-radius:10px;';
label.innerText = order++;
el.style.position = 'relative';
el.appendChild(label);
});
alert('Tab order shown. Numbers indicate focus sequence.');
})();
Mobile Debugging
📱 Mobile-Specific Tools
These bookmarklets are especially useful on mobile devices where traditional DevTools aren't available:
- • Viewport size display
- • Touch event debugging
- • Orientation change detection
- • Mobile performance metrics
- • Console log viewer
📱 Mobile Debug Panel
All-in-one mobile debugging tool
javascript:(function(){
var panel = document.createElement('div');
panel.style = 'position:fixed;bottom:0;left:0;right:0;background:#000;' +
'color:#fff;padding:10px;font-size:12px;z-index:9999;';
function update() {
panel.innerHTML =
'Viewport: ' + window.innerWidth + 'x' + window.innerHeight + ' | ' +
'Screen: ' + screen.width + 'x' + screen.height + ' | ' +
'DPR: ' + window.devicePixelRatio + ' | ' +
'Orientation: ' + screen.orientation.type;
}
update();
window.addEventListener('resize', update);
window.addEventListener('orientationchange', update);
panel.onclick = () => {
panel.remove();
};
document.body.appendChild(panel);
})();
Creating Custom Debug Tools
These examples demonstrate the power of bookmarklet debugging. You can combine multiple techniques to create custom debugging tools tailored to your specific needs. Consider creating bookmarklets for:
- Framework-specific debugging (React, Vue, Angular)
- API response inspection
- WebSocket monitoring
- Local storage debugging
- Service worker inspection
- Animation performance testing
Debug Like a Pro
Master debugging with bookmarklets and never be without your tools again. Create your own custom debugging utilities or explore more advanced techniques.