diff --git a/.env.development b/.env.development
index 397a5656..0c2fb552 100644
--- a/.env.development
+++ b/.env.development
@@ -23,6 +23,11 @@ REACT_APP_DEV_DISABLE_LIVE_RELOAD=
FAST_REFRESH=false
+# MATOMO
+REACT_APP_MATOMO_URL=
+REACT_APP_CDN_MATOMO_TRACKER_URL=
+REACT_APP_MATOMO_SITE_ID=
+
#Debug flags
# To enable bounding box for text containers
diff --git a/.env.production b/.env.production
index 183db7ea..8737c63c 100644
--- a/.env.production
+++ b/.env.production
@@ -12,6 +12,13 @@ REACT_APP_WS_SERVER_URL=
REACT_APP_FIREBASE_CONFIG='{"apiKey":"AIzaSyAd15pYlMci_xIp9ko6wkEsDzAAA0Dn0RU","authDomain":"excalidraw-room-persistence.firebaseapp.com","databaseURL":"https://excalidraw-room-persistence.firebaseio.com","projectId":"excalidraw-room-persistence","storageBucket":"excalidraw-room-persistence.appspot.com","messagingSenderId":"654800341332","appId":"1:654800341332:web:4a692de832b55bd57ce0c1"}'
# production-only vars
+# GOOGLE ANALYTICS
REACT_APP_GOOGLE_ANALYTICS_ID=UA-387204-13
+# MATOMO
+REACT_APP_MATOMO_URL=https://excalidraw.matomo.cloud/
+REACT_APP_CDN_MATOMO_TRACKER_URL=//cdn.matomo.cloud/excalidraw.matomo.cloud/matomo.js
+REACT_APP_MATOMO_SITE_ID=1
+
+
REACT_APP_PLUS_APP=https://app.excalidraw.com
diff --git a/public/index.html b/public/index.html
index 35640c0d..47a59624 100644
--- a/public/index.html
+++ b/public/index.html
@@ -146,8 +146,10 @@
// setting this so that libraries installation reuses this window tab.
window.name = "_excalidraw";
- <% if (process.env.REACT_APP_DISABLE_TRACKING !== 'true' &&
- process.env.REACT_APP_GOOGLE_ANALYTICS_ID) { %>
+ <% if (process.env.REACT_APP_DISABLE_TRACKING !== 'true') { %>
+
+
+ <% if (process.env.REACT_APP_GOOGLE_ANALYTICS_ID) { %>
+ <% } %>
+
+
<% } %>
diff --git a/src/analytics.ts b/src/analytics.ts
index 668d49c2..1e9a429b 100644
--- a/src/analytics.ts
+++ b/src/analytics.ts
@@ -1,22 +1,30 @@
-export const trackEvent =
- typeof process !== "undefined" &&
- process.env?.REACT_APP_GOOGLE_ANALYTICS_ID &&
- typeof window !== "undefined" &&
- window.gtag
- ? (category: string, action: string, label?: string, value?: number) => {
- try {
- window.gtag("event", action, {
- event_category: category,
- event_label: label,
- value,
- });
- } catch (error) {
- console.error("error logging to ga", error);
- }
- }
- : typeof process !== "undefined" && process.env?.JEST_WORKER_ID
- ? (category: string, action: string, label?: string, value?: number) => {}
- : (category: string, action: string, label?: string, value?: number) => {
- // Uncomment the next line to track locally
- // console.log("Track Event", { category, action, label, value });
- };
+export const trackEvent = (
+ category: string,
+ action: string,
+ label?: string,
+ value?: number,
+) => {
+ try {
+ // Uncomment the next line to track locally
+ // console.log("Track Event", { category, action, label, value });
+
+ if (typeof window === "undefined" || process.env.JEST_WORKER_ID) {
+ return;
+ }
+
+ if (process.env.REACT_APP_GOOGLE_ANALYTICS_ID && window.gtag) {
+ window.gtag("event", action, {
+ event_category: category,
+ event_label: label,
+ value,
+ });
+ }
+
+ // MATOMO event tracking _paq must be same as the one in index.html
+ if (window._paq) {
+ window._paq.push(["trackEvent", category, action, label, value]);
+ }
+ } catch (error) {
+ console.error("error during analytics", error);
+ }
+};
diff --git a/src/global.d.ts b/src/global.d.ts
index 4a70443d..73c8fc81 100644
--- a/src/global.d.ts
+++ b/src/global.d.ts
@@ -18,6 +18,8 @@ interface Window {
EXCALIDRAW_EXPORT_SOURCE: string;
EXCALIDRAW_THROTTLE_RENDER: boolean | undefined;
gtag: Function;
+ _paq: any[];
+ _mtm: any[];
}
interface CanvasRenderingContext2D {
diff --git a/src/utils.ts b/src/utils.ts
index 4a01e587..1d545f97 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -689,11 +689,7 @@ export const arrayToMapWithIndex = (
return acc;
}, new Map());
-export const isTestEnv = () =>
- typeof process !== "undefined" && process.env?.NODE_ENV === "test";
-
-export const isProdEnv = () =>
- typeof process !== "undefined" && process.env?.NODE_ENV === "production";
+export const isTestEnv = () => process.env.NODE_ENV === "test";
export const wrapEvent = (name: EVENT, nativeEvent: T) => {
return new CustomEvent(name, {