You have shoppers who browse your store, add items to cart, and leave. Then you have shoppers who browse, do not add to cart, and leave. The second group is bigger than you think. They liked something. They were not ready to buy. And you have no way to bring them back.
A wishlist fixes this. Not the bloated kind that requires an account and three clicks. A simple save button on every product page that stores items in a list the shopper can come back to. No login required. No friction. Just a heart icon and a reminder email two days later.
Here is how to build one in under an hour without a paid app.
What You Need
- A store platform that supports custom JavaScript (Shopify, WooCommerce, BigCommerce all do)
- Access to your theme files or a custom code snippet tool
- Browser localStorage (built into every modern browser, no setup needed)
- An email marketing tool that supports triggered emails (Klaviyo, Mailchimp, Omnisend)
Step 1: Add the Save Button to Your Product Page
Open your product page template and add a button next to the add-to-cart button. Keep it simple. A heart outline icon with the text “Save for later” works better than a generic wishlist icon nobody recognises.
Give the button an ID so you can target it with JavaScript:
<button id="wishlist-save" data-product-id="{{ product.id }}" data-product-title="{{ product.title }}" data-product-image="{{ product.featured_image }}">(Heart) Save for later</button>
Style it to sit beside the add-to-cart button, not below it. The save button should feel like a secondary action, not a competing one. Use a subtle outline style, not a filled button.
Step 2: Store Saved Items in localStorage
When a shopper clicks the save button, store the product details in their browser using localStorage. This means no account required and no server-side storage. The data lives in their browser and persists across visits.
Add this JavaScript to your product page:
document.getElementById('wishlist-save').addEventListener('click', function() {
let wishlist = JSON.parse(localStorage.getItem('wishlist') || '[]');
let product = {
id: this.dataset.productId,
title: this.dataset.productTitle,
image: this.dataset.productImage,
savedAt: new Date().toISOString()
};
if (!wishlist.find(p => p.id === product.id)) {
wishlist.push(product);
localStorage.setItem('wishlist', JSON.stringify(wishlist));
this.innerHTML = '(Heart) Saved';
}
});
This checks if the product is already saved, adds it if not, and changes the button text to confirm the save. No page reload, no popup, no friction.
Step 3: Build the Wishlist Page
Create a new page at /pages/wishlist that reads from localStorage and displays the saved items. The page should show each product with its image, title, price, and an add-to-cart button.
The key is making the page feel like a curated collection, not a shopping cart. Use a grid layout with generous spacing. Show prices but do not push urgency. These are items the shopper is considering, not committing to.
Read the saved items and render them:
let wishlist = JSON.parse(localStorage.getItem('wishlist') || '[]');
let container = document.getElementById('wishlist-items');
if (wishlist.length === 0) {
container.innerHTML = '<p>Your wishlist is empty. Browse our collection and save items for later.</p>';
} else {
wishlist.forEach(product => {
container.innerHTML += renderProductCard(product);
});
}
Add a “Remove” link on each card so shoppers can curate their list. And add a “Move all to cart” button for shoppers ready to buy everything at once.
Step 4: Add a Wishlist Counter to Your Header
Add a small counter next to your header cart icon that shows the number of saved items. This keeps the wishlist visible across every page and reminds shoppers they have items waiting.
let wishlist = JSON.parse(localStorage.getItem('wishlist') || '[]');
document.getElementById('wishlist-count').textContent = wishlist.length;
Run this on every page load. If the count is zero, hide the badge. If it is one or more, show the number. Simple.
Step 5: Capture Email Addresses for Recovery
This is where the wishlist becomes a recovery tool. Add a small form on the wishlist page that says “Email me my wishlist so I do not lose it.” When the shopper enters their email, send the wishlist contents to your email tool and trigger a reminder sequence.
Send the wishlist data to Klaviyo using their track API:
fetch('https://a.klaviyo.com/api/track', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
token: 'YOUR_KLAVIYO_KEY',
event: 'Wishlist Saved',
customer_properties: {email: userEmail},
properties: {items: wishlist}
})
});
Then build a triggered email in Klaviyo that sends 24 hours later with the subject “Your saved items are still waiting” and a link back to the wishlist page.
Step 6: Set Up the Reminder Email Sequence
One email is not enough. Build a three-email sequence:
- Email 1 (24 hours): “Your saved items are still waiting.” Show the top 3 items with images and a button to view the full wishlist.
- Email 2 (5 days): “Still thinking about these?” Show the items again with a small nudge like “Only 3 left in stock” if inventory data is available.
- Email 3 (12 days): “Your wishlist expires soon.” Create soft urgency. If you have a first-time buyer discount, mention it here. Do not discount the wishlist items directly.
Stop the sequence the moment someone buys any item from the wishlist. Nobody wants a reminder for something they already bought.
What to Measure
Track three numbers:
- Save rate: What percentage of product page visitors click save? Aim for 8 to 15 percent. Anything below 5 percent means your button is not visible enough.
- Email capture rate: What percentage of wishlist visitors enter their email? Aim for 20 to 30 percent.
- Recovery rate: What percentage of emailed shoppers buy within 14 days? Aim for 10 to 18 percent.
If your save rate is low, try moving the button above the fold or changing the icon. If your email capture rate is low, try offering a one-time discount for submitting the form. If your recovery rate is low, shorten the email sequence and add more specific urgency.
Why This Works Without a Loyalty Programme
Most wishlist apps tie the feature to a loyalty programme. That means accounts, points, and an extra layer of complexity most small stores do not need. The localStorage approach works because it removes every barrier between interest and action.
The shopper sees a product they like. They click one button. The item is saved. When they come back, the items are still there. If they give you their email, you can bring them back yourself. No account, no password, no friction.
The wishlist is not a feature. It is a recovery tool disguised as a convenience feature. Build it that way.
Want more like this? Join MOKU Club for free. Weekly resources, early access to new guides, and occasional templates you can actually use. Join below.



