Skip to content
New Webhooks added: Inventory and Order modifications. Check the changelog →
Cartly Developers

Conversion Tracking & Custom Scripts

Two isolated injection surfaces for merchant scripts: site-wide Liquid layouts and order-confirmation React route. CSP nonce auto-injected. Multi-script snippets (async loader + inline config) both execute.

Two Surfaces

  • Site-wide (/admin/settings → Custom Scripts): analytics_config.custom_head_script / custom_body_script. Fires on every Liquid storefront page via {{ shop.custom_head_script }} in layouts/theme.liquid.
  • Order Confirmation (/admin/preferences → Checkout Scripts): analytics_config.order_status_head_script / order_status_body_script. Fires exclusively on the React storefront.checkout.success route, gated by (!error && order).

Storage

JSONB column shops.analytics_config. Site-wide and order-status keys are disjoint — they no longer collide (previous bug: last save won).

CSP Nonce

injectScriptNonce() in frontend/liquid-service.mjs patches every <script> tag in the merchant HTML with the per-request CSP nonce. Merchants do not add nonces manually.

Multi-Script Support

executeMerchantHTML (React) clones every <script> node via document.createElement('script') — the HTML-spec path for reliable execution of dynamically-inserted scripts. Paste a Google Ads snippet with two script tags and both execute.

Platform Governance

PATCH /platform/analytics — super-admin enables/disables custom scripts globally. Merchant editor shows a hint when disabled.

Theme Integration

Add to layouts/theme.liquid:

{{ shop.custom_head_script }}
</head>
<body>
{{ shop.custom_body_script }}

Boilerplate and Minimal already include these. Clarity/Linen/Mono follow in v1.23.

Full guide →