Implement tracking in a Shoporama theme
Developer guide to implement e-commerce tracking in a Shoporama theme with standard data layer, Google Tag Manager and custom events.
This guide is for theme developers and freelancers who want to implement e-commerce tracking in a Shoporama theme. We'll cover Shoporama's built-in tracking, the automatic data layer, setting up Google Tag Manager and how to fire custom events from your own theme.
Recommendation
The easiest way is to let Shoporama handle the tracking itself. Activate the tracking module under Webshop → Tracking and we will send data directly to Facebook, Google Ads, GA4, TikTok and more via server-side tracking. You avoid writing a single line of code. Read more in Tracking in your Shoporama webshop.
1. Use Shoporama's built-in tracking
Before you write code yourself, consider Shoporama's tracking module. You'll find it in the left sidebar under Online Store (gear icon) → Tracking. Check Enable tracking, select the platforms you want to send data to and enter your IDs and access tokens.
The module supports:
- Facebook Pixel and Conversion API
- Google Ads (incl. offline conversions)
- Microsoft Ads
- Google GA4
- Pinterest, Snapchat, TikTok and LinkedIn
- Server-side tracking via your own subdomain (avoids adblockers)
- Consent Mode v2
When the tracking module is active, Shoporama automatically fires events to the selected platforms. A complete GA4 e-commerce data layer plus a Google Tag Manager container will also be pushed to your store frontend if you have filled in a GTM ID in the store settings.
2. The automatic data layer
The default themes (Delaware, Montana, Massachusetts etc.) include a partial called partials/datalayer.html. It pushes GA4-compliant e-commerce events to window.dataLayer as soon as tracking is enabled on the shop.
The following events are automatically fired by the theme:
| Event | When |
|---|---|
| view_item | Product page is shown |
| view_item_list | Category or landing page is displayed |
| select_item | A product card is clicked |
| add_to_cart | Product is added to cart |
| remove_from_cart | Product is removed from cart |
| view_cart | Cart page is displayed |
| begin_checkout | Address page is shown (checkout starts) |
| add_shipping_info | Shipping is selected |
| add_payment_info | Payment method is selected |
| purchase | Thank you page (receipt) is shown after purchase is completed |
| search | Search results page is displayed |
| customerInfo | Logged in customer with email |
| ShopOramaSettings | Settings are pushed on page load (pixel ID, currency, GA4 ID etc.) |
A typical view_item push generated by the theme looks like this:
window.dataLayer = window.dataLayer || []; window.dataLayer.push({ ecommerce: null }); window.dataLayer.push({ event: 'view_item', ecommerce: { items: [{ item_id: '12345', item_name: 'Example product', affiliation: 'My Webshop', currency: 'DKK', index: 0, item_brand: 'Brand', price: 199.00, quantity: 1 }] } });
If you are building your own theme from scratch, you can copy templates/partials/datalayer.html from the Delaware theme and include it in your global.html:
<{include file="partials/datalayer.html"}>
3. Set up Google Tag Manager via HTML fields
If you have filled in the Google Tag Manager Container ID field in your store settings, Shoporama will automatically insert the GTM snippet for you - it's at the bottom of partials/datalayer.html.
If you want to control GTM (or other scripts like Cookiebot, Hotjar or Klaviyo) manually, use HTML fields instead. Go to Webshop → HTML fields. Here you can create named fields and choose whether to insert them automatically in the head or body, or use them manually in your theme via a tag name.
A typical GTM snippet in an HTML field set to "Automatically add to head" looks like this:
<!-- Google Tag Manager --> <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:''';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-XXXXXXX');</script> <!-- End Google Tag Manager -->
Also remember the <noscript> fallback in the body field:
<!-- Google Tag Manager (noscript) --> <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> <!-- End Google Tag Manager (noscript) -->
Read more about how HTML fields work in HTML fields: Insert Cookiebot, GTM and other scripts.
4. Tags and triggers in GTM
With the default data layer active, you can use GA4's built-in tags and custom event triggers. A typical setup looks like this:
- GA4 Configuration Tag with your Measurement ID, fired on All Pages
- GA4 Event Tag for each e-commerce event - set to read the e-commerce object from the data layer
- Custom Event triggers with the names view_item, add_to_cart, begin_checkout, purchase, etc.
- Use Preview mode in GTM to verify that events fire with correct data
For Google Ads conversions, link your Google Ads Conversion ID/Label to the purchase event. See also Google Analytics tracking of your online shop.
5. Custom events from your own theme
If you need to fire events that are not covered by the standard data layer - for example, a video playback, a tab click, a chat opening or a custom CTA - then push directly to window.dataLayer from your theme:
<button onclick="trackVideoPlay()">Play video</button> <script> function trackVideoPlay() { window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: 'video_play', video_title: 'Product-demo', video_id: 'demo-123' }); } </script>
On the receipt page, you can extend or replace the default purchase event by using the order object and Smarty:
<script> window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: 'custom_purchase', ecommerce: { transaction_id: '<{$order->getWebshopOrderId()}>', value: <{$order->getTotalPrice()|number_format:2:".":"""}>', currency: '<{$webshop->getCurrency()}>', coupon: '<{$order->getVoucherCode()|escape:"javascript"}>' }); </script>
Note that Shoporama's default purchase event already sets setTrackingCalled() on the order, so it only fires once. If you want the same behavior on your custom event, you need to handle idempotence yourself (e.g. via a cookie or localStorage).
6. Testing and troubleshooting
- Use the GTM/GA Debugger Chrome extension or Tag Assistant to see which events are firing
- Type window.dataLayer in the browser console to see the entire dataLayer history
- Use GTM's Preview mode to see tags fire in real-time
- Verify purchase events in GA4 DebugView
- If nothing fires: check if Enable tracking is set in Webshop → Tracking - without it, the datalayer.html block is inactive
Frequently asked questions
Do I have to choose between Shoporama's built-in tracking and my own GTM setup?
No, you can run both at the same time. The built-in tracking module sends data server-side to the selected platforms, while your own GTM setup runs client-side. Many shops actually run both for the most robust tracking - especially during Consent Mode where client-side events can be blocked.
Where should I put the GTM snippet if I don't want to use HTML fields?
Directly in your theme's templates/global.html or a custom header partial. However, we recommend HTML fields as they survive theme updates and can be changed without deploying a new theme.
Can I overwrite or disable the default events Shoporama fires?
Yes, you can. If you have a completely custom theme, do not include partials/datalayer.html. If you're building on Delaware or Montana and only want to change a few events, create your own partial and include it instead of the default version.
What variables do I have access to in the dataLayer template?
The typical ones: $webshop, $product, $category, $order, $basket, $customer, $voucher and $inc which indicates which template is being rendered (e.g. basket.html, thanks.html). The classes are documented in admin/class/safe/.
How do I avoid firing the purchase event twice if the customer refreshes the receipt page?
This is already handled by the theme via $order->getTrackingCalled() and $order->setTrackingCalled(). If you build your own purchase event, reuse the same pattern or set a flag cookie/localStorage value after the first firing.
Do I need to account for Consent Mode in my own theme?
Yes, you do. If the customer has not given consent, do not fire tracking events that use cookies. Use a cookie consent manager (Cookiebot, CookieInformation or your own solution) and let GTM tags depend on the consent state. Shoporama's server-side tracking handles Consent Mode automatically when you enable Use Consent Mode in the tracking module.
Can I send my own dataLayer events to platforms other than Google?
Yes. dataLayer is platform-agnostic. You can set up tags in GTM for Meta CAPI, TikTok Events API or anything that supports dataLayer as a source. Alternatively, you can fire directly to the platforms' own SDKs (e.g. fbq() or ttq.track()) from your theme.
Need help with implementation? Write to support@shoporama.dk.
Related articles
Implement Pricerunner tracking
Guide to implementing Pricerunner conversion tracking on your Shoporama online shop with proper Smarty code.
Set up Daisycon tracking on your webshop
Guide to implementing Daisycon conversion tracking on your Shoporama webshop with correct Smarty code.
SEO in Shoporama
Complete guide to the SEO features in Shoporama - from meta tags and sitemap to Google Shopping and AI Assistant.