Platforms
Ready-to-use examples for tag managers, WooCommerce, Shopify, VTEX, Nuvemshop and single-page applications.
Google Tag Manager#
Global tag#
Custom HTML tag, All Pages trigger:
<script src="https://bridge.moclick.com.br/moclick-YOUR-SLUG.js" defer></script>
Conversion tag#
Custom HTML tag, fired on the purchase event:
<script> window.MoclickConversion = { value: {{DLV - ecommerce.value}}, transaction_id: "{{DLV - ecommerce.transaction_id}}" }; </script>
Create the data layer variables before referencing them. On GA4 the paths are
ecommerce.value and ecommerce.transaction_id. Confirm in
GTM Preview that the variables resolve — the number one cause of
missing conversions here is an empty variable.
WooCommerce#
Through the child theme’s functions.php, or a snippets plugin:
// Global tag on every page add_action('wp_head', function () { echo '<script src="https://bridge.moclick.com.br/moclick-YOUR-SLUG.js" defer></script>'; }); // Conversion on the thank-you page add_action('woocommerce_thankyou', function ($order_id) { $order = wc_get_order($order_id); if (!$order) { return; } $value = number_format((float) $order->get_total(), 2, '.', ''); $txid = $order->get_order_number(); printf( '<script>window.MoclickConversion={value:%s,transaction_id:%s};</script>', wp_json_encode((float) $value), wp_json_encode((string) $txid) ); });
Use wp_json_encode for both values. Interpolating straight into the
string breaks the JavaScript whenever the order number contains an apostrophe, a
slash or a prefix configured in Woo.
Shopify#
Global tag#
Under Online Store → Themes → Edit code → theme.liquid, inside the <head>:
<script src="https://bridge.moclick.com.br/moclick-YOUR-SLUG.js" defer></script>
Conversion#
Under Settings → Checkout → Order status page, or as a Custom Pixel:
<script src="https://bridge.moclick.com.br/moclick-YOUR-SLUG.js" defer></script> <script> window.MoclickConversion = { value: {{ checkout.total_price | divided_by: 100.0 }}, transaction_id: "{{ checkout.order_number }}" }; </script>
checkout.total_price comes in cents: an order of BRL 150.00 arrives as
15000. Without divided_by: 100.0 your revenue is a hundred
times too high. Repeat the global tag on the Order status page — it is served
outside the theme and does not inherit theme.liquid.
VTEX#
Global tag under Storefront → Settings → Scripts. The conversion goes in the order-placed page template:
<script> window.addEventListener("message", function (e) { if (!e.data || e.data.eventName !== "vtex:orderPlaced") return; var o = e.data; window.MoclickConversion = { value: o.transactionTotal, transaction_id: String(o.transactionId) }; }); </script>
Nuvemshop / Tiendanube#
Global tag under My store → Settings → External code, marked for all pages. The conversion goes in the purchase confirmation code:
<script> window.MoclickConversion = { value: {{ order.total | raw }}, transaction_id: "{{ order.number }}" }; </script>
Single-page applications#
In an SPA the page never reloads, so the global tag loads once and conversion watching stays active for 120 seconds. If the gap between load and confirmation can exceed that, reload the tag on the confirmation route:
function trackMoclickConversion(order) { window.MoclickConversion = { value: order.total, transaction_id: String(order.id) }; // Reload the tag to restart the watch window. // The 5 min cache avoids a new transfer; dedup avoids a duplicate. var s = document.createElement("script"); s.src = "https://bridge.moclick.com.br/moclick-YOUR-SLUG.js"; s.defer = true; document.head.appendChild(s); }
Reloading the tag is safe: deduplication by transaction_id prevents a
double conversion, and the repeat-record guard prevents a double visit.
Any other platform#
Any platform that lets you insert JavaScript on every page and expose the order and its value on confirmation is compatible. That is the whole requirement:
- The global tag loaded on every page, including the confirmation page
window.MoclickConversiondefined on confirmation, with a dot-decimal value and a stable order identifier
If the value or the identifier only exist in the backend, use Postback S2S.