Bambuser Live (web embed)
Client-side Live Shopping player. Wire Bambuser into a host repo that already owns UI, product lookup, cart, and wishlist — keep Bambuser-specific code thin.
References: cart-events · product-hydration · wishlist · miniplayer · player-api
Docs: Player API · Cart · Wishlist · Miniplayer · Inline player
Integration boundaries
| Surface | Role |
|---|---|
| Web embed / Player API | This skill — player, cart, hydration, wishlist, miniplayer, configure |
| Live REST API | Server-side — use bambuser-api |
| Product catalog feed | BamHub ingest; can replace PROVIDE_PRODUCT_DATA but cart events still required |
| Mobile Commerce SDK (Swift/Kotlin) | Out of scope |
| App Framework / Channels library | Out of scope |
Workflow
Complete each step before claiming that domain done. Open the linked reference when a gate applies — payloads and skeletons live there, not here.
- Embed — Copy brand-specific embed script URL + show id from BamHub → show Setup (match Global vs EU). Register one
window.onBambuserLiveShoppingReadybefore the embed script loads. Mount<bam-inline-player>and/or overlay viainitBambuserLiveShopping. Done when script region matches BamHub and ready hook runs before init. - Adapters — Declare host seams in
BambuserLiveAdapters(below). Done when every required domain has a host function mapped. - Cart + hydration — When in-player ATC or cart is shown: open product-hydration and cart-events; wire
PROVIDE_PRODUCT_DATA→updateProductand required cart events +locale/currency. Done when every required cart event has a handler and ATC is enabled (or Product Feed replaces hydration only). - Wishlist — When BamHub theme has wishlist on or the user asks for it: open wishlist; wire status + add/remove + open/login. Done when
updateWishlistStatusanswersPROVIDE_WISHLIST_STATUSand add/remove callbacks cover success andlogin-required/more-info-required. - Miniplayer / SPA — When dismiss/checkout/product use minimize, or host is SPA nav-behind: open miniplayer. Done when button config matches intent and SPA
NAVIGATE_BEHIND_TO(if MANUAL mode) routes without full reload. - Configure / chrome — When touching buttons, UI hide flags, cookies, tracking, theme, captions, playback, or other Player API surface: open player-api. Done when every touched key/method is applied inside the ready hook.
- Host UI — Compose rail, PDP, CartSheet beside the player with the same product/cart/wishlist data. Bambuser does not own those components.
Embed
| Region | BamHub host |
|---|---|
| Global | lcx.bambuser.com |
| Europe | lcx-eu.bambuser.com |
Copy the brand-specific embed script URL from BamHub → show Setup (match Global vs EU). Use that official Bambuser-hosted script only — do not invent a URL.
Inline player
<style>
bam-inline-player {
min-width: 320px;
min-height: 320px;
}
</style>
<bam-inline-player show-id="SHOW_ID_HERE"></bam-inline-player>
Mini-player is not supported for inline. Configure via onBambuserLiveShoppingReady the same as overlay.
Overlay (button trigger)
window.initBambuserLiveShopping({
showId: 'SHOW_ID_HERE',
node: document.getElementById('join-show'),
type: 'overlay',
})
Ready hook (before embed)
window.onBambuserLiveShoppingReady = (player) => {
player.configure({
currency: 'EUR', // required for cart
locale: 'en-US', // required for cart
})
// Domain handlers — see reference/
}
player and its methods exist only inside this handler.
Adapter contract
Map host APIs onto these seams. Cart/product/wishlist logic stays in the project.
type HostProduct = {
name: string
brand?: string
sku: string // product-level ref; size-level skus used for ATC / wishlist
introduction?: string
description?: string // text or HTML
defaultVariationIndex?: number
variations: Array<{
name: string
sku: string
colorName?: string
colorHexCode?: string
imageUrls: string[]
sizes: Array<{
name: string
sku: string // ATC / wishlist identity
inStock: boolean
currency?: string
current: number
original?: number
perUnit?: number
unitAmount?: number
unitDisplayName?: string
}>
}>
}
type BambuserLiveAdapters = {
getProduct: (ref: string, url: string) => Promise<HostProduct>
addToCart: (sku: string) => Promise<void>
updateCartItem: (sku: string, quantity: number) => Promise<void>
checkout: () => void | Promise<void>
getCartState?: () => Promise<{ items: { sku: string; quantity: number }[] }>
openHostCart?: () => void
getWishlistStatuses?: (skus: string[]) => Promise<Record<string, boolean>>
addToWishlist?: (sku: string) => Promise<void>
removeFromWishlist?: (sku: string) => Promise<void>
openWishlist?: () => void | Promise<void>
openWishlistLogin?: () => void | Promise<void>
}
Wire adapters inside onBambuserLiveShoppingReady. Host UI can share the same getProduct / cart / wishlist mutations without going through the player.
In-player cart needs the required cart event set or ATC stays disabled. Host-UI-only ATC still benefits from hydration; implement cart events if in-player ATC is shown.
Next.js notes
- Set
onBambuserLiveShoppingReadyin a client module that loads before the embed script. - Load embed with
next/script(strategy="afterInteractive") from env (e.g.NEXT_PUBLIC_BAMBUSER_EMBED_SRC). - Declare custom element / globals in a
.d.ts. - CSP: allowlist the Bambuser embed script origin from BamHub Setup for that region.
Rules
- One
window.onBambuserLiveShoppingReadyper page — merge integrations into a single handler. - All player listeners and
configurecalls go inside that handler. - Cart configs:
locale+currency. - In-player ATC → full required cart event set (cart-events).
- Live REST (
liveshopping-api) stays server-side (bambuser-api). - Bridge into host cart/wishlist/checkout; prefer host UI over Bambuser chrome when the project already has those surfaces.
- Match BamHub region (Global vs EU) for embed host.
- Embed script URL comes only from BamHub show Setup (or host env such as
NEXT_PUBLIC_BAMBUSER_EMBED_SRC). Do not invent or hardcode a defaultembed.jsURL. - Hydrate for cart-quality data unless Product Feed covers it — scrape alone is thin.