Live on this page

Both widgets are the real thing — a selection on the product page carries into the cart.

Product page
💐
Seasonal Bouquet
$25.00

Hand-tied · locally sourced

Cart
💐
Seasonal Bouquet
Qty 1
$25.00
Subtotal$25.00
Initializing…

Quick start

<!-- 1. styles + config, then the bundle -->
<link rel="stylesheet" href="https://cdn.birdchime.com/widget/bird.bundle.css">
<script>
  window.BirdApp = { config: { shop: 'your-store.myshopify.com' } };
</script>
<script src="https://cdn.birdchime.com/widget/bird.bundle.js" defer></script>

// 2. mount once ready (mount is async)
await window.BirdApp.ready;
const handle = await window.BirdApp.widget.mount(el);

// 3. keep the cart in sync — pass your Storefront cart as-is
window.BirdApp.sdk.setCart(cart);

The window.BirdApp object

One global, four members — you set config; the bundle fills in the rest.

window.BirdApp = {
  config,   // you set this — { shop, locale?, customer? }
  ready,    // Promise<sdk | null> — await before mounting
  sdk,      // BirdSDK instance (or null) — sdk.setCart(cart)
  widget,   // { mount(container, options?) }
}

Configuration

window.BirdApp.config — set it before the script loads. Only shop is required; everything else (settings, translations, timezone, availability rules) is fetched automatically.

FieldRequiredNotes
shopyesYour *.myshopify.com domain
localenoDefaults to 'en'
customerno{ id, tags, loggedIn } — needed only if the merchant uses customer-tag availability rules

Mounting

widget.mount(container, options?)Promise<MountHandle | null>. Default type is 'cart'; pass { type: 'product', item } for a product page. The handle is { destroy(), isMounted(), remount? }. Resolves null if mounting couldn't complete (check the console).

Keeping the cart in sync

Call sdk.setCart(cart) on load and whenever the cart changes. Pass your Storefront-API cart object as-is.

Notes

  • Browser-only. window.BirdApp exists only client-side — never reference it during server render (in Hydrogen, mount inside a useEffect).
  • ready never rejects. On init failure it resolves null (and mount() then resolves null) — check for null, don't .catch().
  • Loaded defer and CDN-cached — it never blocks your page render.