"Vanilla" Matomo in a React.js application


I want to track the usage of a Single Page Application (React.js) with Matomo.
I know there is a guide to include it in SPAs, but it doesn’t work for me. The guide says you should include the tracking code as usual and then call


for every consecutive URL change. But aren’t the _paq.push([‘trackPageView’]); calls supposed to be made before the script is loaded?

It seems to work for the first page view (when the tracking code is executed), but using _paq.push afterwards gives me an error:

_paq.push() was used but Matomo tracker was not initialized before the matomo.js file was loaded. Make sure to configure the tracker via _paq.push before loading matomo.js.

That kind of makes sense to me - but the guide for SPAs seems to suggest the above procedure.

I even tried to execute the full tracker code on every URL change, but of course this prepends a new script tag with the matomo.js for every change (ending up with duplicate script tags) and still gives me the same error.

Is there anything i forgot? I don’t want to use third-party modules like piwik-react-router, because this would force me to change a lot of my application logic just for including the tracking.

Thanks in advance for any help!

(Lukas Winkler) #2


No, you can call _paq functions whenever you like. (After the script is loaded it is replaced with a function that executes them immediatly).

I’m not 100% sure what’s the solution and I also already got confused a bit by this in my vue site, but I think it is just important that you always try to access the window._paq. But I am not that much of a JS expert and might be wrong here. But calling trackPageView on route change is definitly the way to go.

(Lukas Winkler) #3

Of course you can cheat and look how it is solved in piwik-react-router:

Seems like going with window._paq is worth a try.


Thanks for your suggestions so far! I now understand i can push stuff to _paq after the library has loaded.
I’m sorry to say that, but my problem changed a bit: I want to have a true opt-in for the tracking, so i waited to execute the tracking code until the opt-in really happens. To test if this is the problem, i tried to add the tracking code snippet to the static index.html outside of my actual SPA and then fire the _paq.push calls when i need them. And, oh wonder, it works. The problem is that i manage the opt-in in my SPA and don’t want to load the library prior to that. I’m gonna investigate where that problem comes from - from what i can see all i do differently is executing the original tracking code later, not right on page load. Any ideas?
Thanks again!


Another thing i noticed: If I execute the tracker code long after page load (when the opt-in happens), window.Matomo is undefined for the consecutive calls. If i load the script right on page load, everything is where it’s supposed to be.

(Lukas Winkler) #6

Is it possible, that you are loading the tracker in a function, then you should try adding window._paq = _paq at the end of the tracker so it is available globally.
Similar to here:


Yes, I do load the tracker in a function. Your hint sounds very promising, i will try that.
I thought assigning _paq to window._paq is something the loaded library does internally.


@Lukas Thank you! It’s working now. Do you mind if I suggest adding this to the SPA guide? I guess I’m not the only one who wants to wait for an opt-in in a SPA context (which will always bring up the exact same problem i had).