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
| Directive | Add | Why |
|---|---|---|
script-src | the SDK CDN origin; 'wasm-unsafe-eval' (try-on) | loader and lazy chunks; the face tracker compiles WebAssembly |
worker-src | blob: (and the SDK CDN origin for same-origin installs) | the face tracker runs in a module worker |
connect-src | the API origin, the asset CDN origin, the SDK CDN origin | manifest, session and events; 3D model downloads; tracker model and WASM |
img-src | blob: and the asset CDN origin | textures |
style-src | nothing 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.
| Event | Category |
|---|---|
eligible_impression | behavioral |
viewer_open | behavioral |
viewer_ready | operational |
tryon_open | behavioral |
ar_open | behavioral |
consent_shown | operational |
consent_result | operational |
camera_permission_result | operational |
tryon_ready | operational |
tracking_lost | operational |
variant_changed | behavioral |
product_switched | behavioral |
snapshot_taken | behavioral |
fallback_shown | operational |
experience_closed | behavioral |
add_to_cart | behavioral |
purchase | behavioral |
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.