Install on a custom site
A custom site is any storefront that is not installed through the Shopify app: a headless or framework frontend, or a Shopify theme where you add the script yourself. After onboarding you have a site id and a public ingest token. The token can only send events; it cannot read anything.
1. Add the script
Load the SDK once per page, as early as practical, and start it when it has loaded:
<script async src="https://cdn.dozenfold.com/sdk/v1.js" id="dozenfold-sdk"></script>
<script>
document.getElementById('dozenfold-sdk').addEventListener('load', function () {
window.Dozenfold.init({
siteId: 'site_…',
token: 'omz_pub_v1_…',
origin: window.location.origin,
consent: 'unknown', // updated by your consent banner, see step 2
release: 'web@2026.10.06', // optional: your build id
currency: 'EUR', // optional: default for order values
});
});
</script>
In a single-page app (React, Vue, Next.js, Nuxt), load it in the root layout, not per route. Page views on client-side navigation are captured automatically.
2. Connect consent
Collection follows the consent value. Call setConsent from your banner whenever the visitor
decides:
// Accepted analytics
window.Dozenfold.setConsent('granted');
// Declined, but your policy allows anonymous measurement
window.Dozenfold.setConsent('cookieless');
// Declined
window.Dozenfold.setConsent('denied');
cookieless stores nothing in the browser and sends no identifier. Replay and identify need
granted. If you already know the visitor’s choice when the page loads, pass it to init directly.
3. Report the journey
Dozenfold builds the funnel, page groups and revenue impact from journey stages. Call funnel where
your app knows them:
Dozenfold.funnel('product_viewed', { product_id: product.id });
Dozenfold.funnel('product_added_to_cart', { product_id: product.id });
Dozenfold.funnel('checkout_started');
Dozenfold.funnel('checkout_completed', { order_value: order.total, currency_code: order.currency });
checkout_completed with an order_value turns impact into money. Without it, impact reads as
missed orders per day. The full list of stages is in the SDK reference.
4. Map your page types
Shopify-style paths (/products, /collections, /cart, /search, /checkout) are recognised
without configuration. If your product pages live at /p/… or your listing pages at /shop/…, map
them so journeys and page groups line up:
pageTypes: { pdp: ['/p'], plp: ['/shop'], checkout: ['/pay'] }
5. Report handled errors and your framework’s errors
Errors your code catches are not reported automatically. Send the ones that matter:
// Vue
app.config.errorHandler = (error) => window.Dozenfold.captureException(error);
// React error boundary
componentDidCatch(error) { window.Dozenfold.captureException(error); }
6. Allow the hosts in your CSP
If the site sends a Content Security Policy, allow:
script-src https://cdn.dozenfold.comconnect-src https://ingest.dozenfold.com https://cdn.dozenfold.com
7. Verify
Open the live site in a normal browser, accept analytics, and browse a product, the cart and the
checkout. Within a few minutes the session appears in Sessions and the Overview leaves its
empty state. Pass debug: true to init to see in the console why something was not sent.
Automated browsers are not collected: Playwright, Puppeteer, Selenium, Lighthouse and headless Chrome sessions are dropped on purpose, so test with a regular browser. See No data is appearing if nothing shows up.
Next steps
- Upload source maps from CI so stacks point to your code: Source maps.
- Mark each deploy as a release: Releases.
- Turn on Error-session replay and Slack alerts.