Settings
Cart Integration
When a customer adds an item to their cart from the wishlist page, Stashlist calls window.stashlistOnCartAdd(result). By default this redirects to /cart, but most themes have their own cart drawer or notification popup that needs to be triggered instead.
The Cart Integration section generates a ready-made snippet for your theme. Select your theme from the Theme preset dropdown, copy the snippet, and paste it into your theme's relevant snippet file; the UI tells you which file to edit. Then click Save & Apply.
How it works
Stashlist calls window.stashlistOnCartAdd(result) after every successful add-to-cart from the wishlist. The result object contains:
| Property | Description |
|---|---|
result.id | The cart item ID of the newly added line item |
result.key | The cart item key |
result.sections | Re-rendered section HTML if window.stashlistSections is defined |
To request section re-renders (e.g. to update the cart icon bubble count), define window.stashlistSections as an array of Shopify section IDs before Stashlist loads:
window.stashlistSections = ['cart-notification-product', 'cart-icon-bubble']; window.stashlistOnCartAdd(result) yourself using the properties above.
Product Metafields
Show extra product data on each card in the wishlist: things like materials, ratings, or custom attributes. Add a metafield and it appears on every wishlist card alongside the product title and price.
Adding a metafield
There are two ways to add a metafield:
- From your store: use the dropdown to browse metafields already defined in your Shopify store. Select one, give it a display label (e.g. "Material"), and click Add.
- By field key: enter the key manually in
namespace.keyformat (e.g.reviews.rating) if the metafield doesn't appear in the dropdown. Give it a label and click Add.
Display formats
| Format | Use for |
|---|---|
| Plain text | Strings, short labels (e.g. material, colour) |
| Score (e.g. 4.5) | Numeric rating values from review apps |
Reordering
Once added, drag metafields in the Card Layout section above to control the order they appear on each wishlist card.
Custom CSS
Write CSS that applies to your storefront without editing any theme files. Use it to tweak button colours, sizing, spacing, or any other visual aspect of Stashlist components. Click Save & Apply to push changes live immediately.
CSS class reference
A full list of Stashlist's CSS classes is available inside the Custom CSS section; click CSS class reference to expand it. Key classes include:
| Class | Targets |
|---|---|
.stashlist-wishlist-btn | The heart button on product pages and collection cards |
.stashlist-heart-icon | The SVG heart icon inside the button |
.stashlist-heart-path | The heart SVG path, useful for fill/stroke colour |
.stashlist-header-icon | The wishlist icon in the header/floating link |
.stashlist-wishlist-btn-wrapper | The wrapper div around each button |
.stashlist-toast | The toast notification popup |
Example
/* Change the heart icon colour */
.stashlist-heart-icon {
color: #e63946;
}
/* Make the button match your theme's border radius */
.stashlist-wishlist-btn {
border-radius: 4px;
} Wishlist Page Code
Write JavaScript that takes over the wishlist page's overall layout, the grid, heading, and empty state, by defining window.stashlistCustomPage. Optional and advanced; most stores never need this. If you just want to change how individual product cards look, use Product Card Code instead.
How it works
If window.stashlistCustomPage(container, items, renderCard) is defined, Stashlist calls it instead of rendering the page itself. The items array only contains raw wishlist entries, Stashlist hasn't resolved product or metafield data for them yet at this point, since each item's product data is normally fetched asynchronously as the page renders. Call renderCard with your own resolved product data if you want a default-styled card inside your custom layout.
The Wishlist Page Code section in your admin includes a live preview panel that runs your code's logic against real sample products from your store, useful for catching errors before you save. It shows your code's logic and real sample data, not your theme's exact visual styling, check the actual wishlist page on your storefront for that.
| Parameter | Description |
|---|---|
container | The wishlist page's root element (#stashlist-wishlist-page) |
items | Array of { item } entries, one per saved wishlist item. item is the raw wishlist entry (variantId, productUrl, productTitle, etc.), not resolved product data |
renderCard | Stashlist's default card renderer. Call as renderCard(item, product, metaValues) with product data you've fetched yourself to get a default-styled card |
Example
A minimal custom layout that adds its own heading and fetches each item's product data before handing it to renderCard:
window.stashlistCustomPage = function (container, items, renderCard) {
var heading = document.createElement('h2');
heading.textContent = 'My Saved Items (' + items.length + ')';
var grid = document.createElement('ul');
grid.className = 'my-wishlist-grid';
items.forEach(function (entry) {
var item = entry.item;
var handle = item.productUrl ? item.productUrl.split('/products/')[1] : null;
if (!handle) return;
fetch('/products/' + handle + '.js')
.then(function (r) { return r.json(); })
.then(function (product) {
var card = renderCard(item, product, {});
if (card) grid.appendChild(card);
});
});
container.innerHTML = '';
container.appendChild(heading);
container.appendChild(grid);
return true; // we're handling rendering ourselves
}; return false; falls back to Stashlist's built-in page layout. Omitting a return statement, or returning anything other than false, means Stashlist treats your code as having handled rendering, it will not fall back, so a function that forgets to return false can leave the page blank. If your code throws, Stashlist catches it, logs the error to the console prefixed [Stashlist Custom Code], and falls back to the default layout automatically, a bug in your custom script can never break the page for a shopper. Like Cart Integration, this code is saved once for your whole store, it isn't scoped per theme. To fully disable this feature, clear the textarea and save, an empty value removes the live code entirely.
Product Card Code
Write JavaScript that controls how each individual wishlist item's card renders by defining window.stashlistCustomCard. Use it to hide products conditionally, swap in a custom image, change the add-to-cart button, or replace a card's markup entirely.
How it works
Stashlist calls window.stashlistCustomCard(item, product, metaValues) once per wishlist item, after that item's product data has already been fetched, so unlike Wishlist Page Code, product is fully resolved here.
The Product Card Code section in your admin includes a live preview panel that runs your code's logic against real sample products from your store, useful for catching errors before you save. It shows your code's logic and real sample data, not your theme's exact visual styling, check the actual wishlist page on your storefront for that.
| Parameter | Description |
|---|---|
item | The raw wishlist entry (variantId, productUrl, productTitle, etc.) |
product | Resolved product data: title, price, images, variants, and more |
metaValues | Metafield values configured in Product Metafields, keyed by field |
Return null or false to hide the item. Return a DOM node, or an HTML string (parsed into a node automatically), to use as the card. Return anything else, or nothing, to use Stashlist's default card for that item.
Example: hide a product by metafield
window.stashlistCustomCard = function (item, product, metaValues) {
// metaValues is keyed by the field configured in Product Metafields,
// e.g. a metafield added there as "custom.hide_from_wishlist"
if (metaValues['custom.hide_from_wishlist'] === 'true') {
return null; // hides this item from the wishlist page entirely
}
// fall through (return nothing) to use the default card for everything else
}; Example: swap the product image from a metafield
window.stashlistCustomCard = function (item, product, metaValues) {
var altImage = metaValues['custom.wishlist_image'];
if (!altImage) return; // no override configured, use the default card
var title = (product && product.title) || item.productTitle;
var el = document.createElement('li');
el.className = 'stashlist-page__item';
var link = document.createElement('a');
link.href = item.productUrl || '#';
var img = document.createElement('img');
img.src = altImage;
img.alt = title;
img.style.width = '100%';
img.style.borderRadius = '8px';
link.appendChild(img);
el.appendChild(link);
var titleEl = document.createElement('p');
titleEl.className = 'stashlist-page__item-title';
titleEl.textContent = title;
el.appendChild(titleEl);
return el;
}; Example: change the add-to-cart button conditionally
window.stashlistCustomCard = function (item, product, metaValues) {
var isPreorder = metaValues['custom.preorder'] === 'true';
var el = document.createElement('li');
el.className = 'stashlist-page__item';
var title = document.createElement('p');
title.textContent = (product && product.title) || item.productTitle;
el.appendChild(title);
var btn = document.createElement('button');
btn.className = 'stashlist-page__item-atc';
btn.textContent = isPreorder ? 'Pre-order' : 'Add to cart';
btn.addEventListener('click', function () {
window.Stashlist.addToCart(item.variantId);
if (isPreorder) btn.textContent = 'Pre-ordered!';
});
el.appendChild(btn);
return el;
}; Cart & wishlist helpers
Both hooks can call the same window.Stashlist SDK Stashlist uses internally, so your custom markup doesn't need to reimplement cart or wishlist mutations:
| Method | Description |
|---|---|
window.Stashlist.addToCart(variantId) | Adds the given variant to the cart, same logic as the built-in add-to-cart button |
window.Stashlist.remove(variantId) | Removes the given variant from the customer's wishlist |
[Stashlist Custom Code] and falls back to the default card for that item only, the rest of the wishlist renders normally. Like Cart Integration, this code is saved once for your whole store, it isn't scoped per theme. To fully disable this feature, clear the textarea and save, an empty value removes the live code entirely.