Skip to main content

Product Hydration

Product hydration lets your app push live pricing, stock levels, and product details into the Bambuser Shoppable Video player at runtime. When the player needs product data, it emits a provide-product-data event. Your app fetches the data from your own catalog and sends it back via invoke('updateProductWithData', ...).

Prerequisites

currency and locale must be set in the playerConfig block of your configuration; product hydration will not work without them:

playerConfig: {
currency: 'USD', // ISO 4217 three-letter code, required
locale: 'en-US', // BCP 47 locale tag, required
},

Handle the provide-product-data Event

The player fires this event at startup and again whenever a new product needs to be displayed. Handle it in your onEvent callback. On iOS the products array is nested under data.event; on Android it is at the top level:

ShoppableFeedScreen.tsx
import { Platform } from 'react-native';

function onEvent(e) {
const { type, data } = e.nativeEvent;

if (type === 'provide-product-data') {
const products = Platform.OS === 'ios'
? data?.event?.products
: data?.products;

hydrate(products ?? []);
}
}

Each entry in the products array has:

FieldTypeDescription
idstringBambuser-generated product ID. Pass this back to the player.
refstringYour product SKU. Use this to look up your own catalog.

Send Product Data Back to the Player

Call invoke('updateProductWithData', ...) for each product. The arguments string must start with the Bambuser product id in single quotes, followed by a comma and the product object:

ShoppableFeedScreen.tsx
async function hydrate(products) {
for (const product of products) {
const id = product.id;
const sku = product.ref;
if (!id || !sku) continue;

const source = await YourProductService.product(sku);
if (!source) continue;

const hydrationJson = `{
sku: '${source.sku}',
name: '${source.name}',
brandName: '${source.brand}',
introduction: '${source.shortDescription}',
description: '${source.description}',
variations: [
{
sku: '${source.variationSku}',
name: '${source.variationName}',
colorName: '${source.colorName}',
imageUrls: ['${source.imageUrl}'],
sizes: [
{
sku: '${source.sizeSku}',
currency: 'USD',
current: ${source.price},
original: ${source.originalPrice},
name: '${source.sizeName}',
inStock: ${source.stock},
}
]
}
]
}`;

await playerRef.current?.invoke(
'updateProductWithData',
`'${id}', ${hydrationJson}`,
);
}
}

Full Product Data Structure

The product object passed to updateProductWithData supports the following fields:

Product

FieldTypeRequiredDescription
skustringYesYour product SKU / identifier.
namestringYesProduct display name.
brandNamestringYesBrand name.
introductionstringNoShort introductory text.
descriptionstringNoFull description, supports HTML.
variationsarrayYesList of product variations (colors/styles).

Variation

FieldTypeRequiredDescription
skustringYesVariation SKU.
namestringYesVariation display name.
colorNamestringYesColor name shown in the variation selector.
colorHexCodestringNoHex color code, e.g. "#000000".
imageUrlsstring[]YesOrdered list of image URLs for this variation.
sizesarrayYesList of sizes/SKUs for this variation.

Size

FieldTypeRequiredDescription
skustringYesSize-level SKU.
namestringYesSize name, e.g. "Small", "XL".
currentnumberYesCurrent (sale) price.
originalnumberNoOriginal price, shown as strike-through.
currencystringYesThree-letter currency code, e.g. "USD".
inStocknumberYesAvailable stock quantity (0 = out of stock).
perUnitnumberNoPrice per unit (for bundle/multi-pack pricing).
unitAmountnumberNoQuantity per unit.
unitDisplayNamestringNoUnit label, e.g. "kg", "L", "st".

Notes

  • The player may fire provide-product-data multiple times during a session as new products become visible. Your hydration handler must be idempotent.
  • Fields not provided in your hydration response fall back to data previously scraped or manually set in the Bambuser dashboard.
  • You do not need to respond to every product in the array; omit any products you cannot find in your catalog and they will use their fallback data.
  • invoke is asynchronous and returns a Promise; await it when you need to chain further work or surface errors.
  • If you prefer a typed builder over raw string interpolation, construct the hydration object in JS and JSON.stringify it, then pass `'${id}', ${json}` as the arguments string.

Next Steps