Populate KiCad BOM Data from Digikey using Bookmarklets
Extract and Copy Part Information with a JavaScript Bookmarklet
The Problem
Creating a bill of materials is an essential part of circuit board design. Major distributors like DigiKey and Mouser have streamlined the component search and ordering process significantly by publishing online part catalogs. These vendors’ websites contain a ton of useful information for BOM population - much of it is required by assembly houses to populate components onto a fabricated circuit board.
The issue starts to arise when you need to collate a ton of data from DigiKey into your KiCad bill of materials. Manually copying and pasting part information from distributor websites can be tedious and error-prone.
The Solution
To streamline this process, we’ve created a handy JavaScript bookmarklet that extracts and copies fields like Manufacturer (Mfg), Manufacturer Part Number (MfgPN), Distributor (Dist), and Distributor Part Number (DistPN) in a tab-delimited format. This puts your DigiKey information into a convenient, tab-delimited format that can be copy-pasted into a part entry inside KiCad’s “Edit Symbol Fields” dialog. Automating this process with a bookmarklet saves time and ensures accuracy, making it easier to collect and organize the data you need for your projects.
A Short Demo
(Note: we recommend full screen, so that the demo is slightly easier to see.)
What is a Bookmarklet?
A bookmarklet is a small JavaScript program stored as a URL within a bookmark in a web browser. When you click the bookmark, the JavaScript code runs on the current page. This allows you to add custom functionality to web pages you frequently use, without needing to modify the pages themselves.
The Solution
The bookmarklet in question is shown below, in oneliner format to easily copy/paste into a browser bookmark:
javascript:(function(){function copyToClipboard(text){var textarea=document.createElement('textarea');textarea.value=text;document.body.appendChild(textarea);textarea.select();document.execCommand('copy');document.body.removeChild(textarea);}var url=window.location.href.toLowerCase();var dist=url.includes("digikey")?"DigiKey":url.includes("mouser")?"Mouser":"";var fieldMapping={"DigiKey Part Number":"DistPN","Manufacturer":"Mfg","Manufacturer Product Number":"MfgPN"};var data={};if(dist){data['Dist']=dist;}let rows=document.querySelectorAll('tbody.MuiTableBody-root tr');rows.forEach(row=>{let cells=row.querySelectorAll('td');if(cells.length>1){let key=cells[0].innerText.trim();let value=cells[1].querySelector('a')&&key==="Datasheet"?cells[1].querySelector('a').href:cells[1].innerText.trim();let values=value.split('\n').map(v=>v.trim()).filter(v=>v);if(key==="DigiKey Part Number"&&values.some(v=>v.endsWith("Cut Tape (CT)")){value=values.find(v=>v.endsWith("Cut Tape (CT)"));data[fieldMapping[key]||key]=value;}else if(values.length>1){data[fieldMapping[key]||key]=values[0];}else{data[fieldMapping[key]||key]=value;}}});var fields=["Dist","DistPN","Mfg","MfgPN"];var tabDelimitedText=fields.map(field=>data[field]||'').join('\t');copyToClipboard(tabDelimitedText);alert('Data copied to clipboard: '+tabDelimitedText);})();
And, for those of you who want to follow along with the exact JavaScript commands, here’s the script in a more human-readable format.
javascript:(function() {
function copyToClipboard(text) {
var textarea = document.createElement('textarea');
textarea.value = text;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
}
var url = window.location.href.toLowerCase();
var dist = url.includes("digikey") ? "DigiKey" : url.includes("mouser") ? "Mouser" : "";
var fieldMapping = {
"DigiKey Part Number": "DistPN",
"Manufacturer": "Mfg",
"Manufacturer Product Number": "MfgPN"
};
var data = {};
if (dist) {
data['Dist'] = dist;
}
let rows = document.querySelectorAll('tbody.MuiTableBody-root tr');
rows.forEach(row => {
let cells = row.querySelectorAll('td');
if (cells.length > 1) {
let key = cells[0].innerText.trim();
let value = cells[1].querySelector('a') && key === "Datasheet" ? cells[1].querySelector('a').href : cells[1].innerText.trim();
let values = value.split('\n').map(v => v.trim()).filter(v => v);
if (key === "DigiKey Part Number" && values.some(v => v.endsWith("Cut Tape (CT)"))) {
value = values.find(v => v.endsWith("Cut Tape (CT)"));
data[fieldMapping[key] || key] = value;
} else if (values.length > 1) {
data[fieldMapping[key] || key] = values[0];
} else {
data[fieldMapping[key] || key] = value;
}
}
});
var fields = ["Dist", "DistPN", "Mfg", "MfgPN"];
var tabDelimitedText = fields.map(field => data[field] || '').join('\t');
copyToClipboard(tabDelimitedText);
alert('Data copied to clipboard: ' + tabDelimitedText);
})();
Our hope is that this saves you some time, and prevents some errors from copy/pasting BOM info into your KiCad schematics.
Future Work
- Right now, this only supports DigiKey. Supporting Mouser component data links would be a relatively simple improvement!
- Adding component data to a local part database of commonly used parts would be helpful.