matomo-tracker
matomo-tracker copied to clipboard
Integrate it with react.Router history
Is your feature request related to a problem? Please describe. I was expecting this lib to integrate with React Router out of the box, such as https://github.com/guillaumeparis2000/react-piwik :
<Provider store={store}>
<Router routes={routes} history={piwik.connectToHistory(history, trackAtConnect)} />
</Provider>,
Describe the solution you'd like I'd like sth similar as above or at least a README on how to listen to history events and track pageViews on history changes.
Describe alternatives you've considered Choosing another lib or implementing it myself.
Implementing it was quite fast:
import { MatomoProvider, createInstance } from '@datapunt/matomo-tracker-react';
import { getRuntimeEnvVar } from 'helpers';
import { useEffect } from 'react';
import { useLocation } from 'react-router';
export const createClient = () => {
const host = getRuntimeEnvVar('REACT_APP_RUNTIME_MATOMO_HOST');
const siteId = parseInt(getRuntimeEnvVar('REACT_APP_RUNTIME_MATOMO_SITE_ID'));
return createInstance({
urlBase: host,
siteId: siteId,
// userId: 'UID76903202', // optional, default value: `undefined`. // TODO CDC-1389
trackerUrl: `${host}/piwik.php`, // optional, default value: `${urlBase}matomo.php`
srcUrl: `${host}/piwik.js`, // optional, default value: `${urlBase}matomo.js`
heartBeat: { // optional, enabled by default
active: true, // optional, default value: true
seconds: 30 // optional, default value: `15
},
linkTracking: true, // optional, default value: true
configurations: { // optional, default value: {}
// any valid matomo configuration, all below are optional
// disableCookies: true,
setSecureCookie: true,
setRequestMethod: 'POST'
// TODO POST is default, but we would need to setup CORS: https://developer.matomo.org/api-reference/tracking-javascript
}
})
}
/**
* MatomoRouterProvider provides Matomo hooks for children components
* and it tracks page views on location change.
*
* It should be embedded within <Router>
*/
export const MatomoRouterProvider = (
{children}: {children: JSX.Element}) => {
const isEnabled = getRuntimeEnvVar('REACT_APP_RUNTIME_MATOMO_ENABLED');
if (!isEnabled) {
return children;
}
const matomoClient = createClient();
let location = useLocation();
useEffect(() => {
// track page view on each location change
matomoClient.trackPageView()
}, [location]);
return (
<MatomoProvider value={matomoClient}>
{children}
</MatomoProvider>
)
}
/**
* withMatomo is an HOC to wrap other component in order to provide Matomo to children
*
* It does not integrate with react-router
*
* @param Child
*/
export const withMatomo = <T,>(Child: React.ComponentType<T>) => {
const isEnabled = getRuntimeEnvVar('REACT_APP_RUNTIME_MATOMO_ENABLED');
if (!isEnabled) {
return Child;
}
const matomoClient = createClient();
return (props: T) => (
<MatomoProvider value={matomoClient}>
<Child {...props}/>
</MatomoProvider>
);
}
We might be able to make this a separate package to connect the two together. At the moment we are busy with the new API design and migrating some internal applications, so this is on the back-burner for now.
As mentioned by @KrzysztofMadejski, it's pretty trivial to add this in the application code. So we are going to recommend doing so for now.