Miva Merchant Analytics Implementation | OpsBlu Docs

Miva Merchant Analytics Implementation

Install tracking scripts, configure data layers using MVTE template variables, and implement e-commerce tracking on Miva Merchant storefronts.

Analytics Architecture on Miva Merchant

Miva Merchant uses its own proprietary template language called MVTE (Miva Template Engine) for rendering storefronts. Analytics code is injected through template editing in the Miva admin panel. The key integration points are:

  • Global Header/Footer templates -- site-wide script injection via the global_header and global_footer template sections
  • Page Code -- each Miva page (SFNT, CTGY, PROD, BASK, OCST, OSEL, OPAY, INVC) has its own template where page-specific tracking can be added
  • ReadyTheme framework -- modern Miva stores use ReadyTheme, which provides structured template regions and component-based layouts
  • Item variables -- &mvte:product:*; tokens expose product data server-side for data layer construction
  • Basket variables -- &mvte:basket:*; tokens expose cart and order data

All tracking code is placed directly in Miva's template editor. There is no file-system access to templates; everything is managed through the admin UI at User Interface > Template Editor.


Installing Tracking Scripts

In the Miva admin, navigate to User Interface > Global Settings and add scripts to the global footer:

<!-- Global Footer template -->
<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-XXXXXX');
</script>

Page-Specific Script Injection

Each Miva page code has its own template. To add tracking to the product page, edit the PROD page template:

<!-- In PROD page template -->
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  'event': 'view_item',
  'ecommerce': {
    'items': [{
      'item_id': '&mvte:product:code;',
      'item_name': '&mvte:product:name;',
      'price': &mvte:product:price;,
      'item_category': '&mvte:category:name;'
    }]
  }
});
</script>

Head Tag Injection

For scripts that must load in <head> (such as preconnect hints or synchronous pixels), edit the global header template or use the Head Tag section in ReadyTheme:

<!-- Global Header template -->
<link rel="preconnect" href="https://www.googletagmanager.com">
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>

Data Layer Implementation

Miva's MVTE variables render server-side, making them reliable for constructing data layers. The syntax is &mvte:entity:field; for HTML-encoded output or &mvt:entity:field; for raw output.

Product Page Variables

Available on the PROD page:

MVTE Variable Description
&mvte:product:code; Product SKU/code
&mvte:product:name; Product name
&mvte:product:price; Current price
&mvte:product:base_price; Base price before discounts
&mvte:product:weight; Product weight
&mvte:product:id; Internal product ID
&mvte:category:name; Current category name

Category Page Data Layer

On the CTGY page, product listings are rendered via &mvt:product:*; inside a product loop:

<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  'event': 'view_item_list',
  'ecommerce': {
    'item_list_name': '&mvte:category:name;',
    'items': [
      <mvt:foreach iterator="product" array="products">
      {
        'item_id': '&mvte:product:code;',
        'item_name': '&mvte:product:name;',
        'price': &mvte:product:price;
      },
      </mvt:foreach>
    ]
  }
});
</script>

Basket (Cart) Data Layer

On the BASK page:

<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  'event': 'view_cart',
  'ecommerce': {
    'value': &mvte:basket:total;,
    'items': [
      <mvt:foreach iterator="item" array="basket_items">
      {
        'item_id': '&mvte:item:code;',
        'item_name': '&mvte:item:name;',
        'price': &mvte:item:price;,
        'quantity': &mvte:item:quantity;
      },
      </mvt:foreach>
    ]
  }
});
</script>

E-commerce Tracking

Order Confirmation (INVC Page)

The INVC (invoice/confirmation) page exposes order data for purchase tracking:

<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  'event': 'purchase',
  'ecommerce': {
    'transaction_id': '&mvte:order:id;',
    'value': &mvte:order:total;,
    'tax': &mvte:order:tax;,
    'shipping': &mvte:order:ship;,
    'currency': 'USD',
    'items': [
      <mvt:foreach iterator="item" array="order_items">
      {
        'item_id': '&mvte:item:code;',
        'item_name': '&mvte:item:name;',
        'price': &mvte:item:price;,
        'quantity': &mvte:item:quantity;
      },
      </mvt:foreach>
    ]
  }
});
</script>

Add to Cart Tracking

Miva's add-to-cart is a form POST action. Attach a JavaScript listener to the add-to-cart form on the PROD page:

<script>
document.addEventListener('DOMContentLoaded', function() {
  var form = document.querySelector('form[action*="ATWL"]') ||
             document.querySelector('form[action*="ADPR"]');
  if (form) {
    form.addEventListener('submit', function() {
      window.dataLayer = window.dataLayer || [];
      window.dataLayer.push({
        'event': 'add_to_cart',
        'ecommerce': {
          'items': [{
            'item_id': '&mvte:product:code;',
            'item_name': '&mvte:product:name;',
            'price': &mvte:product:price;,
            'quantity': parseInt(document.querySelector('input[name="Quantity"]').value) || 1
          }]
        }
      });
    });
  }
});
</script>

Common Issues

MVTE variables rendering as empty strings -- Ensure you are using the correct variable scope for the current page. &mvte:product:*; variables are only populated on the PROD page. On other pages, they will be empty.

Trailing commas in JSON from foreach loops -- The <mvt:foreach> loop does not provide an index or "last item" flag. The trailing comma after the last item in a JavaScript array will cause syntax errors in older browsers. Use a JavaScript cleanup pattern or build the array in a Miva Script module.

ReadyTheme vs legacy templates -- ReadyTheme stores use a different template structure with named regions (e.g., readytheme_contentsection). If your store uses ReadyTheme, inject tracking code into the appropriate region, not the legacy page templates.

Checkout pages (OSEL, OPAY) restrictions -- Miva's checkout flow spans multiple pages (OSEL for shipping, OPAY for payment). Payment page templates have limited variable access for security. Place conversion tracking only on the INVC page.

Cached template output -- Miva can cache rendered template fragments. If your data layer values appear stale, check whether template caching is enabled for the page in question and exclude analytics script blocks from caching.


Platform-Specific Considerations

Miva Script for advanced logic -- For complex tracking requirements (conditional data layers, custom event logic), use Miva's server-side scripting language (Miva Script) to generate structured JSON before outputting it to the template.

No filesystem template access -- Unlike PHP-based platforms, Miva templates are stored in the database and edited exclusively through the admin UI. There are no files to edit via FTP/SSH.

Page code routing -- Miva uses page codes (SFNT, PROD, CTGY, BASK, OCST, OSEL, OPAY, INVC) to route requests. Understanding which page code corresponds to which step in the customer journey is essential for placing tracking code correctly.

Miva JSON API -- Miva provides a JSON API for accessing product and order data. For server-side tracking implementations, query the API endpoints at /mm5/json.mvc with appropriate function calls and authentication tokens.

Multi-currency -- If the store supports multiple currencies, the &mvte:product:price; variable reflects the active currency. Ensure your data layer includes the currency code alongside price values.