Bookmarklets that I’m currently using in my own workflow, these may be unique to me, however some may be useful in your day to day!
To add / use a bookmarklet to Google Chrome:
- Add a new bookmark & name it
- Paste the code into the URL box
- Visit the site you want to use the bookmarklet on
- Click the bookmarklet in your bookmark bar
On-page
Pull on page metrics such as: Number of headings, word count, links.
This bookmarklet includes a copy to clipboard button which allows you to easily paste the data straight into a a table format.

javascript:(function() {
function countHeadings() {
return ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].reduce((counts, tag) => {
counts[tag] = document.getElementsByTagName(tag).length;
return counts;
}, {});
}
function countWords() {
return document.body.textContent.split(/\s+/).length;
}
function countLinks() {
const allLinks = document.links;
return [...allLinks].reduce((counts, link) => {
if (link.hostname === window.location.hostname) {
counts.internalLinks++;
} else {
counts.externalLinks++;
}
return counts;
}, { internalLinks: 0, externalLinks: 0 });
}
function copyToClipboard(text) {
const input = document.createElement('textarea');
input.style.position = 'fixed';
input.style.opacity = 0;
input.value = text;
document.body.appendChild(input);
input.select();
document.execCommand('Copy');
document.body.removeChild(input);
copyButton.innerHTML = 'Copied!';
setTimeout(() => {
copyButton.innerHTML = 'Copy to clipboard';
}, 1000);
}
function closeAlert() {
document.body.removeChild(alertBox);
}
const headingCounts = countHeadings();
const wordCount = countWords();
const linkCounts = countLinks();
let message = '';
for (const heading in headingCounts) {
message += `${heading}'s:\t${headingCounts[heading]}\n`;
}
message += `\nWord count:\t${wordCount}\n\nLink counts:\nInternal:\t${linkCounts.internalLinks}\nExternal:\t${linkCounts.externalLinks}\n\n`;
const copyButton = document.createElement('button');
copyButton.innerHTML = 'Copy to clipboard';
copyButton.addEventListener('click', () => copyToClipboard(message));
const alertBox = document.createElement('div');
const title = document.createElement('h2');
title.innerHTML = 'On-page SEO bookmarklet';
alertBox.appendChild(title);
alertBox.innerHTML += message.replace(/\n/g, '<br>');
alertBox.appendChild(copyButton);
alertBox.style.cssText = `
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
border: 1px solid #999;
border-radius: 2px;
padding: 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
`;
const credit = document.createElement('div');
credit.innerHTML = 'Built by <a href="https://www.adambrown.uk/" target="_blank">AdamBrown</a>';
credit.style.cssText = `
font-size: 10px;
color: #999;
`;
alertBox.appendChild(credit);
document.body.appendChild(alertBox);
alertBox.addEventListener('click', (event) => event.stopPropagation());
document.addEventListener('click', closeAlert);
})();
Download internal link numbers into CSV

javascript: (function() {
const links = [...document.querySelectorAll('a')]
.filter(a => a.href.startsWith(location.origin))
.map(a => a.href);
const linkCounts = links.reduce((counts, link) => {
counts[link] = (counts[link] || 0) + 1;
return counts;
}, {});
const csv = Object.entries(linkCounts).map(([link, count]) => `${link},${count}`).join('\n');
const a = document.createElement('a');
a.href = 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv);
a.download = 'internal-links.csv';
a.click();
})();
Check what schema / structured data is used on a page
javascript:(function(){
function getSchemaTypes() {
var types = [];
var scripts = document.getElementsByTagName('script');
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].type === 'application/ld+json') {
var schema = JSON.parse(scripts[i].innerHTML);
types.push(schema['@type']);
}
}
return types;
}
function getStructuredData() {
var data = [];
var elements = document.querySelectorAll('[itemscope][itemtype]');
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
var type = element.getAttribute('itemtype');
data.push(type);
}
return data;
}
function showList(title, items) {
if (items.length === 0) {
return title + '\nNo items found';
}
var list = items.map(function(item) {
return '- ' + item;
}).join('\n');
return title + '\n' + list;
}
var schemaTypes = getSchemaTypes();
var structuredData = getStructuredData();
var message = showList('Schema Types', schemaTypes) + '\n\n' + showList('Structured Data', structuredData);
alert(message);
})();
Pull H1 & H2 tags – Excluding any heading tags found in grids, comments and tables.
The headings pulled can be changed within the headingtags line, if you need to exclude further words in heading tags that can also be found within the excludeWords line.

javascript:(function(){
var headings = [];
var headingTags = ['h2', 'h3'];
var excludeWords = ['articles', 'explore more', 'similar blogs', 'related', 'recent posts', 'more articles'];
headingTags.forEach(function(tag) {
var elements = document.body.querySelectorAll(tag);
for (var i=0; i<elements.length; i++) {
var heading = elements[i];
if (heading.offsetParent !== null && !heading.closest('.comments, .grid, .table')) {
var include = true;
excludeWords.forEach(function(word) {
if (heading.textContent.indexOf(word) !== -1) {
include = false;
}
});
if (include) {
headings.push(heading.textContent);
}
}
}
});
var output = headings.join("\n");
var textarea = document.createElement("textarea");
textarea.value = output;
document.body.appendChild(textarea);
textarea.select();
document.execCommand("copy");
document.body.removeChild(textarea);
alert("Headings copied to clipboard:\n" + output);
})();
Copy the number of words within <p> tags

javascript:(function() {
var paragraphs = document.getElementsByTagName('p');
var text = '';
for (var i = 0; i < paragraphs.length; i++) {
text += paragraphs[i].innerText + ' ';
}
var wordCount = text.split(' ').length;
var copyText = wordCount + ' words';
navigator.clipboard.writeText(copyText).then(function() {
alert('📜 Copied word count to clipboard: ' + copyText);
}, function(err) {
console.error('Async: Could not copy text: ', err);
});
})();