Matomo Analytics
Matomo Analytics tracks page views and events with either Matomo Cloud or a self-hosted instance.
Nuxt Config Setup
Add this to your nuxt.config.ts to load Matomo Analytics globally. Alternatively you can use the useScriptMatomoAnalytics composable for more control.
export default defineNuxtConfig({
scripts: {
registry: {
matomoAnalytics: {
cloudId: 'my-site',
trigger: 'onNuxtReady',
}
}
}
})This config automatically enables first-party mode (proxy). See below to customise.
useScriptMatomoAnalytics()
The useScriptMatomoAnalytics composable lets you have fine-grain control over when and how Matomo Analytics is loaded on your site.
const { proxy } = useScriptMatomoAnalytics()
proxy._paq.push(['trackEvent', 'category', 'action'])Please follow the Registry Scripts guide to learn more about advanced usage.
First-Party Mode: Privacy Focused Proxy
No extra config needed. Runtime requests are reverse-proxied through your server instead of going directly to Matomo Analytics. User IPs are anonymised and requests work with ad blockers. Learn more.
export default defineNuxtConfig({
scripts: {
// ✅ First-party mode: proxied
registry: {
matomoAnalytics: {
cloudId: 'my-site',
trigger: 'onNuxtReady',
},
},
},
})Example
Using Matomo Analytics in a component with the proxy to send events .
<script setup lang="ts">
const { proxy } = useScriptMatomoAnalytics()
// noop in development, ssr
// just works in production, client
function handleAction() {
proxy._paq.push(['trackEvent', 'category', 'action'])
}
</script>
<template>
<div>
<button @click="handleAction">
Send Event
</button>
</div>
</template>The watch option defaults to true. The composable registers its useScriptEventPage watcher immediately, independently of the script trigger. Register the composable before the initial page:finish hook to track that route and later navigations; registering it afterward only catches subsequent navigations. Pass siteId explicitly: the current runtime does not apply its intended fallback of 1 when the option is omitted.
useScriptMatomoAnalytics({
cloudId: 'YOUR_CLOUD_ID', // e.g. nuxt.matomo.cloud
siteId: 2,
// watch: true, // Enabled by default; tracks pages automatically.
})
Push commands to _paq for custom dimensions or manual events:
const { proxy } = useScriptMatomoAnalytics({
cloudId: 'YOUR_CLOUD_ID', // e.g. nuxt.matomo.cloud
siteId: 2,
})
// set custom dimension
proxy._paq.push(['setCustomDimension', 1, 'value'])
// send page event
proxy._paq.push(['trackPageView'])
See the Config Schema for the full option list.
Custom page tracking
Provide watch: false to disable the built-in page watcher, then queue the initial route yourself if you need it:
const { proxy } = useScriptMatomoAnalytics({
cloudId: 'YOUR_CLOUD_ID',
siteId: 2,
watch: false, // disable automatic tracking
})
// watch: false disables the built-in page watcher.
proxy._paq.push(['trackPageView'])
// Custom page tracking with additional logic
useScriptEventPage((payload) => {
// Set custom dimensions based on route
if (payload.path.startsWith('/products')) {
proxy._paq.push(['setCustomDimension', 1, 'Product Page'])
}
// Standard Matomo tracking calls (same as built-in watch behavior)
proxy._paq.push(['setDocumentTitle', payload.title])
proxy._paq.push(['setCustomUrl', payload.path])
proxy._paq.push(['trackPageView'])
// Track additional custom events
proxy._paq.push(['trackEvent', 'Navigation', 'PageView', payload.path])
})
Using self-hosted Matomo
For self-hosted Matomo, set matomoUrl to customize tracking. Set trackerUrl as well if you use a custom tracking endpoint.
useScriptMatomoAnalytics({
// For example, https://your-url.com/matomo.js and /matomo.php both exist.
matomoUrl: 'https://your-url.com',
siteId: 2,
})
Consent mode
Matomo has a built-in tracking-consent API gated by requireConsent. Set defaultConsent to arm the gate at registration, then call consent.give() / consent.forget() at runtime.
defaultConsent
| Value | Behavior |
|---|---|
'required' | Pushes ['requireConsent']. Matomo tracks nothing until the user opts in. |
'given' | Pushes ['requireConsent'] then ['setConsentGiven']. Tracking starts immediately. |
'not-required' | Default Matomo behavior (no consent gating). |
consent.give() and consent.forget() are no-ops unless defaultConsent: 'required' or 'given' was set at registration. Matomo ignores setConsentGiven and forgetConsentGiven when requireConsent hasn't been pushed. A development-only warning fires if you forget.
Example
<script setup lang="ts">
const { consent } = useScriptMatomoAnalytics({
cloudId: 'YOUR_CLOUD_ID',
siteId: 2,
defaultConsent: 'required',
})
function onAccept() {
consent.give()
}
function onRevoke() {
consent.forget()
}
</script>
Using white-label Matomo
For a white-label Matomo deployment, set trackerUrl and scriptInput.src to customize tracking.
useScriptMatomoAnalytics({
siteId: 2,
trackerUrl: 'https://c.staging.cookie3.co/lake',
scriptInput: {
src: 'https://cdn.cookie3.co/scripts/latest/cookie3.analytics.min.js',
},
})
matomoUrlstringThe URL of your self-hosted Matomo instance. Either `matomoUrl` or `cloudId` is required.
siteIdstring | number = '1'Your Matomo site ID.
cloudIdstringYour Matomo Cloud ID (the subdomain portion of your `*.matomo.cloud` URL). Either `matomoUrl` or `cloudId` is required.
trackerUrlstringA custom tracker URL. Overrides the default tracker endpoint derived from `matomoUrl` or `cloudId`.
trackPageViewbooleanWhether to track the initial page view on load.
enableLinkTrackingbooleanEnable download and outlink tracking.
disableCookiesbooleanDisable all tracking cookies for cookieless analytics.
watchboolean = trueAutomatically track page views on route change.
defaultConsent'required' | 'given' | 'not-required'Default tracking-consent state applied BEFORE the tracker is initialised. - `'required'` — call `requireConsent` without granting (user must opt in later). - `'given'` — call `requireConsent` then `setConsentGiven`. - `'not-required'` — no consent gating (default Matomo behaviour).