Skip to main content

Shopify + LiveShopping

Integrate Bambuser Live Shopping with your Shopify store​

img

In order to integrate the Bambuser LiveShopping player into a Shopify store, you will need to add some code to your Shopify LiveShopping landing page (wherever you want to embed the player). The embed and integration codes can be added by adding script tags to your page content or theme codes.

Below you'll find a sample Shopify integration code that you can use when integrating Bambuser One-to-many player into your Shopify store.



Steps:

  1. Embed show(s) into a page πŸ”—
  2. Add the sample integration code to your page πŸ”—
  3. Add Conversion Tracking πŸ”—
Compatibility

Due to Shopify's technical limitations, the Miniplayer feature is not compatible with Shopify stores. You can read more about the Miniplayer compatibility here.


Get started​

Embedding a show​

The simplest way to embed a One-to-many show on a Shopify store page is to copy-paste the embed code to your page content. In the Bambuser dashboard, on each show setup page, you will find a code snippet that contains the embed code for that show. You can simply copy-paste it to any page (as HTML).

  1. Copy the embed code from the show setup page on the Bambuser dashboard.

    img

  2. On your Shopify page, switch the editor to HTML view.

    img

  3. Paste the embed code and save the page.

    img

Further customization

To learn more about the embed code, how to make it autoplay, or how to customize the triggering element, read the Initial Setup guide.

Embedding multiple shows on one page​

If you want to embed multiple shows on one page you can call window.initBambuserLiveShopping method multiple times to register more than one show.

Bind an element to trigger a live shopping show
window.initBambuserLiveShopping({
showId: 'BAMBUSER-LIVESHOPPING-SHOW-ID-HERE', // ShowID from the Dashboard
node: document.getElementById('myCoolClickableThing'), // Triggering element
type: 'overlay',
});

In the example below you see how to have more than one show embedded into your landing page.

Example code
<!-- Your very cool interactive element here provided with a id attribute -->
<div id="myCoolClickableThing-1">Watch episode 1</div>

<div id="myCoolClickableThing-2">Watch episode 1</div>

<script>
(function() {
if (!window.initBambuserLiveShopping) {
window.initBambuserLiveShopping = function(item) { window.initBambuserLiveShopping.queue.push(item) };
window.initBambuserLiveShopping.queue = [];
var scriptNode = document.createElement('script');
scriptNode['src'] = 'https://lcx-embed.bambuser.com/your-brand-name/embed.js';
document.body.appendChild(scriptNode);
}

// Multiple shows can be embedded in a single page as below
// node: The trigger element for opening the specified show
window.initBambuserLiveShopping({
showId: 'BAMBUSER-LIVESHOPPING-SHOW-ID-HERE',
node: document.getElementById('myCoolClickableThing-1'),
type: 'overlay',
});

window.initBambuserLiveShopping({
showId: 'BAMBUSER-LIVESHOPPING-SHOW-ID-HERE',
node: document.getElementById('myCoolClickableThing-2'),
type: 'overlay',
});
})();
</script>

Cart Integration​

To add product and cart functionalities to the player, you need to implement Cart Integration into your Shopify store.

Sample integration code​

Here you find a sample integration code that implements the Cart Integration feature into your Shopify store. This sample code works on almost all Shopify stores that have standard product models without any changes required. However, if you have a special product setup, you may need to modify the code to justify that with your case.

In the next section, we explain how you should add the integration code into your Shopify store.

Sample code
<script>
// Reduces server calls if a product has a crazy number of images.
const MAX_IMAGES_COUNT = 6;

// Extracts product handle from the product URL
const SHOPIFY_PRODUCT_URL_HANDLE_REGEX = /\/products\/(.[\w\d-+]+)/;

// Sometimes image URLs miss the protocol at the beginning
// E.g. '//cdn.shopify.com/s/files/.../image.jpg'
const urlSanitizer = url => {
if (typeof url === 'string') {
if (url.startsWith("//")) return `https:${url}`;
else if (url.toLocaleLowerCase().startsWith("http")) return url;
else console.log(`Not a valid URL: ${url}`);
} else console.log(`Not a valid URL: ${url}`);
return null;
};

//========== Shopify Ajax API Helper methods ===============

const storeApi = {};

storeApi.getProductByUrl = url => {
const handle = SHOPIFY_PRODUCT_URL_HANDLE_REGEX.exec(url);
if ((typeof handle[1] !== 'string') && (handle[1].length > 0)){
console.error('The provided URL is hhgfhghs')
return;
}
return fetch("/products/" + handle[1] + ".js", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
}).then(resp => resp.json());
};

storeApi.addToCart = itemId =>
fetch("/cart/add.js", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
items: [
{
quantity: 1,
id: itemId,
},
],
}),
}).then(resp => resp.json());

storeApi.updateItemInCart = (itemId, quantity) =>
fetch("/cart/update.js", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
updates: {
[itemId]: quantity,
},
}),
}).then(resp => resp.json());

storeApi.getCartState = () =>
fetch("/cart.js", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
}).then(resp => resp.json());

//=========== Bambuser onReady Handler =================

window.onBambuserLiveShoppingReady = player => {

// ---- Start of player configuration ----
const currency = document.cookie
.split('; ')
.find((row) => row.startsWith('cart_currency'));

player.configure({
currency: (currency && currency.split('=')[1]) || 'USD',
locale: "en-US",
buttons: {
dismiss: player.BUTTON.CLOSE,
},
});
// ---- End of player configuration ----

// ---- Start of Cart Integrations ----
player.on(player.EVENT.ADD_TO_CART, (addedItem, callback) => {
storeApi
.addToCart(addedItem.sku)
.then(res => {
if (res.items) {
callback(true);
console.log("Item added succussfully!");
} else if (res.description && res.description.includes("sold out")) {
callback({ success: false, reason: "out-of-stock" });
} else callback(false);
})
.catch(error => {
callback(false);
console.error("Add to cart error! ", error);
});
});

player.on(player.EVENT.UPDATE_ITEM_IN_CART, (updatedItem, callback) => {
console.log(`Cart updated! ${updatedItem.previousQuantity} --> ${updatedItem.quantity}`);
storeApi
.updateItemInCart(updatedItem.sku, updatedItem.quantity)
.then(res => {
if (res.items) {
callback(true);
console.log("Item updated succussfully!");
} else callback(false);
})
.catch(error => {
callback(false);
console.error("Error on updating item! ", error);
});
});

player.on(player.EVENT.SYNC_CART_STATE, () => {
// Use your method to check if the user has checkout
storeApi.getCartState().then(res => {
if (res.item_count == 0) {
// Emptying the in-player cart
player.updateCart({
items: [],
});
}
});
});

player.on(player.EVENT.CHECKOUT, () => {
// Use the showCheckout() method to safely
// navigate the user to your checkout page
player.showCheckout(window.location.origin + "/cart");
});
// ---- End of Cart Integrations ----

// ---- Start of Product Hydration ----
player.on(player.EVENT.PROVIDE_PRODUCT_DATA, (event) => {
// Iterates over all the products you have added to the show on the dashboard
event.products.forEach(({ ref: sku, id, url }) => {
// Your method to fetch a product data
storeApi.getProductByUrl(url).then((item) => {
//Uncomment the line below for testing
//console.log(item);
player.updateProduct(id, productFactory =>
productFactory.product(detailsFactory =>
detailsFactory
.name(item.title)
.sku(item.id)
.brandName(item.vendor)
.description(item.description)
.variations(variationFactory =>
item.variants.map(variation =>
variationFactory()
.attributes(attributeFactory => attributeFactory.colorName(variation.title))
.imageUrls([
// Adding the featured image of the chosen variation (if existed) at the beginning of the images array
...(variation.featured_image
? [variation.featured_image.src]
: []),
// Adding product imgaes
...item.images
.slice(0, MAX_IMAGES_COUNT - 1)
.map(url => urlSanitizer(url))
.filter(url => typeof url === 'string'),
])
.name(variation.title)
.sku(item.id)
.sizes(sizeFactory => [
sizeFactory()
.name(variation.title)
.sku(variation.id)
.inStock(variation.available)
.price(priceFactory =>
priceFactory
.original(variation.compare_at_price/100)
.current(variation.price/100)
)
])
)
)
)
);
});
});
});
};
</script>
How the Cart Integration works

For more detailed information about the Cart Integration feature and its implementation, read Cart Integration guide.

Adding integration code to your Shopify​

There are different ways to add the integration code to the Shopify store. You need to make sure that your integration code is included in all pages that you have the player embedded on.

(Option 1) Add to the page content​

Recommended if:

  • You only have a single landing page for the incoming traffic to the live show

Steps:

  1. Copy-paste the provided sample integration code to your page content (in HTML mode)

(Option 2) Add to all pages​

Recommended if:

  • You have the player embedded on multiple or all pages
  • You have the FAB widget embedded on all pages

Steps:

  1. In your Shopify theme codes, create a snippet and add the sample integration code there
  2. Assuming that you named the snippet bambuser-cart-integration.liquid, add this snippet to the theme.liquid layout as below:
    theme.liquid
    {% render 'bambuser-cart-integration'%}

(Option 3) Add to a specific page template​

Recommended if:

  • You have a set of pages where you embed the player

Steps:

  1. In your Shopify theme codes, create a snippet and add the sample integration code there
  2. Assuming that you named the snippet bambuser-cart-integration.liquid, you can add this snippet to your page template(s) as below:
    page.yourTemplateName.liquid
    {% render 'bambuser-cart-integration'%}

The result​

Once you have the cart integration working, you should be seeing the following behaviour:

  • The product prices are shown in the product list
  • Clicking a product shows the product details view in the player
  • You can add products to the cart
  • You can manage the cart and go to check out

img


Implement Conversion Tracking​

To set up the Bambuser Conversion Tracking in your store, on your Shopify Admin dashboard, append the code snippet below in Settings > Checkout > Order Processing > Additional Scripts.

<!-- START - BAMBUSER CONVERSION TRACKING -->
<script>
function onPurchase() {
var data = {
event: "purchase", // value needs to be β€œpurchase”
orderId: Shopify.checkout.order_id.toString(), // the order id
orderValue: Shopify.checkout.total_price, // total of all products in the order
orderProductIds: Shopify.checkout.line_items.map(n => n.product_id), // comma-separated string of all product ids in the order
currency: Shopify.checkout.currency, // the currency used for the order
};

// Send the conversion data above to Bambuser
window._bambuser.collect(data);
}
// Load the tracking library and sec invoke onPurchase() method
(function(){
var bamSrcElm = document.createElement('script');
bamSrcElm.src = 'https://cdn.liveshopping.bambuser.com/metrics/bambuser.min.js';
bamSrcElm.onload = onPurchase;
document.head.appendChild(bamSrcElm);
})();
</script>
<!-- END - BAMBUSER CONVERSION TRACKING -->

To find out more, see the Bambuser Conversion Tracking πŸ›’ documentation.
If you have any issues, check out the Conversion Tracking troubleshooting checklist.