qwik
qwik copied to clipboard
[DOCS] Analytics and Scripts
How can the documentation be improved? I want to add analytics without using Partytown. It's unclear to me how to do this.
For Vue and React, I'd usually edit the index.html file and install my own scripts in the
tag like this: https://stackoverflow.com/a/56185465/12713117But I can't find an index.html in Qwik. The examples seem to assume I'm going to use Partytown and that 3rd party analytics will be shoved into a service worker. Although I do approve of this as a general idea, there should be an obvious way to get analytics working without Partytown.
My specific use-case is evaluating Qwik with an apples-to-apples comparison to our Vue website. To do that, I need to ensure things like Analytics are loaded similarly, and since our analytics are loaded in the
tag with defer, that means I need to put our analytics into the tag in Qwik.
To add html tags to the <head>
, <body>
or <html>
, you can add any html tag in src/root.tsx
in <head>
, <body>
or <QwikCity>
.
(Adding to <QwikCity>
is not recommended, as it leads to technically not valid html)
E. g. :
export default component$(() => {
return (
<QwikCity>
<head>
<meta charSet="utf-8" />
<RouterHead />
+ <script type="application/javascript" src="some-script.js" defer />
</head>
<body lang="en">
<RouterOutlet />
<ServiceWorkerRegister />
</body>
</QwikCity>
);
});
Maybe I'm not understanding something simple, but adding a
export default component$(() => {
/**
* The root of a QwikCity site always start with the <QwikCity> component,
* immediately followed by the document's <head> and <body>.
*
* Dont remove the `<head>` and `<body>` elements.
*/
return (
<QwikCity>
<head>
<meta charSet="utf-8" />
<RouterHead />
<script defer async>
window.dataLayer = window.dataLayer || [];
function gtag() { window.dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', '');
gtag('config', '');
</script>
</head>
<body lang="en">
<RouterOutlet />
<ServiceWorkerRegister />
</body>
</QwikCity>
);
});
Because of the errors: Cannot find name 'dataLayer'.ts(2304)
and Cannot find name 'arguments'.ts(2304)
which I assume are causing the Qwik error: [plugin:vite-plugin-qwik] Unexpected token `QwikCity`. Expected jsx identifier
I googled for how to deal with this in React without using index.html and found: https://vancelucas.com/blog/using-google-analytics-with-react/
But that uses dangerouslySetHTML, which I believe is not available in Qwik: https://github.com/BuilderIO/qwik/issues/1033
I've seen dangerouslySetInnerHTML
in qwik:
https://github.com/BuilderIO/qwik/blob/c1e759eef1364984270e0eb1fbc6d0b443ef11ac/starters/apps/basic/src/components/router-head/router-head.tsx#L39
This works for me:
export default component$(() => {
const analyticsScript = `
window.dataLayer = window.dataLayer || [];
function gtag() { window.dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', '');
gtag('config', '');
`;
return (
<QwikCity>
<head>
<meta charSet="utf-8" />
<RouterHead />
<script defer async dangerouslySetInnerHTML={analyticsScript}></script>
</head>
<body lang="en">
<RouterOutlet />
<ServiceWorkerRegister />
</body>
</QwikCity>
);
});
I can see the scripts now, thanks @wtho - I'll do some testing to make sure the analytics scripts are working properly with Qwik, and if they seem to be working, then I'll try to do a docs PR too.
Hi @Gregory-Ledray 👋 Hope everything is up and running on your end 💪 just wanted to dbl check what the current state is and if you still would like to give a hand on creating a PR 👼
relevant part of the root.tsx file
return (
<QwikCityProvider>
<head>
<meta charSet="utf-8" />
<link rel="manifest" href="/manifest.json" />
<QwikPartytown forward={['gtag','dataLayer.push']} />
<script
type="text/partytown"
dangerouslySetInnerHTML={`
window.dataLayer = window.dataLayer || [];
window.gtag = function() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-XXXXXX'); // <-- CHANGE THIS
`}
/>
<script
async
type="text/partytown"
src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXX"
/>
<RouterHead />
</head>
<body lang="en">
<RouterOutlet />
<ServiceWorkerRegister />
</body>
</QwikCityProvider>
);
Courtesy of @kerbelp on Builder.io discord. Worked for me after many hours of struggle <3