For developers and agencies

One script tag. Or one React component.

The storefront runtime is 19.6 KB gzip and loads the 3D viewer and try-on only when a shopper taps. It never touches your cart, checkout or product media.

Read the docs Talk to an engineer

API keys come from the dashboard. During the pilot the npm packages and the full API reference are shared with Founding Partners.

Quickstart: script tag

Put the target where the launcher should appear (usually under your product media):

<div id="trialhood-product"></div>
<script defer src="https://cdn.trialhood.com/sdk/v1/loader.js"
        data-api-base="https://analyst-attached-piece-him.trycloudflare.com"></script>
<script>
  function mountTrialhood() {
    Trialhood.mount({
      target: '#trialhood-product',
      storeId: 'st_…',          // public store id, never a secret
      productId: 'SKU-123',      // your product id
      variantId: 'SKU-123-BLK',  // optional
      consent: { analytics: false },
      strings: { tryOn: 'Try these on' },
    });
  }
  if (window.Trialhood) mountTrialhood();
  else window.addEventListener('trialhood:ready', mountTrialhood, { once: true });
</script>

Mount is idempotent per target. Call instance.update({ variantId }) when the shopper picks another variant, and instance.setConsent({ analytics }) when your cookie banner changes.

React and Shopify Hydrogen

import { Trialhood } from '@trialhood/sdk-react';

<Trialhood
  storeId="st_…"
  productId={productId}
  variantId={variantId}
  consent={{ analytics: consentGiven }}
  onStateChange={(d) => setState(d.state)}
/>;

The server renders an empty element and the runtime mounts after hydration, with its space reserved so the page does not shift. A Hydrogen product route example is in our repository (shared with pilot partners).

Weight and loading

  • Loader: 19.6 KB gzip (CI budget 30 KB), loads with your page.
  • 3D viewer and try-on: separate chunks, loaded on the first tap.
  • Face tracking: model and WASM self-hosted on our CDN, downloaded only after the shopper accepts the consent screen. The camera and tracking start only after Start camera.
  • Failure: any error or timeout (8 s) collapses the widget; your original media stays.

Content Security Policy

DirectiveAddWhy
script-srcthe SDK CDN origin; 'wasm-unsafe-eval' (try-on)loader and lazy chunks; the face tracker compiles WebAssembly
worker-srcblob: (and the SDK CDN origin for same-origin installs)the face tracker runs in a module worker
connect-srcthe API origin, the asset CDN origin, the SDK CDN originmanifest, session and events; 3D model downloads; tracker model and WASM
img-srcblob: and the asset CDN origintextures
style-srcnothing extra with constructable stylesheets; otherwise 'unsafe-inline'Shadow DOM style fallback

Events

The runtime sends only allowlisted events. Operational events (for example consent shown or try-on ready) are sent without analytics consent; behavioural events need it.

EventCategory
eligible_impressionbehavioral
viewer_openbehavioral
viewer_readyoperational
tryon_openbehavioral
ar_openbehavioral
consent_shownoperational
consent_resultoperational
camera_permission_resultoperational
tryon_readyoperational
tracking_lostoperational
variant_changedbehavioral
product_switchedbehavioral
snapshot_takenbehavioral
fallback_shownoperational
experience_closedbehavioral
add_to_cartbehavioral
purchasebehavioral

Developer questions

Will it slow down my store?

Our storefront script is under 20 KB and loads with your page. The 3D viewer, AR and try-on code load only when a shopper taps a button. If anything fails, shoppers see your original product images, never a broken widget. We will publish a before-and-after Lighthouse report.

Does it work with my theme?

On Shopify it’s a theme app block you place in the theme editor. Anywhere else it’s one script tag or a React component. Button text and colours are yours.