Subscribe to router changes for analytics
I'm looking for a way to centrally define GTM dataLayer pushes based on router state changes, e.g whenever a navigation occurs. We use the dataLayer for tracking all sorts of things for observability.
What's the recommended way of achieving this with wouter?
Something like this (although the onChange property doesn't exist, I know):
<Router
onChange={
() => window.dataLayer.push({ event: 'navigation', /*[...]*/ })
}
>
{/*[...]*/}
</Router>
Perhaps this can be done via hooks?
Thanks in advance for the help
P.S: So glad we don't need to use the behemoth of react-router for simple React apps anymore! Good work!
Wouter doesn't support events yet, as an alternative I can suggest listening to changes of the current location:
const [location] = useLocation()
useEffect(() => {
// some additional logic if you want to avoid sending events on mount or duplicate events
...
}, [location])
@molefrog @jahilldev
For similar things, when I need to perform some action on every navigation, I am using kind of monkey patching of the useLocation
export function useCustomLocation(): HookReturnValue<LocationHook> {
const [location, setLocation] = useBrowserLocation();
const appSetLocation = useCallback(async (to: Path, options?: { replace?: boolean }) => {
// do whatever I want, for example override the to
const destination = `MY_PREFIX/${to}`;
setLocation(destination, options);
}
}, [setLocation]);
return [location, appSetLocation];
}
<Router hook={useCustomLocation}>
{/* when components here call useLocation the useCustomLocation will be used */}
</Router>
@jahilldev If you pass something like a callback to the router, you should also keep in mind that something inside the router might change the title. This means the router should wait until all content has been rendered before running anything, especially when there’s specific data fetching inside nested useEffects that can change the title.
Closing this for now. The approach @nikita-starostin suggested is actually quite good!