Reputation:
So currently one can chose between Universal Analytics and Google Analytics 4.
My arguments as why to use Google Analytics 4:
react-ga
is in passive maintenance and it wont be updated to support GA-4 unless someone else makes a PR.react-ga4
module that works with GA-4So I created a property on GA and followed this guide
I installed th module and just initialized in my main index.tsx file with ReactGA.initialize
.
The ID is not stored in an env file as it is public anyway according to this answer.
A test on localhost shows that GA picks up the data.
No more code is needed. GA4 is intelligent enough to measure all of those interactions automatically. You don’t have to bother to code them in your project. GA4 automatically measures interactions and content on sites in addition to standard page view measurement: Page views, scrolls, outbound clicks, site search, video engagement and file downloads. See: Enhanced measurement Events
Any other use case based events, we have to code by ourself. That’s basically unchanged from Universal Analytics.
So my 1. Question is: Are the information I gathered together correct? Would you integrate it in another way? Or am I missing something?
In general I am wondering what the benefit of using the library is?
--> Alternatively I could do for integration: Add the global site tag directly to your web pages
What is the better approach?
Now the second part, in the first code snippet you see the react-ga4 initialization in my index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import ReactGA from 'react-ga4';
ReactGA.initialize('G-XXXXXXXX');
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
A test on localhost shows that data gets picked up in GA dashboard. Perfect!
But then there is the problem with Adblocker crashes. It typically crashes the app if someone has an adblocker (adblocker blocks analytics request endpoints, no error handling, etc) and to mitigate this we detect whether the script didn't load and hence derive if the user has an adblocker that's preventing the GA script from loading. In my example code, I just ignore it and load the app... in other scenarios, I suppose you could invoke a modal to tell them to disable it (of course, that would come with extra code). Taken from spencer741 response
index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import ReactGA from 'react-ga4';
(async _ => {
await ReactGA.initialize('G-XXXXXXXXX')
.then(res => console.log("Analytics Success."))
.catch(err => console.log("Analytics Failure."))
.finally(() => {
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
});
})();
I know that this throws errors in Typescript right now:
Property 'then' does not exist on type 'void'.
Property 'catch' does not exist on type 'void'.
Property 'finally' does not exist on type 'void'.
'res' is declared but its value is never read.
Parameter 'res' implicitly has an 'any' type.
'err' is declared but its value is never read.
Parameter 'err' implicitly has an 'any' type.
But before I try to resolve the errors I would like to know if Is this a viable solution to circumvent potential errors with adblocker?
Upvotes: 7
Views: 7696
Reputation: 11
The best solution is to use the gtag directly, if using reactjs paste the code into your index.html file under public
Image showing index.html file under public inside reactjs source code
Upvotes: 1
Reputation: 1566
Since there are no other answers, I'll try to answer OP's questions to the best of my abilities.
1. Are the information I gathered together correct?
Yes and no. Although both libraries do what they say they do, I'd take "GA4 is intelligent enough to measure all of those interactions automatically" with a pinch of salt, since both of them require some configuration to track custom events or multiple trackingId
and fine tune your analytics. See react-ga4
repository and react-ga
demo.
2. Would you integrate it in another way? Or am I missing something? If by "another way" you meant other than the question's examples, yes. As said in the comments, a better approach would be wrapping up all your GA logic, either with a Higher-Order Component or a custom hook (examples below).
3. In general I am wondering what the benefit of using the library is?
I think that depends on your project's needs. If you're working on a temporary project or minimum value product (MVP) that may not be in production a year from now, you might be better off with react-ga
since it's been battle-tested and currently has 600k downloads per week on NPM. If not, updating your code-base to react-ga4
might help minimising technical debts in the future and leveraging Google Analytics 4 updates.
4. What is the better approach?
From GA4 answers, there are currently 8 events you can further customize. Let's see how we could implement a custom hook with react-ga4
:
ga4.ts
import ga4 from 'react-ga4'
const TRACKING_ID = 'G-XXXXXXXXX-X'
const isProduction = process.env.NODE_ENV === 'production'
export const init = () => ga4.initialize(TRACKING_ID, {
testMode: !isProduction
})
export const sendEvent = (name: string) => ga4.event('screen_view', {
app_name: "myApp",
screen_name: name,
})
export const sendPageview = (path: string) => ga4.send({
hitType: 'pageview',
page: path
})
useAnalytics.ts
import React from 'react'
import { useLocation } from 'react-router-dom'
import * as analytics from './ga4'
export function useAnalytics() {
const location = useLocation()
React.useEffect(() => {
analytics.init()
}, [])
React.useEffect(() => {
const path = location.pathname + location.search
analytics.sendPageview(path)
}, [location])
}
export default useAnalytics
Alternatively, if you're not using react-router-dom
you could get the path from the global window
object, like so:
analytics.sendPageview(window.location.pathname)
Or with Next.js:
const router = useRouter()
analytics.sendPageview(router.asPath)
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Switch } from 'react-router-dom'
import { useAnalytics } from './useAnalytics'
function App() {
useAnalytics() // add it here
return <Switch>...</Switch>
}
ReactDOM.render(
<Router>
<App />
</Router>,
node
)
5. Is this a viable solution to circumvent potential errors with adblocker?
There is a tutorial on FreeCodeCamp.org showing how to use proxies to avoid adblockers. You could also use libraries such as FuckAdBlock
, BlockAdBlock
or adblock-detect-react
to check if ad block is enabled on a page and initialize react-ga4
conditionally. As a reminder: it takes normally 24/48 hours for analytics to be gathered. New GA accounts can take a few days before it starts recording data.
import React from 'react'
import { useDetectAdBlock } from 'adblock-detect-react'
const useAnalytics = () => {
const adBlockDetected = useDetectAdBlock()
React.useEffect(() => {
if(!adBlockDetected) analytics.init()
}, [])
React.useEffect(() => {
if (!adBlockDetected) {
analytics.sendPageview(window.location.pathname)
}
} [adBlockDetected, path])
}
Hope that helps! Cheers.
Upvotes: 18