Tracking events for ad conversions
Last updated:
A custom JavaScript event fires after a form submission or a successful Shopify cart addition. Use these events for ad tracking, CRM data, or storefront scripts. This article also shows how to save a ShareLink with a cart.
Starter, Standard, and Pro plan families, including their yearly variants, do not receive the tracking events in the List of events section. One exception applies: a Shopify iframe embed can still send add-to-cart events. This restriction does not apply to ShareLink events. ShareLinks need a plan that includes sharing.
Note: The form:submitted webhook was deprecated on 24 August 2026. It continues to send the same payload on every submission. There is no cut-off date. For a new integration, read submissions from the quotes API. The API also returns submission history.
List of events
-
Add-to-cart events use signCustomiserProductAddedToCart.
-
Custom design form submission events use signCustomiserFormSubmitted.
-
Quote form submission events use signCustomiserQuoteSubmitted.
Form and quote events fire only when the customer customiser runs inline on the storefront page. They do not reach a Sign Customiser iframe embed. The Use iframe (experimental) setting on the Sign Customiser block creates an iframe embed. A Shopify iframe embed does send add-to-cart events to the storefront page. ShareLink events also reach the storefront page.
How to listen to these events
Add this JavaScript to your storefront theme:
document.addEventListener("signCustomiserProductAddedToCart", function (event) { useCartEvent(event.detail);});Replace useCartEvent with your tracking or integration code.
Add-to-cart event detail
{ customiserId: "25", cart: { ... }, domain: "your-store.myshopify.com", adClickIds: { gclid: "CjwKCAjw7p6aBhAoBhAAEiwA..." }, utmParams: { utm_source: "google", utm_medium: "cpc", utm_campaign: "spring_sale" }}cart is the Shopify cart/add.js response for the added line. For the full contract, read the Storefront JavaScript events guide.
Form submission event detail
{ customiserId: "25", formId: 1241, data: [ { fieldId: "abc123", label: "First name", value: "Jane" } ], domain: "your-store.myshopify.com", adClickIds: { gclid: "CjwKCAjw7p6aBhAoBhAAEiwA..." }, utmParams: { utm_source: "google", utm_medium: "cpc", utm_campaign: "spring_sale" }}formId identifies the submitted form. Use each fieldId to map a field to your CRM. Do not use the label text as an identifier.
For file-upload fields, value is an array of File objects. A urls array of stored file URLs is added only when files are stored. Map these fields separately from text values.
Ad click ID tracking
All three events include adClickIds when Sign Customiser captures a supported ad click ID. The object can contain:
-
gclid, the Google Ads click identifier. -
gbraid, the Google Ads parameter for a click on a web ad that leads to an iOS app. -
wbraid, the Google Ads parameter for a click on an ad in an iOS app that leads to a web page. -
fbclid, the Meta click identifier. Meta adds it to the URL when a person clicks an ad on Facebook or Instagram.
The field is null if Sign Customiser did not capture a supported ad click ID.
This example runs your conversion code only when Sign Customiser captured a Google click ID:
document.addEventListener("signCustomiserProductAddedToCart", function (event) { var gclid = event.detail.adClickIds && event.detail.adClickIds.gclid; if (gclid) { gtag("event", "conversion", { send_to: "AW-XXXXXXXXX/XXXXXXX", }); }});To send click IDs to your CRM, read Send Google Ads click IDs to your CRM.
UTM parameter tracking
All three events include utmParams when Sign Customiser captured UTM parameters for the browser session. The parameters can come from the storefront URL or from an earlier page in the same session. The object can contain:
-
utm_source, the advertiser, site, or publication that sends traffic. -
utm_medium, the marketing medium, for examplecpcoremail. -
utm_campaign, the campaign name. -
utm_content, a value that tells similar content or links in the same ad apart. -
utm_keyword, a keyword value that Sign Customiser also captures. -
utm_term, the paid search keyword.
The field is null if Sign Customiser did not capture UTM parameters for the browser session.
This example sends captured UTM data to a Google Tag Manager data layer:
document.addEventListener("signCustomiserFormSubmitted", function (event) { var utm = event.detail.utmParams; if (utm) { window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: "sign_form_submitted", utm_source: utm.utm_source, utm_medium: utm.utm_medium, utm_campaign: utm.utm_campaign, }); }});For the webhook workflow, read Track marketing campaigns with UTM parameters.
Save a ShareLink with a cart
Use ShareLink events when your theme needs the current design URL for a cart. Do not click the customer Share my design button (its default label). Do not remove the share modal.
The ShareLink contract uses these events:
-
signCustomiserShareLinkRequested -
signCustomiserShareLinkCreated -
signCustomiserShareLinkFailed
The Store must be able to go live. Its plan must include sharing. Starter, Standard, Pro, and Launch plans do not include sharing. A ShareLink created by this flow expires 365 days after creation.
Read Save a customer ShareLink with storefront JavaScript for the setup procedure. Read the Storefront JavaScript events guide for complete event details.
Use this pattern to replace a script that clicks the Share my design button and reads or removes the share modal:
function requestSignCustomiserShareLink(callback) { var requestId = "cart-" + Date.now() + "-" + Math.random().toString(36).slice(2); var timeout = window.setTimeout(function () { cleanup(); callback(null); }, 10000); function cleanup() { document.removeEventListener( "signCustomiserShareLinkCreated", handleCreated, ); document.removeEventListener( "signCustomiserShareLinkFailed", handleFailed, ); window.clearTimeout(timeout); } function handleCreated(event) { if (!event.detail || event.detail.requestId !== requestId) { return; } cleanup(); callback(event.detail.url); } function handleFailed(event) { if (!event.detail || event.detail.requestId !== requestId) { return; } cleanup(); callback(null); } document.addEventListener( "signCustomiserShareLinkCreated", handleCreated, ); document.addEventListener( "signCustomiserShareLinkFailed", handleFailed, ); document.dispatchEvent( new CustomEvent("signCustomiserShareLinkRequested", { detail: { requestId: requestId, }, }), );}function continueCartFlow() { requestSignCustomiserShareLink(async function (shareLinkUrl) { try { if (shareLinkUrl) { await saveShareLinkForCart(shareLinkUrl); } } finally { await continueToCart(); } });}Save the complete returned URL. Do not build or log token parts. Do not log the ShareLink URL. Do not send it to analytics.
If the request fails or times out, continue the cart flow without a ShareLink. Do not save an empty or partial URL.