Overview
A well-structured data layer serves as the contract between your website and Matomo tracking. It standardizes how user actions, page context, and transaction data are exposed, enabling consistent tracking across all pages and reducing reliance on fragile DOM scraping.
Data Layer Architecture
Recommended Structure
Use the Matomo Tag Manager data layer format for maximum compatibility:
window._mtm = window._mtm || [];
_mtm.push({
'event': 'mtm.Start',
'pageType': 'product',
'userId': 'user_12345',
'consentGranted': true,
'customDimensions': {
'1': 'premium',
'2': 'electronics'
}
});
For sites not using Matomo Tag Manager, a generic data layer works equally well:
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'pageType': 'checkout',
'cartValue': 149.99,
'cartItems': 3
});
Required Fields by Page Type
All Pages
| Field | Description | Example |
|---|---|---|
pageType |
Classification of the page | home, category, product, cart, checkout, confirmation |
userId |
Authenticated user identifier (if logged in) | user_12345 |
visitorId |
Matomo visitor ID from cookie | abc123xyz |
consentStatus |
Current consent state | granted, denied, pending |
siteSection |
Top-level content area | blog, shop, support |
Product Pages
_mtm.push({
'event': 'productView',
'product': {
'sku': 'SKU-12345',
'name': 'Wireless Headphones',
'category': 'Electronics/Audio',
'price': 79.99,
'currency': 'USD',
'brand': 'AudioTech',
'variant': 'Black'
}
});
Cart and Checkout
_mtm.push({
'event': 'cartUpdate',
'cart': {
'items': [
{
'sku': 'SKU-12345',
'name': 'Wireless Headphones',
'category': 'Electronics/Audio',
'price': 79.99,
'quantity': 1
}
],
'subtotal': 79.99,
'tax': 6.40,
'shipping': 5.99,
'discount': 0,
'total': 92.38,
'currency': 'USD'
}
});
Order Confirmation
_mtm.push({
'event': 'orderComplete',
'transaction': {
'orderId': 'ORD-98765',
'revenue': 92.38,
'tax': 6.40,
'shipping': 5.99,
'discount': 0,
'currency': 'USD',
'paymentMethod': 'credit_card',
'items': [
{
'sku': 'SKU-12345',
'name': 'Wireless Headphones',
'category': 'Electronics/Audio',
'price': 79.99,
'quantity': 1
}
]
}
});
Custom Dimensions Mapping
Planning Custom Dimensions
Before implementation, define your custom dimension schema:
| Index | Name | Scope | Description |
|---|---|---|---|
| 1 | Customer Tier | Visit | guest, registered, premium |
| 2 | Content Category | Action | Primary content classification |
| 3 | A/B Test Variant | Visit | Active experiment variations |
| 4 | Author | Action | Content author for attribution |
| 5 | Login Status | Visit | logged_in, logged_out |
Implementing in Data Layer
_mtm.push({
'event': 'pageview',
'customDimension1': 'premium',
'customDimension2': 'electronics',
'customDimension3': 'variant_b',
'customDimension4': 'john_smith',
'customDimension5': 'logged_in'
});
Tag Manager Variable Mapping
In Matomo Tag Manager:
- Create Data Layer Variables for each custom dimension field
- In your Matomo Configuration tag, map variables to dimension indexes
- Verify mappings in preview mode before publishing
User Identification
Visitor ID Persistence
Expose the Matomo visitor ID for server-side correlation:
// After Matomo loads
var visitorId = Matomo.getTracker().getVisitorId();
_mtm.push({'matomoVisitorId': visitorId});
User ID for Logged-In Users
// Set when user authenticates
_paq.push(['setUserId', 'user_12345']);
_mtm.push({'userId': 'user_12345'});
Ensure User ID persists across sessions and is removed on logout:
// On logout
_paq.push(['resetUserId']);
_mtm.push({'userId': null});
Consent Management Integration
Pre-Consent State
Initialize the data layer with consent status before any tracking:
_mtm.push({
'event': 'mtm.Start',
'consentStatus': 'pending',
'consentCategories': []
});
Post-Consent Update
When user grants consent, update the data layer:
_mtm.push({
'event': 'consentGranted',
'consentStatus': 'granted',
'consentCategories': ['analytics', 'marketing']
});
Governance and Maintenance
Schema Documentation
Maintain a versioned schema file that defines:
- All data layer variables and their expected types
- Required vs. optional fields per page type
- Custom dimension mappings and business definitions
- Event naming conventions
Change Management
- Version your schema: Include a schema version in the data layer for debugging
- Deprecation process: Mark fields as deprecated before removal
- QA requirements: All schema changes require Tag Manager preview validation
- Stakeholder notification: Alert analytics consumers when schema changes deploy
Validation and Debugging
Browser Console Checks
// View current data layer state
console.log(window._mtm);
// Monitor data layer pushes in real-time
(function() {
var originalPush = _mtm.push;
_mtm.push = function() {
console.log('Data Layer Push:', arguments);
return originalPush.apply(this, arguments);
};
})();
Tag Manager Preview Mode
- Enable Matomo Tag Manager preview
- Navigate through key user flows
- Verify each data layer push appears in the Variables panel
- Confirm values match expected data from the page
Server-Side Validation
For critical transactions, compare data layer values against server records to catch discrepancies in pricing, product data, or order totals.