Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 36 additions & 5 deletions docs/content/scripts/analytics/matomo-analytics.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use the [useScriptMatomoAnalytics](#useScriptMatomoAnalytics) composable.

## Loading Globally

The following config assumes you're using Matomo Cloud with the default `siteId` of `1`.
The following config assumes you're using Matomo Cloud with the default `siteId` of `1`. Page views are **automatically tracked** on navigation by default.

If you're self-hosting, you'll need to provide the `matomoUrl` instead. If you have other sites you want to track, you can add them using `siteId`.

Expand Down Expand Up @@ -84,13 +84,13 @@ const matomoAnalytics = useScriptMatomoAnalytics({
})
```

By default, a `siteId` of `1` is used and the page is not tracked. You can enable tracking by setting `trackPageView` to `true`.
By default, a `siteId` of `1` is used and page tracking is **automatically enabled** via the `watch` option.

```ts
const matomoAnalytics = useScriptMatomoAnalytics({
cloudId: 'YOUR_CLOUD_ID', // e.g. nuxt.matomo.cloud
trackPageView: true,
siteId: 2,
// watch: true, // enabled by default - automatic page tracking!
})
```

Expand All @@ -109,6 +109,35 @@ proxy._paq.push(['trackPageView'])

Please see the [Config Schema](#config-schema) for all available options.

## Custom Page Tracking

By default, all pages are tracked automatically, to disable the automatic tracking you can provide `watch: false`.

```ts
import { useScriptEventPage } from '#nuxt-scripts'

const { proxy } = useScriptMatomoAnalytics({
cloudId: 'YOUR_CLOUD_ID',
watch: false, // disable automatic tracking
})

// 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 Matomo Self-Hosted

For self-hosted Matomo, set `matomoUrl` to customize tracking, you may need to set the `trackerUrl` if you've customized this.
Expand Down Expand Up @@ -151,11 +180,13 @@ You must provide the options when setting up the script for the first time.
// matomoUrl and site are required
export const MatomoAnalyticsOptions = object({
matomoUrl: optional(string()),
siteId: optional(string()),
siteId: optional(union([string(), number()])),
cloudId: optional(string()),
trackerUrl: optional(string()),
trackPageView: optional(boolean()),
trackPageView: optional(boolean()), // deprecated - use watch instead
enableLinkTracking: optional(boolean()),
disableCookies: optional(boolean()),
watch: optional(boolean()), // default: true
})
```

Expand Down
10 changes: 8 additions & 2 deletions src/runtime/composables/useScriptEventPage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useNuxtApp, useRoute, injectHead } from 'nuxt/app'
import { ref } from 'vue'
import { ref, onScopeDispose } from 'vue'
import type { TrackedPage } from '#nuxt-scripts/types'

export function useScriptEventPage(onChange?: (payload: TrackedPage) => void) {
Expand All @@ -17,7 +17,7 @@ export function useScriptEventPage(onChange?: (payload: TrackedPage) => void) {
let lastPayload: TrackedPage = { path: '', title: '' }
let stopDomWatcher = () => {}
// TODO make sure useAsyncData isn't running
nuxt.hooks.hook('page:finish', () => {
const stopPageFinishHook = nuxt.hooks.hook('page:finish', () => {
Promise.race([
// possibly no head update is needed
new Promise(resolve => setTimeout(resolve, 100)),
Expand All @@ -39,5 +39,11 @@ export function useScriptEventPage(onChange?: (payload: TrackedPage) => void) {
}
})
})

onScopeDispose(() => {
stopDomWatcher()
stopPageFinishHook()
})

return payload
}
21 changes: 19 additions & 2 deletions src/runtime/registry/matomo-analytics.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { withBase, withHttps, withoutProtocol, withoutTrailingSlash } from 'ufo'
import { useRegistryScript } from '../utils'
import { useScriptEventPage } from '../composables/useScriptEventPage'
import { boolean, object, optional, string, number, union } from '#nuxt-scripts-validator'
import type { RegistryScriptInput } from '#nuxt-scripts/types'
import { logger } from '../logger'

export const MatomoAnalyticsOptions = object({
matomoUrl: optional(string()),
Expand All @@ -11,6 +13,7 @@ export const MatomoAnalyticsOptions = object({
trackPageView: optional(boolean()),
enableLinkTracking: optional(boolean()),
disableCookies: optional(boolean()),
watch: optional(boolean()),
})

export type MatomoAnalyticsInput = RegistryScriptInput<typeof MatomoAnalyticsOptions, false, false, false>
Expand Down Expand Up @@ -48,6 +51,7 @@ export function useScriptMatomoAnalytics<T extends MatomoAnalyticsApi>(_options?
return window._paq.push(...args)
},
}

return { _paq: _paqProxy }
},
},
Expand All @@ -67,8 +71,21 @@ export function useScriptMatomoAnalytics<T extends MatomoAnalyticsApi>(_options?
_paq.push(['setTrackerUrl', withBase(`/matomo.php`, withHttps(normalizedCloudId))])
}
_paq.push(['setSiteId', String(options?.siteId) || '1'])
if (options?.trackPageView) {
_paq.push(['trackPageView'])
// Deprecated: trackPageView option
if (options?.trackPageView !== undefined) {
if (import.meta.dev) {
logger.warn('The `trackPageView` option is deprecated. Use `watch: true` (default) for automatic page view tracking, or remove this option entirely.')
}
if (options.trackPageView) {
_paq.push(['trackPageView'])
}
}
else if (options?.watch !== false) {
useScriptEventPage((payload) => {
window._paq.push(['setDocumentTitle', payload.title])
window._paq.push(['setCustomUrl', payload.path])
window._paq.push(['trackPageView'])
})
}
},
}
Expand Down
Loading