Open bamboechop opened 2 years ago
Yes, Matomo is not provided until the script is loaded. I'm not familiar with Quasar, but I don't think there's much we can do about that.
What is the point of even providing an injection then though if there is no way for vue-matomo to delay initialization of a Vue app. Everything that injects vue-matomo won't get anything because it ain't ready anyways.
Maybe related to this topic but is there a way to access $matomo through the composition API? When using Vue.use(VueMatomo)
it is not possible to access $matomo inside the composition API
Maybe related to this topic but is there a way to access $matomo through the composition API? When using
Vue.use(VueMatomo)
it is not possible to access $matomo inside the composition API
https://github.com/AmazingDreams/vue-matomo/blob/master/src/index.js#L81
if (version > 2) {
Vue.config.globalProperties.$piwik = Matomo
Vue.config.globalProperties.$matomo = Matomo
Vue.provide(matomoKey, Matomo)
}
Since the globalProperties are only an legacy escape hatch and NOT for the setup function you could use getCurrentInstance
. But that is not intended for userland, only for internal access and was documented in the v3 docs by mistake. https://stackoverflow.com/a/72940466/7447314
The alternative is to inject Matomo in the components that you want to use it within which then leads to the problem I reported here. Since vue-matomo doesn't wait for Matomo to be loaded your Vue application starts up and some time later Matomo becomes available. Any component that injects Matomo before it is loaded will receive undefined
instead and injects are not reactive.
So with Composition API you basically have no way of using the provided Matomo instance, you have to rely on window._paq completely.
Edit: You might be able to use Matomo by injecting when you hide your whole app behind a loading spinner that only goes away once Matomo is loaded and window._paq
is available.
<template>
<div>
<template v-if="!pageLoading">
[your app components]
</template>
<template v-if="pageLoading">
[loading spinner component]
</template>
</div>
</template>
<script setup>
const pageLoading = ref(true);
onMounted() {
checkMatomoAvailablility();
}
function checkMatomoAvailability() {
if(window._paq) {
this.pageLoading = false;
} else {
window.setTimeout(checkMatomoAvailability(), 1000);
}
}
</script>
Then your components should receive Matomo when injecting it. Didn't test the code, just thought about it. :thinking:
Hello,
I'm currently rewriting my vue-matomo implementation to allow the user to consent to the data tracking. For this reason I want to show a dialog on page load that informs the user about the intended usage of Matomo and asks for his consent.
When looking through the source code I found that vue-matomo provides the Matomo instance during setup.
I'm using the Quasar framework and there I created a boot file that sets up vue-matomo for me. So far, so good.
When I now try to grab the provided Matomo instance via the
matomoKey
(btw. the whole provide/inject part is missing in the documentation, is this still a WIP?) by injecting it in my dialog component I receive a Vue warning.When I delay my dialog component by a few seconds the injection works as expected. Now the boot files in Quasar run before the root Vue app instance is instantiated and therefore are the ideal place to do this. I suspect that due to the async nature of what's going on during the install function of vue-matomo (loadScript async, piwikExists check async) the initial
app.use(VueMatomo, { ... })
call finishes without waiting for all the async stuff to really be done. This then allows Quasar to continue with rendering the app as the boot file is "done", rendering my dialog who tries to inject Matomo and fails due to Matomo not being provided yet.I could of course switch to the window variables and use those instead but since you already provide the Matomo instance I'd prefer to use the "correct" way here and inject it whenever I need it. Is there anything that I'm currently overlooking and doing wrong or is the
app.use(VueMatomo, { ... });
at the moment indeed not aware of the async stuff happening within the install function?