Skip to content

Commit 09b6175

Browse files
committed
updated to Google Analytics 4 as Universal Analytics is end of life
1 parent eea0cee commit 09b6175

File tree

5 files changed

+59
-53
lines changed

5 files changed

+59
-53
lines changed

.env.example

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
REACT_APP_GOOGLE_ANALYTICS_TRACKING_ENABLED=false
2-
REACT_APP_GOOGLE_ANALYTICS_TRACKING_ID=UA-000000-01
2+
REACT_APP_GOOGLE_ANALYTICS_TRACKING_ID=UA-000000-01
3+
REACT_APP_GOOGLE_ANALYTICS_GA_MEASUREMENT_ID=G-xxxxxxxxxx

public/index.html

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,32 @@
3535
<!--[if lt IE 9]>
3636
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
3737
<![endif]-->
38+
39+
<!-- Google Analytics 4 - BEGIN -->
40+
<script src="https://www.googletagmanager.com/gtag/js?id=%REACT_APP_GOOGLE_ANALYTICS_GA_MEASUREMENT_ID%">
41+
</script>
42+
<script id="google-analytics">
43+
const isGoogleAnalyticsTrackingEnabled = "true" === "%REACT_APP_GOOGLE_ANALYTICS_TRACKING_ENABLED%".toLowerCase();
44+
const gaMeasurementId = "%REACT_APP_GOOGLE_ANALYTICS_GA_MEASUREMENT_ID%";
45+
46+
if (isGoogleAnalyticsTrackingEnabled && typeof gaMeasurementId !== "undefined") {
47+
console.log("Google Analytics tracking enabled and gaMeasurementId is defined, running Google Analytics gtag codes now");
48+
49+
window.dataLayer = window.dataLayer || [];
50+
function gtag(){dataLayer.push(arguments);}
51+
gtag('js', new Date());
52+
53+
gtag('config', '%REACT_APP_GOOGLE_ANALYTICS_GA_MEASUREMENT_ID%');
54+
} else {
55+
if (!isGoogleAnalyticsTrackingEnabled) {
56+
console.log("Google Analytics gaMeasurementId is defined but Google Analytics tracking is disabled, thus not initializing");
57+
} else {
58+
console.log("Google Analytics gaMeasurementId is not defined, thus not initializing");
59+
}
60+
}
61+
</script>
62+
<!-- Google Analytics 4 - END -->
63+
3864
</head>
3965

4066
<body>

src/App.tsx

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import React from 'react';
33
import "./stylesheets/App.css";
44

55
import StyledTextArea from "./StyledTextArea";
6-
import {transform} from './transform';
7-
import {promiseReverse} from "./reverse";
6+
import { transform } from './transform';
7+
import { promiseReverse } from "./reverse";
88
import GoogleAnalyticsManager from "./services/GoogleAnalyticsManager";
99

1010
const initialStarterText = "";
@@ -30,13 +30,6 @@ enum TRANSLATION_ACTIONS {
3030
export default class App extends React.Component<AppProps, AppState> {
3131
private readonly gAManager: GoogleAnalyticsManager = new GoogleAnalyticsManager();
3232

33-
componentDidMount(): void {
34-
if (typeof window !== "undefined") {
35-
const path = window.location.pathname + window.location.search;
36-
this.gAManager.pageview(path);
37-
}
38-
}
39-
4033
constructor(props) {
4134
super(props);
4235
this.update = this.update.bind(this);
@@ -48,8 +41,6 @@ export default class App extends React.Component<AppProps, AppState> {
4841
outputText: initialStarterText,
4942
shouldFormat: false
5043
};
51-
52-
this.gAManager.init();
5344
}
5445

5546
inputTextUpdate(e) {
@@ -138,7 +129,7 @@ export default class App extends React.Component<AppProps, AppState> {
138129
value={outputText}
139130
isError={!!this.state.error}
140131
/>
141-
<br/>
132+
<br />
142133
<input
143134
id="checkbox-format"
144135
className="checkbox-format"
@@ -152,9 +143,8 @@ export default class App extends React.Component<AppProps, AppState> {
152143
}
153144

154145
private trackTranslation(action: TRANSLATION_ACTIONS) {
155-
this.gAManager.event({
156-
category: GA_TRACKING_CATEGORIES.TRANSLATION,
157-
action
146+
this.gAManager.event(GA_TRACKING_CATEGORIES.TRANSLATION, {
147+
action,
158148
});
159149
}
160150
}

src/global.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// reference: https://www.emmanuelgautier.com/blog/typescript-extend-window
2+
declare global {
3+
interface Window {
4+
gtag?: (...args: any[]) => void
5+
dataLayer?: Record<string, any>
6+
}
7+
}
Lines changed: 19 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,35 @@
1-
import ReactGA, {EventArgs} from 'react-ga';
2-
31
export default class GoogleAnalyticsManager {
4-
private _isInitialized: boolean = false;
5-
6-
public init() {
7-
const isGoogleAnalyticsTrackingEnabled = isTrue(process.env.REACT_APP_GOOGLE_ANALYTICS_TRACKING_ENABLED);
8-
const trackingId = process.env.REACT_APP_GOOGLE_ANALYTICS_TRACKING_ID;
9-
10-
if (isGoogleAnalyticsTrackingEnabled && trackingId) {
11-
console.log("Google Analytics tracking enabled and trackingId is defined, initializing Google Analytics module now");
12-
ReactGA.initialize(trackingId);
13-
this._isInitialized = true;
14-
} else {
15-
if (!isGoogleAnalyticsTrackingEnabled) {
16-
console.log("Google Analytics tracking disabled and trackingId is defined, thus not initializing");
17-
} else {
18-
console.log("Google Analytics trackingId is not defined, thus not initializing");
19-
}
20-
}
21-
}
22-
232
public pageview(path: string) {
24-
this.safeReactGaTrack({
25-
track: () => ReactGA.pageview(path),
26-
trackDescription: `pageview at path: ${path}`
3+
this.event('page_view', {
4+
page_location: path
275
});
286
}
297

30-
public event(args: EventArgs) {
31-
this.safeReactGaTrack({
32-
track: () => ReactGA.event(args),
33-
trackDescription: `event with args: ${JSON.stringify(args)}`,
34-
});
8+
public event(eventName: string, eventParams: Record<string, string> = {}) {
9+
const trackDescription = `event '${eventName}'${eventParams ? `with args: ${JSON.stringify(eventParams)}` : ''}`;
10+
if (this.isInitialized()) {
11+
console.log(trackDescription);
12+
window['gtag']('event', eventName, eventParams);
13+
} else {
14+
console.warn(`Not initialized - not going to send ${trackDescription}`);
15+
}
3516
}
3617

3718
public isInitialized(): boolean {
38-
return this._isInitialized;
39-
}
19+
const isGoogleAnalyticsTrackingEnabled = isTrue(process.env.REACT_APP_GOOGLE_ANALYTICS_TRACKING_ENABLED);
20+
const gaMeasurementId = process.env.REACT_APP_GOOGLE_ANALYTICS_GA_MEASUREMENT_ID;
21+
const isGtagFunctionDefined = typeof window['gtag'] === "function";
4022

41-
private safeReactGaTrack({track, trackDescription}: { track: () => any, trackDescription: string }) {
42-
if (this.isInitialized()) {
43-
console.log(trackDescription);
44-
track();
23+
if (isGoogleAnalyticsTrackingEnabled && gaMeasurementId && isGtagFunctionDefined) {
24+
console.log("Google Analytics tracking enabled and gaMeasurementId is defined, Google Analytics tracking is available");
25+
return true;
4526
} else {
46-
console.warn(`Not initialized - not going to send ${trackDescription}`);
27+
console.log(`Google Analytics tracking not available, details: isGoogleAnalyticsTrackingEnabled=${isGoogleAnalyticsTrackingEnabled}, isGtagFunctionDefined=${isGtagFunctionDefined}}`);
28+
return false;
4729
}
4830
}
4931
}
5032

5133
function isTrue(optionalString?: string): boolean {
5234
return (typeof optionalString !== "undefined") && ("true" === optionalString.toLowerCase());
53-
}
35+
}

0 commit comments

Comments
 (0)