Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Merge pull request #144 from Amsterdam/feature/enable-link-tracking
Browse files Browse the repository at this point in the history
Expose the trackLink method in the react package as well, add a new m…
  • Loading branch information
royderks authored May 8, 2020
2 parents 5ae777a + 46987f8 commit b4cdd57
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 13 deletions.
5 changes: 3 additions & 2 deletions packages/js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const MatomoInstance = new window.MatomoTracker({
active: true, // optional, default value: true
seconds: 10 // optional, default value: `15
}
linkTracking: false // optional, default value: true
})
```

Expand All @@ -69,7 +70,7 @@ MatomoInstance.trackEvent({
})

MatomoInstance.trackLink({
'https://link-to-other-website.org'
href: 'https://link-to-other-website.org',
})
```

Expand Down Expand Up @@ -112,7 +113,7 @@ MatomoInstance.trackEvent({

MatomoInstance.trackLink({
href: 'https://link-to-your-file.pdf',
linkType: 'download' // optional, default value 'link'
linkType: 'download', // optional, default value 'link'
})
```

Expand Down
2 changes: 1 addition & 1 deletion packages/js/bundle.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/js/src/MatomoTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class MatomoTracker {
trackerUrl,
srcUrl,
heartBeat,
linkTracking = true,
}: UserOptions) {
if (urlBase[urlBase.length - 1] !== '/') {
urlBase = urlBase + '/'
Expand All @@ -51,7 +52,7 @@ class MatomoTracker {

// // measure outbound links and downloads
// // might not work accurately on SPAs because new links (dom elements) are created dynamically without a server-side page reload.
this.enableLinkTracking(true)
this.enableLinkTracking(linkTracking)

const doc = document
const scriptElement = doc.createElement('script')
Expand Down
3 changes: 2 additions & 1 deletion packages/js/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface UserOptions {
active: boolean
seconds?: number
}
linkTracking?: boolean
}

export interface TrackPageViewParams {
Expand All @@ -40,7 +41,7 @@ export interface TrackEventParams extends TrackPageViewParams {

export interface TrackLinkParams {
href: string
linkType: 'download' | 'link'
linkType?: 'download' | 'link'
}

export interface TrackSiteSearchParams extends TrackPageViewParams {
Expand Down
59 changes: 51 additions & 8 deletions packages/react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ Before you're able to use this Matomo Tracker you need to create a Matomo instan
import { MatomoProvider, createInstance } from '@datapunt/matomo-tracker-react'

const instance = createInstance({
urlBase: "https://LINK.TO.DOMAIN",
urlBase: 'https://LINK.TO.DOMAIN',
siteId: 3, // optional, default value: `1`
trackerUrl: "https://LINK.TO.DOMAIN/tracking.php", // optional, default value: `${urlBase}matomo.php`
srcUrl: "https://LINK.TO.DOMAIN/tracking.js" // optional, default value: `${urlBase}matomo.js`
});
trackerUrl: 'https://LINK.TO.DOMAIN/tracking.php', // optional, default value: `${urlBase}matomo.php`
srcUrl: 'https://LINK.TO.DOMAIN/tracking.js', // optional, default value: `${urlBase}matomo.js`
})

ReactDOM.render(
<MatomoProvider value={instance}>
<MyApp />
</MatomoProvider>
</MatomoProvider>,
)
```

Expand All @@ -46,7 +46,11 @@ const MyPage = () => {
trackEvent({ category: 'sample-page', action: 'click-event' })
}

return <button type="button" onClick={handleOnClick}>Click me</button>
return (
<button type="button" onClick={handleOnClick}>
Click me
</button>
)
}
```

Expand Down Expand Up @@ -80,7 +84,11 @@ const MyPage = () => {
trackEvent({ category: 'sample-page', action: 'click-event' })
}

return <button type="button" onClick={handleOnClick}>Click me</button>
return (
<button type="button" onClick={handleOnClick}>
Click me
</button>
)
}
```

Expand Down Expand Up @@ -111,10 +119,45 @@ const MyPage = () => {
})
}

return <button type="button" onClick={handleOnClick}>Click me</button>
return (
<button type="button" onClick={handleOnClick}>
Click me
</button>
)
}
```

## SPA Link Tracking

Matomo provides the option to track outbound link, however, this implementation is flaky for a SPA (Single Page Application) **without** SSR (Server Side Rendering) across different versions of Matomo. Therefore you can use the `enableLinkTracking` method to listen to outbound clicks on anchor elements. This method should be placed on a component directly below your `MatomoProvider` on a component that's rendered on every page view. Also, make sure to disable the `enableLinkTracking` option on the instance passed to the provider to prevent Matomo from catching some link clicks:

```js
import { MatomoProvider, createInstance } from '@datapunt/matomo-tracker-react'

const instance = createInstance({
urlBase: "https://LINK.TO.DOMAIN",
enableLinkTracking: false // Important!
});

ReactDOM.render(
<MatomoProvider value={instance}>
<MyApp />
</MatomoProvider>
)

const MyApp = () => {
const { enableLinkTracking } = useMatomo()

enableLinkTracking()

return (
// Render components
)
}

```

## References

- [Matomo JavaScript Tracking Guide](https://developer.matomo.org/guides/tracking-javascript-guide)
```
3 changes: 3 additions & 0 deletions packages/react/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface MatomoInstance {
trackEvent?: Function
trackPageView?: Function
trackSiteSearch?: Function
trackLink?: Function
}

export interface InstanceParams extends types.UserOptions {}
Expand All @@ -13,3 +14,5 @@ export interface TrackPageViewParams extends types.TrackPageViewParams {}
export interface TrackEventParams extends types.TrackEventParams {}

export interface TrackSiteSearchParams extends types.TrackSiteSearchParams {}

export interface TrackLinkParams extends types.TrackLinkParams {}
9 changes: 9 additions & 0 deletions packages/react/src/useMatomo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import {
TrackPageViewParams,
TrackEventParams,
TrackSiteSearchParams,
TrackLinkParams,
} from './types'
import useOutboundClickListener from './utils/useOutboundClickListener'

function useMatomo() {
const instance: MatomoInstance = React.useContext(MatomoContext)
Expand All @@ -19,10 +21,17 @@ function useMatomo() {
const trackSiteSearch = (params: TrackSiteSearchParams) =>
instance.trackSiteSearch && instance.trackSiteSearch(params)

const trackLink = (params: TrackLinkParams) =>
instance.trackLink && instance.trackLink(params)

const enableLinkTracking = () => useOutboundClickListener(instance)

return {
trackEvent,
trackPageView,
trackSiteSearch,
trackLink,
enableLinkTracking,
}
}

Expand Down
37 changes: 37 additions & 0 deletions packages/react/src/utils/useOutboundClickListener.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react'
import { MatomoInstance } from '../types'

const useOutboundClickListener = ({ trackLink }: MatomoInstance) => {
const handleOutboundClick = (event: MouseEvent) => {
if (!event.target) {
return
}

const { target } = event
const { nodeName } = target as HTMLElement

if (nodeName === 'A' && trackLink) {
const { href } = target as HTMLAnchorElement // We know from the nodeName that the element is an anchor
// Check if the click target differs from the current hostname, meaning it's external
if (
href &&
!href.match(
new RegExp(
`^(http://www.|https://www.|http://|https://)+(${window.location.hostname})`,
),
)
) {
trackLink({ href })
}
}
}

React.useEffect(() => {
window.document.addEventListener('click', handleOutboundClick)

return () =>
window.document.removeEventListener('click', handleOutboundClick)
}, [])
}

export default useOutboundClickListener

0 comments on commit b4cdd57

Please sign in to comment.