Developer API & events
Luv Upsell works on most themes with no code. When you want your own analytics, apps or theme to work with its offers, everything on this page is public and safe to build on.
window.LuvUpsell
Available once Luv Upsell has loaded (listen for luvupsell:ready):
versionandbuild: which version is runningshow(placement, options): show a popup now, to check your design on your own store.placementis"atc"(after add to cart) or"checkout"(before checkout). It shows the first live offer for that place, or the one named inoptions.offer_id, ignoring who the funnel is for and how often popups show, isn't counted in Insights, and returns a promise oftruewhen it showed.refresh(): read the cart again and redraw the blocks, after your own code changes the cartisOpen(): whether a popup is showingon(name, fn)andoff(name, fn): subscribe to the events below by name, without theluvupsell:prefix (for exampleLuvUpsell.on("added", fn)), and unsubscribe
function whenLuvUpsell(fn) {
if (window.LuvUpsell) fn();
else document.addEventListener("luvupsell:ready", fn, { once: true });
}
whenLuvUpsell(function () {
LuvUpsell.on("added", function (d) {
console.log("Taken from an offer:", d.offer_id, d.placement, d.items);
});
});
Events
Luv Upsell dispatches these on document. Each event's detail has placement, offer_id, arm ("a" or "b") and items (the product handles in the offer).
luvupsell:ready: Luv Upsell has loaded; itsdetailcarriesversionluvupsell:shown: a popup was shownluvupsell:added: a shopper added products from a popup or block;itemslists what was addedluvupsell:declined: a shopper said no thanks, closed the popup or tapped outside itluvupsell:closed: a popup closed
document.addEventListener("luvupsell:declined", function (e) {
console.log("Passed on", e.detail.offer_id, "at", e.detail.placement);
});
Hooks
Define window.LuvUpsellHooks to adjust what Luv Upsell does:
window.LuvUpsellHooks = {
// Return false to skip showing an offer (ctx: placement, offer_id, arm, items)
beforeShow: function (ctx) { return true; },
// Return false to skip an add (items: the lines about to be added)
beforeAdd: function (items) { return true; },
// Runs after an add, with the cart
afterAdd: function (cart) {}
};
Your own checkout buttons and block containers
- Add
data-luvupsell-checkoutto a custom checkout button so a before-checkout offer can show when it's clicked. The app embed's Extra checkout button selectors setting does the same without editing code. - Add
data-luvupsell-block="product"ordata-luvupsell-block="cart"to an empty element to place the product page bundle or the cart offer there yourself, on themes or page builders without app blocks. On a page that isn't the product's own, adddata-product-handlewith the product's handle.
Test mode works here too: with Test mode on in Settings, open your store with ?luvupsell_test=1 and your live funnels show only to you.
Questions? hi@customerluv.app — a founder answers every message.