Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.hemsy.ai/llms.txt

Use this file to discover all available pages before exploring further.

Script Setup

<script
  src="https://hemsy.ai/hemsy-embed.js"
  data-hemsy-subdomain="your-store-subdomain"
  data-hemsy-selector=".hemsy-launcher"
  defer
></script>
Use a shared class selector like .hemsy-launcher when multiple elements should open Hemsy. Avoid reusing the same id on multiple elements. Any element matching data-hemsy-selector becomes a Hemsy launcher. The launch behavior is decided per element from attributes on that exact clicked element.

Required Attributes

  • data-hemsy-subdomain: Your Hemsy store subdomain. For mystore.hemsy.ai, use "mystore".
  • data-hemsy-selector: CSS selector for elements that should launch Hemsy.

Script Attributes Reference

AttributeRequiredExampleDescription
data-hemsy-subdomaintrue"mystore"Your Hemsy store subdomain.
data-hemsy-selectortrue".hemsy-launcher"CSS selector for elements that launch Hemsy.
data-hemsy-anonymous-idfalse"visitor-42"Anonymous visitor ID passed through to Hemsy for analytics and order metadata.

Launcher Attributes

Attach these to any element matching data-hemsy-selector.
AttributeExampleDescription
data-hemsy-auto-product-context"true"Auto-builds a closet payload from the current PDP variant. Falls back to scratch if no variant is detected.
data-hemsy-closet"eyJwcm9k..."Explicit URL-safe base64 closet payload. Use this for bundles or curated looks.
data-hemsy-flow"<flowId>"Adds a guided flow to the launch. Must be on the clicked launcher element.

Mode Resolution

Evaluated per clicked element, in this order:
  1. data-hemsy-auto-product-context="true": closet mode with a synthesized product payload, or scratch if no product variant is detected.
  2. data-hemsy-closet="<base64>": closet mode with that exact payload.
  3. Nothing else: scratch mode.
data-hemsy-flow composes with any of the above. A flow-only launcher opens scratch mode with the flow applied.

Examples

Scratch Launcher

<a class="hemsy-launcher" href="#">Design a look</a>

PDP Launcher

<button class="hemsy-launcher" data-hemsy-auto-product-context="true">
  Try with this product
</button>

Flow Launcher

<button class="hemsy-launcher" data-hemsy-flow="YOUR_FLOW_ID">
  Build a bed
</button>

Bundle Launcher

<button
  class="hemsy-launcher"
  data-hemsy-closet="YOUR_URLSAFE_BASE64_CLOSET_PAYLOAD"
>
  Try on Bed Bundle
</button>

Closet Payload

FieldRequiredTypeNotes
productstrueArray<object>Must contain at least 1 product.
products[].variantIdfalsenumber | stringPreferred identifier and most reliable.
products[].productIdfalsenumber | stringFallback identifier when variantId is unavailable.
products[].attributesfalseArray<{ key: string; value: string }>Optional line-item attributes passed through to checkout/cart create.
Each product must include at least one identifier: variantId or productId.

Minimal Closet Payload Example

{
  "products": [
    {
      "variantId": 1234567890,
      "attributes": [{ "key": "_bundleTitle", "value": "Starter Bundle" }]
    }
  ]
}

Resolution Rules

  • Best: provide variantId for each line item.
  • If variantId is missing, Hemsy falls back to productId.
  • attributes are preserved and passed to checkout line items.

URL-Safe Base64 Encoding

Hemsy expects URL-safe base64:
  • Replace + with -
  • Replace / with _
  • Remove trailing =
function toUrlSafeBase64(obj) {
  return btoa(JSON.stringify(obj))
    .replace(/\+/g, "-")
    .replace(/\//g, "_")
    .replace(/=+$/, "");
}
Always wrap data-hemsy-closet values in quotes. URL-safe base64 strings can contain = characters that will break unquoted HTML parsing.

Programmatic API

If you’d rather open Hemsy from JavaScript, use window.HemsyEmbed:
// Scratch
HemsyEmbed.open("scratch");

// Product context, auto-built from current page
HemsyEmbed.open({ payload: { autoProductContext: true } });

// Explicit closet payload
HemsyEmbed.open("closet", { closet: "YOUR_URLSAFE_BASE64_CLOSET_PAYLOAD" });

// Into a flow
HemsyEmbed.open("scratch", { flow: "YOUR_FLOW_ID" });

// Close
HemsyEmbed.close();

End-to-End Example

<script
  src="https://hemsy.ai/hemsy-embed.js"
  data-hemsy-subdomain="your-store-subdomain"
  data-hemsy-selector=".hemsy-launcher"
  data-hemsy-anonymous-id="visitor-42"
  defer
></script>

<!-- Nav: design anything from scratch -->
<a class="hemsy-launcher" href="#"> Design a look </a>

<!-- PDP: try with the product currently on screen -->
<button class="hemsy-launcher" data-hemsy-auto-product-context="true">
  Try with this product
</button>

<!-- Bundle: pre-loaded closet -->
<button
  class="hemsy-launcher"
  data-hemsy-closet="eyJwcm9kdWN0cyI6W3sidmFyaWFudElkIjoxMjM0NTY3ODkwLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJfYnVuZGxlVGl0bGUiLCJ2YWx1ZSI6Ik15IEJ1bmRsZSJ9XX1dfQ"
>
  Try on Bundle
</button>

<!-- Flow: guided build -->
<button class="hemsy-launcher" data-hemsy-flow="YOUR_FLOW_ID">
  Build a bed
</button>

Common Mistake

Do not use data-hemsy-trigger:
<a href="https://your-store.hemsy.ai/" data-hemsy-trigger="closet">
  Design Your Bed
</a>
data-hemsy-trigger is not a supported launcher configuration. Specify data-hemsy-selector on the script tag, then make the clickable element match that selector. Use this instead for a flow:
<script
  src="https://hemsy.ai/hemsy-embed.js"
  data-hemsy-subdomain="your-store-subdomain"
  data-hemsy-selector=".hemsy-launcher"
  defer
></script>

<a href="#" class="hemsy-launcher" data-hemsy-flow="YOUR_FLOW_ID">
  Design Your Bed
</a>
Or this for an explicit closet:
<a
  href="#"
  class="hemsy-launcher"
  data-hemsy-closet="YOUR_URLSAFE_BASE64_CLOSET_PAYLOAD"
>
  Design Your Bed
</a>