Save any Amazon list (wishlist, shopping list or idea list) to a spreadsheet with titles, prices, dates added, notes and product links.
Works on every Amazon store. Open the list you want to export, then run the script.
// Responsive Muse · Amazon Wishlist Exporter · v1.1 · 2026-10-22
// Exports the Amazon list you have open (wishlist, shopping list, idea list) to CSV or TXT:
// title, price, ASIN, link, date added, your comment, quantity wanted and priority.
// Works on any Amazon store (.com, .co.uk, .de, .es, .ca…). Runs only on amazon.*/hz/wishlist.
// The script makes no network requests of its own: Amazon loads the rest of the list as it
// scrolls. It never reads cookies, passwords or tokens.
(async () => {
const TOOL = 'Export Amazon list';
const FORMAT = 'csv'; // 'csv' (Excel, Sheets) or 'txt' (one product link per line)
if (!/^(www\.|smile\.)?amazon\.[a-z.]+$/.test(location.hostname) || !location.pathname.startsWith('/hz/wishlist/')) {
alert('Open one of your lists first: Account & Lists > Your Lists\n(for example amazon.com/hz/wishlist/ls)');
return;
}
// A small box on the page shows progress and asks before changing anything,
// so you never need to read or edit the console.
const many = (n, word) => `${n} ${word}${n === 1 ? '' : 's'}`; // 1 video, 2 videos
const panel = (() => {
const box = document.createElement('div');
box.style.cssText = 'position:fixed;right:16px;bottom:16px;z-index:2147483647;width:340px;max-width:calc(100vw - 32px);' +
'background:#111318;color:#e6e8ee;font:14px/1.5 system-ui,sans-serif;border-radius:12px;padding:16px;' +
'box-shadow:0 8px 30px rgba(0,0,0,.4);text-align:left';
const head = document.createElement('strong');
head.textContent = TOOL;
const msg = document.createElement('p');
msg.style.cssText = 'margin:8px 0 12px;white-space:pre-line';
const row = document.createElement('div');
row.style.cssText = 'display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end';
box.append(head, msg, row);
document.body.append(box);
const button = (label, primary, onClick) => {
const b = document.createElement('button');
b.textContent = label;
b.style.cssText = 'font:600 14px system-ui,sans-serif;padding:8px 14px;border-radius:8px;cursor:pointer;' +
(primary ? 'background:#0f766e;color:#fff;border:1px solid #0f766e' : 'background:none;color:#e6e8ee;border:1px solid #3a3f4b');
b.onclick = onClick;
row.append(b);
};
return {
text(t) { msg.textContent = t; },
ask(t, yes) {
msg.textContent = t;
row.replaceChildren();
return new Promise(r => {
button('Cancel', false, () => { row.replaceChildren(); r(false); });
button(yes, true, () => { row.replaceChildren(); r(true); });
});
},
stoppable(onStop) { row.replaceChildren(); button('Stop', false, onStop); },
actions(t, list) {
msg.textContent = t;
row.replaceChildren();
list.forEach(([label, primary, run]) => button(label, primary, run));
},
finish(t) { this.actions(t, [['Close', true, () => box.remove()]]); },
close() { box.remove(); },
};
})();
// Offer the result as a downloaded file or as clipboard text (a real click, so it always works)
const deliver = (summary, body, file) => {
const save = () => {
const a = document.createElement('a');
a.href = URL.createObjectURL(new Blob([/\.csv$/.test(file) ? '\ufeff' + body : body], { type: 'text/plain;charset=utf-8' }));
a.download = file;
a.click();
setTimeout(() => URL.revokeObjectURL(a.href), 5000);
panel.text(`${summary}\nSaved as ${file} (check your Downloads).`);
};
const copy = () => navigator.clipboard.writeText(body)
.then(() => panel.text(`${summary}\nCopied. Paste it into a spreadsheet or a note.`))
.catch(() => panel.text(`${summary}\nThe browser blocked the clipboard: use Download instead.`));
panel.actions(summary, [['Close', false, () => panel.close()], ['Copy', false, copy], ['Download', true, save]]);
};
const sleep = ms => new Promise(r => setTimeout(r, ms));
const rows = () => [...document.querySelectorAll('li[data-itemid]')];
// 1. Scroll to the end until no new items appear three times in a row
let last = -1, idle = 0;
while (idle < 3) {
window.scrollTo(0, document.documentElement.scrollHeight);
await sleep(1500);
const n = rows().length;
idle = n === last ? idle + 1 : 0;
last = n;
panel.text(`Loading your list… ${n} items`);
}
// 2. Read every item
const items = rows().map(li => {
const text = sel => (li.querySelector(sel)?.textContent || '').replace(/\s+/g, ' ').trim();
const link = li.querySelector('[id^="itemName_"]');
const asin = ((link?.getAttribute('href') || '').match(/\/dp\/([A-Z0-9]{10})/) || [])[1] || '';
const price = parseFloat(li.getAttribute('data-price'));
return {
title: (link?.getAttribute('title') || link?.textContent || '').trim(),
price: isFinite(price) ? price : '', // empty = currently unavailable
priceShown: text('.a-price .a-offscreen'),
by: text('[id^="item-byline-"]').replace(/^(by|de|von|par|di)\s+/i, ''),
added: text('[id^="itemAddedDate_"]'),
comment: text('[id^="itemComment_"]'),
wanted: text('[id^="itemRequested_"]'),
priority: text('[id^="itemPriority_"]'),
asin,
url: asin ? `${location.origin}/dp/${asin}` : '',
};
});
if (!items.length) {
panel.finish('No items found. Amazon may have changed its layout: please report it on responsive-muse.com.');
return 0;
}
// 3. Build the file and offer it
const cell = v => '"' + String(v).replace(/"/g, '""') + '"';
const body = FORMAT === 'txt'
? items.map(i => i.url).filter(Boolean).join('\n')
: ['Title,Price,Price shown,By,Date added,Comment,Wanted,Priority,ASIN,URL',
...items.map(i => [i.title, i.price, i.priceShown, i.by, i.added, i.comment, i.wanted, i.priority, i.asin, i.url]
.map(cell).join(','))].join('\n');
const name = (document.querySelector('#profile-list-name')?.textContent.trim() || 'amazon-list')
.replace(/[\\/:*?"<>|]+/g, '_');
deliver(`Found ${many(items.length, 'item')}.`, body, `${name}.${FORMAT}`);
return items.length;
})();
Bookmarklet: drag the middle button to your bookmarks bar, open www.amazon.com and click the bookmark. It runs the same script with the options above.
- Sends nothing anywhere. No fetch, XHR or external scripts. The only network activity is www.amazon.com itself loading your list.
- Never touches your login. It doesn't read cookies, passwords, tokens or browser storage.
- Only runs on www.amazon.com. Anywhere else it stops before doing anything.
- Short and readable. 124 commented lines, not minified or obfuscated.
- Shows its progress on the page. A small box tells you what it's doing and offers Download or Copy at the end.
- Same code for everyone. SHA-256 of the default version:
6f14940d42ac42f2…
Verify it yourself in 30 seconds
- Read it: every line is above, with comments.
- Search the code for
fetch,XMLHttpRequest,cookie,localStorageoreval. None of them appear. - Open the Network tab before running it: you'll only see requests to www.amazon.com.
How to use it
- Open Your Lists on your Amazon store and pick the list you want.
- Open the console: F12 or Ctrl+Shift+J (Cmd+Option+J on Mac). If Chrome asks, type
allow pastingand press Enter. - Copy the script, paste it in the console and press Enter. It scrolls to load the whole list, then shows a box: click Download (or Copy).
What you get
One row per product: title, current price (empty if unavailable), the price shown on the page, author or brand, date added, your comment, quantity wanted, priority, ASIN and a clean product link. Useful to track prices, share a list outside Amazon or keep a backup.
FAQ
Why is the price empty for some items?
Those products are currently unavailable or have no offer, so Amazon shows no price.
Can I export someone else's public wishlist?
Yes, if you can open it. The script reads the list on your screen.
Can I move my wishlist to another account?
Export it here, then add the products from the links in the file. Amazon has no import feature.
