← back to Apartmentwallpaper
public/buybutton.js
71 lines
/* Apartment Wallpaper — on-site buying via the Shopify Buy Button SDK.
* Customers add to cart + check out WITHOUT leaving apartmentwallpaper.com
* (checkout opens in Shopify's secure hosted modal; never sends them to DW).
*
* Needs a Storefront access token — injected by the server as window.AW_CFG
* ({domain, storefrontToken}). Until the token is set, Add-to-Cart hides and
* the Sample flow remains the only CTA (graceful, never broken).
*/
(function () {
var CFG = window.AW_CFG || {};
if (!CFG.storefrontToken || !CFG.domain) {
// No token yet — leave Sample-only. Mark body so CSS can hide .buy-btn.
document.documentElement.classList.add('aw-no-buy');
return;
}
var SDK = 'https://sdks.shopifycdn.com/buy-button/latest/buybutton.js';
var client, ui, cartComp;
function load(cb) {
if (window.ShopifyBuy && window.ShopifyBuy.UI) return cb();
var s = document.createElement('script');
s.async = true; s.src = SDK; s.onload = cb;
s.onerror = function () { document.documentElement.classList.add('aw-no-buy'); };
document.head.appendChild(s);
}
function init() {
client = window.ShopifyBuy.buildClient({ domain: CFG.domain, storefrontAccessToken: CFG.storefrontToken });
ui = window.ShopifyBuy.UI.init(client);
var mount = document.createElement('div'); mount.id = 'aw-cart'; document.body.appendChild(mount);
ui.createComponent('cart', {
node: mount,
options: {
cart: {
startOpen: false,
text: { title: 'Your Cart', button: 'Checkout', total: 'Subtotal', notice: 'Shipping & taxes calculated at checkout' },
styles: { button: { 'background-color': '#1a1a1a', ':hover': { 'background-color': '#333' }, 'border-radius': '6px' } }
},
toggle: { styles: { toggle: { 'background-color': '#1a1a1a', ':hover': { 'background-color': '#333' } } } }
}
});
}
// Add the first non-sample variant of a Shopify product to the cart, open it.
function addToCart(productId, btn) {
if (!client) return;
var orig = btn.textContent; btn.disabled = true; btn.textContent = 'Adding…';
client.product.fetch(productId).then(function (product) {
var v = (product.variants || []).filter(function (x) { return !/sample/i.test((x.title || '') + (x.sku || '')); });
var variant = (v[0] || product.variants[0]);
if (!variant) throw new Error('no variant');
var cart = ui.components.cart[0];
return cart.addVariantToCart(variant, 1).then(function () { cart.open(); });
}).then(function () {
btn.textContent = 'Added ✓'; setTimeout(function () { btn.disabled = false; btn.textContent = orig; }, 1800);
}).catch(function () {
btn.textContent = 'Sold out'; setTimeout(function () { btn.disabled = false; btn.textContent = orig; }, 1800);
});
}
// Delegate clicks on any .buy-btn[data-pid] (cards + product modal).
document.addEventListener('click', function (e) {
var b = e.target.closest && e.target.closest('.buy-btn[data-pid]');
if (!b) return;
e.preventDefault(); e.stopPropagation();
addToCart('gid://shopify/Product/' + b.getAttribute('data-pid'), b);
});
load(init);
})();