feat: Add support for GA4 measurement IDs in GOOGLE_ANALYTICS_ID

This commit is contained in:
Tom Moor
2023-05-08 12:01:35 -04:00
parent a0df79ea5a
commit 1cf597aca7
3 changed files with 24 additions and 19 deletions

View File

@@ -3,13 +3,7 @@
"description": "Open source wiki and knowledge base for growing teams", "description": "Open source wiki and knowledge base for growing teams",
"website": "https://www.getoutline.com/", "website": "https://www.getoutline.com/",
"repository": "https://github.com/outline/outline", "repository": "https://github.com/outline/outline",
"keywords": [ "keywords": ["wiki", "team", "node", "markdown", "slack"],
"wiki",
"team",
"node",
"markdown",
"slack"
],
"success_url": "/", "success_url": "/",
"formation": { "formation": {
"web": { "web": {
@@ -188,7 +182,7 @@
"required": false "required": false
}, },
"GOOGLE_ANALYTICS_ID": { "GOOGLE_ANALYTICS_ID": {
"description": "UA-xxxx (optional)", "description": "G-xxxx (optional)",
"required": false "required": false
}, },
"SENTRY_DSN": { "SENTRY_DSN": {

View File

@@ -8,7 +8,7 @@ import env from "~/env";
const Analytics: React.FC = ({ children }) => { const Analytics: React.FC = ({ children }) => {
// Google Analytics 3 // Google Analytics 3
React.useEffect(() => { React.useEffect(() => {
if (!env.GOOGLE_ANALYTICS_ID) { if (!env.GOOGLE_ANALYTICS_ID?.startsWith("UA-")) {
return; return;
} }
@@ -37,25 +37,38 @@ const Analytics: React.FC = ({ children }) => {
// Google Analytics 4 // Google Analytics 4
React.useEffect(() => { React.useEffect(() => {
if (env.analytics.service !== IntegrationService.GoogleAnalytics) { const measurementIds = [];
if (env.analytics.service === IntegrationService.GoogleAnalytics) {
measurementIds.push(escape(env.analytics.settings?.measurementId));
}
if (env.GOOGLE_ANALYTICS_ID?.startsWith("G-")) {
measurementIds.push(env.GOOGLE_ANALYTICS_ID);
}
if (measurementIds.length === 0) {
return; return;
} }
const measurementId = escape(env.analytics.settings?.measurementId); const params = {
allow_google_signals: false,
restricted_data_processing: true,
};
window.dataLayer = window.dataLayer || []; window.dataLayer = window.dataLayer || [];
window.gtag = function () { window.gtag = function () {
window.dataLayer.push(arguments); window.dataLayer.push(arguments);
}; };
window.gtag("js", new Date()); window.gtag("js", new Date());
window.gtag("config", measurementId, {
allow_google_signals: false, for (const measurementId of measurementIds) {
restricted_data_processing: true, window.gtag("config", measurementId, params);
}); }
const script = document.createElement("script"); const script = document.createElement("script");
script.type = "text/javascript"; script.type = "text/javascript";
script.src = `https://www.googletagmanager.com/gtag/js?id=${measurementId}`; script.src = `https://www.googletagmanager.com/gtag/js?id=${measurementIds.join(
","
)}`;
script.async = true; script.async = true;
document.getElementsByTagName("head")[0]?.appendChild(script); document.getElementsByTagName("head")[0]?.appendChild(script);
}, []); }, []);

View File

@@ -16,7 +16,6 @@ import {
IsIn, IsIn,
IsEmail, IsEmail,
IsBoolean, IsBoolean,
Contains,
MaxLength, MaxLength,
} from "class-validator"; } from "class-validator";
import { languages } from "@shared/i18n"; import { languages } from "@shared/i18n";
@@ -344,9 +343,8 @@ export class Environment {
public RELEASE = this.toOptionalString(process.env.RELEASE); public RELEASE = this.toOptionalString(process.env.RELEASE);
/** /**
* A Google Analytics tracking ID, supports only v3 properties. * A Google Analytics tracking ID, supports v3 or v4 properties.
*/ */
@Contains("UA-")
@IsOptional() @IsOptional()
public GOOGLE_ANALYTICS_ID = this.toOptionalString( public GOOGLE_ANALYTICS_ID = this.toOptionalString(
process.env.GOOGLE_ANALYTICS_ID process.env.GOOGLE_ANALYTICS_ID