Best Practices

Shopify Integration Guide

Install the Shopify Apps

Install the app using the link given to you by our team in your Shopify store. Once the app is installed, go to the Unify StoreApp settings, and enter the HMAC secret provided to you by our team in the Shopify app settings. This will allow the app to verify incoming requests from your storefront and ensure they are legitimate.

Ready your shop theme

Once the app is installed, you’ll need to expose data and listen to events on the pages you want to add widgets on.

Add the EAN13 on your product form

The Stock Widget and Store Availability Widget both need to know which item the customer is viewing. They read it from a DOM element on the product page using a CSS selector you provide.

In Unify, the Item ID is the product's EAN13. On the Shopify side, however, the EAN13 isn't necessarily stored in the barcode field — depending on your catalog it might live in the sku, or somewhere else. This is exactly why Unify lets you map which Shopify field holds the EAN13 in your Unify settings. The mapping configured in Unify is what's authoritative — the value you expose in the input below must come from that same field.

Add a hidden input element containing the product's EAN13 to your product template, replacing YOUR_EAN13_FIELD with the field you mapped in Unify (e.g. barcode, sku, …):

<input type="hidden" id="unify-item-id" value="{{ product.selected_or_first_available_variant['YOUR_EAN13_FIELD'] }}">

Any selector that uniquely identifies the element works (#unify-item-id, [data-unify-ean13], etc.).

Keep the input up-to-date when the variant changes

The widget reads the input value once at page load, then listens for change events to update. If your theme lets customers switch variants without a full page reload, you must update the input value and dispatch a change event every time the variant changes.

// In your theme's variant change handler
const eanInput = document.querySelector('#unify-item-id');

eanInput.value = newVariant.barcode; // or .sku — whichever field you mapped in Unify
eanInput.dispatchEvent(new Event('change', { bubbles: true }));

If the change event is not dispatched, the widget will keep showing stock for the originally loaded variant.

⚠️

Assigning input.value alone is not enough — the widget only reacts to events. Always dispatch change after updating the value.

📘

The exact integration depends on your theme and on the field you mapped in Unify. If you're not sure which field holds your EAN13 or where to add the input, our support team can help.

Unify StoreApp Widgets

Add the POS Navbar

The POS navbar is the core of the Unify StoreApp experience on your storefront – this will, on top of displaying the menu on your website, fire events and update the session to ensure all information is correctly up-to-date.

To do this, open your Shopify theme settings, and on the sidebar, click on the icon with three squares and a plus - then check the ‘Unify POS - Navbar” app integration.

Add the Stock Widget

To add the Stock Widget to your product pages, you can go into the Shopify theme editor and add the widget’s App Block to the desired location on your product pages.

In the App Block settings, there are multiple options to let you customize the behavior of the widget but two settings are required :

  • The API key – used to link your shop and your Unify organization
  • The Item ID selector – used to detect which item is currently selected on your product page.
    Once those two options are correctly filled in, your Stock Widget should show up without issues when in POS mode.

Listen to add-to-cart events

The Unify Stock Widget fires events when a seller chooses to add an item to the cart. For your convenience, we proxy all events of all widgets directly on the window element to make binding listeners easier.

On your end, inside your theme, add a listener for the event we fire to handle API requests & UI feedback when a product is added to the cart.

document.addEventListener('unify-stock:add-to-cart', async (event) => {
    console.log('[♾️ UNIFY] unify-stock:add-to-cart event received', event.detail);

    const variantId = event.detail.item?.reference;
    const isLocationStock = event.detail.source === 'location';
    const locationId = event.detail.locationId;

    if (!variantId) {
        console.error('[♾️ UNIFY] Missing variant ID in event detail', event.detail);
        return;
    }

    const formData = new FormData();
    formData.append('id', variantId);
    formData.append('quantity', '1'); // Hardcoded to 1 since the widget only allows adding one item at a time
    formData.append('properties[_unify_added_from_pos]', true);
    if (isLocationStock && locationId) {
        formData.append('properties[_unify_location_id]', locationId);
    }

    try {
        const response = await fetch('/cart/add.js', {
            method: 'POST',
            body: formData,
            headers: { 'Accept': 'application/json' }
        });

        const data = await response.json();

        if (!response.ok) {
            throw new Error(data.description || `HTTP ${response.status}`);
        }

        alert('✅ Cart updated!');

    } catch (error) {
        alert('❌ Error adding product to cart: ' + error.message);
    }
});

Did this page help you?