From 2ea91aaabfec51de37a1289e040de2792654b72b Mon Sep 17 00:00:00 2001
From: Bartosz Hernas
Date: Mon, 14 Sep 2020 18:13:59 +0200
Subject: [PATCH 1/8] Ability to unregister umami
---
lib/web.js | 8 +++++---
tracker/index.js | 12 ++++++++++--
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/lib/web.js b/lib/web.js
index 4a8578f1..784a9e1e 100644
--- a/lib/web.js
+++ b/lib/web.js
@@ -39,12 +39,14 @@ export const put = (url, params) => apiRequest('put', url, JSON.stringify(params
export const hook = (_this, method, callback) => {
const orig = _this[method];
-
- return (...args) => {
+ _this[method] = (...args) => {
callback.apply(null, args);
-
return orig.apply(_this, args);
};
+
+ return () => {
+ _this[method] = orig;
+ };
};
export const doNotTrack = () => {
diff --git a/tracker/index.js b/tracker/index.js
index f7f00927..0b91d4e7 100644
--- a/tracker/index.js
+++ b/tracker/index.js
@@ -73,8 +73,8 @@ import { removeTrailingSlash } from '../lib/url';
pageView();
};
- history.pushState = hook(history, 'pushState', handlePush);
- history.replaceState = hook(history, 'replaceState', handlePush);
+ const pushStateUnhook = hook(history, 'pushState', handlePush);
+ const replaceStateUnhook = hook(history, 'replaceState', handlePush);
/* Handle events */
@@ -106,4 +106,12 @@ import { removeTrailingSlash } from '../lib/url';
if (!window.umami) {
window.umami = event_value => collect('event', { event_type: 'custom', event_value });
}
+
+ if (!window.umamiUnregister) {
+ window.umamiUnregister = () => {
+ pushStateUnhook();
+ replaceStateUnhook();
+ removeEvents();
+ };
+ }
})(window);
From d19bcbabe053e6b6eb80138818acaa0bed70ea7a Mon Sep 17 00:00:00 2001
From: Bartosz Hernas
Date: Tue, 15 Sep 2020 00:09:09 +0200
Subject: [PATCH 2/8] Different method + fixed lint for tracker + added frame
mode for shared URLs
---
lib/web.js | 10 +++---
pages/share/[...id].js | 4 +--
tracker/index.js | 69 ++++++++++++++++++++++--------------------
3 files changed, 42 insertions(+), 41 deletions(-)
diff --git a/lib/web.js b/lib/web.js
index 784a9e1e..4a8578f1 100644
--- a/lib/web.js
+++ b/lib/web.js
@@ -39,13 +39,11 @@ export const put = (url, params) => apiRequest('put', url, JSON.stringify(params
export const hook = (_this, method, callback) => {
const orig = _this[method];
- _this[method] = (...args) => {
- callback.apply(null, args);
- return orig.apply(_this, args);
- };
- return () => {
- _this[method] = orig;
+ return (...args) => {
+ callback.apply(null, args);
+
+ return orig.apply(_this, args);
};
};
diff --git a/pages/share/[...id].js b/pages/share/[...id].js
index 1e0897a9..50467bf6 100644
--- a/pages/share/[...id].js
+++ b/pages/share/[...id].js
@@ -6,7 +6,7 @@ import useFetch from 'hooks/useFetch';
export default function SharePage() {
const router = useRouter();
- const { id } = router.query;
+ const { id, frame } = router.query;
const shareId = id?.[0];
const { data } = useFetch(shareId ? `/api/share/${shareId}` : null);
@@ -15,7 +15,7 @@ export default function SharePage() {
}
return (
-
+
);
diff --git a/tracker/index.js b/tracker/index.js
index 0b91d4e7..7bb1b7b3 100644
--- a/tracker/index.js
+++ b/tracker/index.js
@@ -1,6 +1,6 @@
import 'promise-polyfill/src/polyfill';
import 'unfetch/polyfill';
-import { post, hook, doNotTrack } from '../lib/web';
+import { doNotTrack, hook, post } from '../lib/web';
import { removeTrailingSlash } from '../lib/url';
(window => {
@@ -31,25 +31,7 @@ import { removeTrailingSlash } from '../lib/url';
/* Collect metrics */
const collect = (type, params) => {
- const payload = {
- url: currentUrl,
- referrer: currentRef,
- website,
- hostname,
- screen,
- language,
- };
-
- if (params) {
- Object.keys(params).forEach(key => {
- payload[key] = params[key];
- });
- }
-
- return post(`${root}/api/collect`, {
- type,
- payload,
- });
+ return window.umamiTrack(website, type, params);
};
const pageView = () => collect('pageview').then(() => setTimeout(loadEvents, 300));
@@ -73,8 +55,8 @@ import { removeTrailingSlash } from '../lib/url';
pageView();
};
- const pushStateUnhook = hook(history, 'pushState', handlePush);
- const replaceStateUnhook = hook(history, 'replaceState', handlePush);
+ history.pushState = hook(history, 'pushState', handlePush);
+ history.replaceState = hook(history, 'replaceState', handlePush);
/* Handle events */
@@ -86,7 +68,7 @@ import { removeTrailingSlash } from '../lib/url';
};
const loadEvents = () => {
- document.querySelectorAll("[class*='umami--']").forEach(element => {
+ document.querySelectorAll('[class*=\'umami--\']').forEach(element => {
element.className.split(' ').forEach(className => {
if (/^umami--([a-z]+)--([a-z0-9_]+[a-z0-9-_]+)$/.test(className)) {
const [, type, value] = className.split('--');
@@ -99,19 +81,40 @@ import { removeTrailingSlash } from '../lib/url';
});
};
- /* Start */
+ if (!window.umamiTrack) {
+ window.umamiTrack = (type, params, id) => {
+ if (!id) {
+ id = website
+ }
+ const payload = {
+ url: currentUrl,
+ referrer: currentRef,
+ website: id,
+ hostname,
+ screen,
+ language,
+ };
- pageView();
+ if (params) {
+ Object.keys(params).forEach(key => {
+ payload[key] = params[key];
+ });
+ }
+
+ return post(`${root}/api/collect`, {
+ type,
+ payload,
+ });
+ };
+ }
+
+ /* Start */
+ const skipAuto = new URL(script.src).search.includes('auto=false');
+ if (!skipAuto) {
+ pageView();
+ }
if (!window.umami) {
window.umami = event_value => collect('event', { event_type: 'custom', event_value });
}
-
- if (!window.umamiUnregister) {
- window.umamiUnregister = () => {
- pushStateUnhook();
- replaceStateUnhook();
- removeEvents();
- };
- }
})(window);
From d6d1c68e6dbacdda3aa8b2fac70322a1c873f49e Mon Sep 17 00:00:00 2001
From: Bartosz Hernas
Date: Tue, 15 Sep 2020 00:12:09 +0200
Subject: [PATCH 3/8] Fix tracker
---
tracker/index.js | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/tracker/index.js b/tracker/index.js
index 7bb1b7b3..9c00a47b 100644
--- a/tracker/index.js
+++ b/tracker/index.js
@@ -55,9 +55,6 @@ import { removeTrailingSlash } from '../lib/url';
pageView();
};
- history.pushState = hook(history, 'pushState', handlePush);
- history.replaceState = hook(history, 'replaceState', handlePush);
-
/* Handle events */
const removeEvents = () => {
@@ -84,7 +81,7 @@ import { removeTrailingSlash } from '../lib/url';
if (!window.umamiTrack) {
window.umamiTrack = (type, params, id) => {
if (!id) {
- id = website
+ id = website;
}
const payload = {
url: currentUrl,
@@ -111,6 +108,8 @@ import { removeTrailingSlash } from '../lib/url';
/* Start */
const skipAuto = new URL(script.src).search.includes('auto=false');
if (!skipAuto) {
+ history.pushState = hook(history, 'pushState', handlePush);
+ history.replaceState = hook(history, 'replaceState', handlePush);
pageView();
}
From d5e49141532455b409310b920e98cdf19b0ed3bb Mon Sep 17 00:00:00 2001
From: Bartosz Hernas
Date: Tue, 15 Sep 2020 12:03:34 +0200
Subject: [PATCH 4/8] Comments fixed
---
pages/share/[...id].js | 4 ++--
tracker/index.js | 44 +++++++++++++++++++++---------------------
2 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/pages/share/[...id].js b/pages/share/[...id].js
index 50467bf6..1e0897a9 100644
--- a/pages/share/[...id].js
+++ b/pages/share/[...id].js
@@ -6,7 +6,7 @@ import useFetch from 'hooks/useFetch';
export default function SharePage() {
const router = useRouter();
- const { id, frame } = router.query;
+ const { id } = router.query;
const shareId = id?.[0];
const { data } = useFetch(shareId ? `/api/share/${shareId}` : null);
@@ -15,7 +15,7 @@ export default function SharePage() {
}
return (
-
+
);
diff --git a/tracker/index.js b/tracker/index.js
index 9c00a47b..ff7f0995 100644
--- a/tracker/index.js
+++ b/tracker/index.js
@@ -19,6 +19,7 @@ import { removeTrailingSlash } from '../lib/url';
const website = script.getAttribute('data-website-id');
const hostUrl = script.getAttribute('data-host-url');
+ const skipAuto = script.getAttribute('data-skip-auto');
const root = hostUrl
? removeTrailingSlash(hostUrl)
: new URL(script.src).href.split('/').slice(0, -1).join('/');
@@ -29,14 +30,7 @@ import { removeTrailingSlash } from '../lib/url';
let currentRef = document.referrer;
/* Collect metrics */
-
- const collect = (type, params) => {
- return window.umamiTrack(website, type, params);
- };
-
- const pageView = () => collect('pageview').then(() => setTimeout(loadEvents, 300));
-
- const pageEvent = (event_type, event_value) => collect('event', { event_type, event_value });
+ const pageViewWithAutoEvents = (url, referrer) => window.umami.pageView(url, referrer).then(() => setTimeout(loadEvents, 300));
/* Handle history */
@@ -52,7 +46,7 @@ import { removeTrailingSlash } from '../lib/url';
currentUrl = newUrl;
}
- pageView();
+ pageViewWithAutoEvents(currentUrl, currentRef);
};
/* Handle events */
@@ -69,7 +63,7 @@ import { removeTrailingSlash } from '../lib/url';
element.className.split(' ').forEach(className => {
if (/^umami--([a-z]+)--([a-z0-9_]+[a-z0-9-_]+)$/.test(className)) {
const [, type, value] = className.split('--');
- const listener = () => pageEvent(type, value);
+ const listener = () => window.umami.event(type, value);
listeners.push([element, type, listener]);
element.addEventListener(type, listener, true);
@@ -78,14 +72,13 @@ import { removeTrailingSlash } from '../lib/url';
});
};
- if (!window.umamiTrack) {
- window.umamiTrack = (type, params, id) => {
+ if (!window.umami) {
+ window.umami = event_value => window.umami.event('custom', event_value, currentUrl);
+ window.umami.collect = (type, params, id) => {
if (!id) {
id = website;
}
const payload = {
- url: currentUrl,
- referrer: currentRef,
website: id,
hostname,
screen,
@@ -103,17 +96,24 @@ import { removeTrailingSlash } from '../lib/url';
payload,
});
};
+ window.umami.pageView = (url = currentUrl, referrer = currentRef) => window.umami.collect('pageview', {
+ url,
+ referrer,
+ });
+ window.umami.event = (event_type, event_value, url = currentUrl) => window.umami.collect('event', {
+ url,
+ event_type,
+ event_value,
+ });
+ window.umami.registerAutoEvents = () => {
+ history.pushState = hook(history, 'pushState', handlePush);
+ history.replaceState = hook(history, 'replaceState', handlePush);
+ return pageViewWithAutoEvents(currentUrl, currentRef);
+ };
}
/* Start */
- const skipAuto = new URL(script.src).search.includes('auto=false');
if (!skipAuto) {
- history.pushState = hook(history, 'pushState', handlePush);
- history.replaceState = hook(history, 'replaceState', handlePush);
- pageView();
- }
-
- if (!window.umami) {
- window.umami = event_value => collect('event', { event_type: 'custom', event_value });
+ window.umami.registerAutoEvents().catch(e => console.error(e));
}
})(window);
From 7a71bb1c68256ee611cc6751f9c4295a3714b004 Mon Sep 17 00:00:00 2001
From: Bartosz Hernas
Date: Tue, 15 Sep 2020 13:54:35 +0200
Subject: [PATCH 5/8] Better snippet
---
.gitignore | 1 +
components/forms/TrackingCodeForm.js | 5 +-
package.json | 1 +
rollup.snippet.config.js | 19 ++++++
tracker/index.js | 87 +++++++++++++++++-----------
tracker/snippet.js | 42 ++++++++++++++
6 files changed, 119 insertions(+), 36 deletions(-)
create mode 100644 rollup.snippet.config.js
create mode 100644 tracker/snippet.js
diff --git a/.gitignore b/.gitignore
index ca0f3c4f..8b349dbb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,7 @@
# production
/build
/public/umami.js
+/public/snippet.js
/lang-compiled
/lang-formatted
diff --git a/components/forms/TrackingCodeForm.js b/components/forms/TrackingCodeForm.js
index a98b471d..36dda30e 100644
--- a/components/forms/TrackingCodeForm.js
+++ b/components/forms/TrackingCodeForm.js
@@ -17,12 +17,15 @@ export default function TrackingCodeForm({ values, onClose }) {
/>
+ {/* Run `npm run build-snippet, and copy paste here the content of public/snippet.js */}
+ {/* TODO: use webpack importing function to import the content of the file here ? */}
diff --git a/package.json b/package.json
index e6dc21ec..e600611d 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
"start": "next start",
"build-app": "next build",
"build-tracker": "rollup -c rollup.tracker.config.js",
+ "build-snippet": "rollup -c rollup.snippet.config.js",
"copy-db-schema": "node scripts/copy-db-schema.js",
"build-db-schema": "dotenv prisma introspect",
"build-db-client": "dotenv prisma generate",
diff --git a/rollup.snippet.config.js b/rollup.snippet.config.js
new file mode 100644
index 00000000..c5925988
--- /dev/null
+++ b/rollup.snippet.config.js
@@ -0,0 +1,19 @@
+import 'dotenv/config';
+import buble from '@rollup/plugin-buble';
+import replace from '@rollup/plugin-replace';
+import resolve from '@rollup/plugin-node-resolve';
+import { terser } from 'rollup-plugin-terser';
+
+export default {
+ input: 'tracker/snippet.js',
+ output: {
+ file: 'public/snippet.js',
+ format: 'iife',
+ },
+ plugins: [
+ replace({ __DNT__: !!process.env.ENABLE_DNT }),
+ resolve(),
+ buble(),
+ terser({ compress: { evaluate: false } }),
+ ],
+};
diff --git a/tracker/index.js b/tracker/index.js
index ff7f0995..6d6886fb 100644
--- a/tracker/index.js
+++ b/tracker/index.js
@@ -3,6 +3,13 @@ import 'unfetch/polyfill';
import { doNotTrack, hook, post } from '../lib/web';
import { removeTrailingSlash } from '../lib/url';
+function log(isDebug, messageFn) {
+ if (isDebug) {
+ return;
+ }
+ console.log(messageFn());
+}
+
(window => {
const {
screen: { width, height },
@@ -20,6 +27,7 @@ import { removeTrailingSlash } from '../lib/url';
const website = script.getAttribute('data-website-id');
const hostUrl = script.getAttribute('data-host-url');
const skipAuto = script.getAttribute('data-skip-auto');
+ const isDebug = script.getAttribute('data-debug');
const root = hostUrl
? removeTrailingSlash(hostUrl)
: new URL(script.src).href.split('/').slice(0, -1).join('/');
@@ -72,45 +80,54 @@ import { removeTrailingSlash } from '../lib/url';
});
};
- if (!window.umami) {
- window.umami = event_value => window.umami.event('custom', event_value, currentUrl);
- window.umami.collect = (type, params, id) => {
- if (!id) {
- id = website;
- }
- const payload = {
- website: id,
- hostname,
- screen,
- language,
- };
- if (params) {
- Object.keys(params).forEach(key => {
- payload[key] = params[key];
- });
- }
+ const scheduledCalls = window.umami.calls;
+ window.umami = {};
+ window.umami.collect = (type, params, id) => {
+ if (!id) {
+ id = website;
+ }
+ const payload = {
+ website: id,
+ hostname,
+ screen,
+ language,
+ };
- return post(`${root}/api/collect`, {
- type,
- payload,
+ if (params) {
+ Object.keys(params).forEach(key => {
+ payload[key] = params[key];
});
- };
- window.umami.pageView = (url = currentUrl, referrer = currentRef) => window.umami.collect('pageview', {
- url,
- referrer,
+ }
+
+ log(isDebug, () => `Umami, collect ${type} with payload: ${JSON.stringify(payload, null, 2)}`);
+ return post(`${root}/api/collect`, {
+ type,
+ payload,
});
- window.umami.event = (event_type, event_value, url = currentUrl) => window.umami.collect('event', {
- url,
- event_type,
- event_value,
- });
- window.umami.registerAutoEvents = () => {
- history.pushState = hook(history, 'pushState', handlePush);
- history.replaceState = hook(history, 'replaceState', handlePush);
- return pageViewWithAutoEvents(currentUrl, currentRef);
- };
- }
+ };
+ window.umami.pageView = (url = currentUrl, referrer = currentRef) => window.umami.collect('pageview', {
+ url,
+ referrer,
+ });
+ window.umami.event = (event_type, event_value, url = currentUrl) => window.umami.collect('event', {
+ url,
+ event_type,
+ event_value,
+ });
+ window.umami.registerAutoEvents = () => {
+ history.pushState = hook(history, 'pushState', handlePush);
+ history.replaceState = hook(history, 'replaceState', handlePush);
+ return pageViewWithAutoEvents(currentUrl, currentRef);
+ };
+
+ log(isDebug, () => 'Umami, calling scheduled invocations');
+ log(isDebug, () => scheduledCalls);
+
+ scheduledCalls.forEach(([fnName, ...params]) => {
+ log(isDebug, () => `Umami, calling ${fnName} fn with params: ${JSON.stringify(params)}`);
+ window.umami[fnName].apply(window.umami, params);
+ });
/* Start */
if (!skipAuto) {
diff --git a/tracker/snippet.js b/tracker/snippet.js
new file mode 100644
index 00000000..ffb89423
--- /dev/null
+++ b/tracker/snippet.js
@@ -0,0 +1,42 @@
+(window => {
+ const umami = window.umami = window.umami || [];
+ if (!umami.registerAutoEvents) {
+ if (umami.invoked) {
+ window.console && console.error && console.error('Umami snippet included twice.');
+ } else {
+ umami.invoked = true;
+ umami.calls = [];
+ umami.methods = ['registerAutoEvents', 'event', 'pageView'];
+ umami.factory = t => {
+ return function() {
+ const e = Array.prototype.slice.call(arguments);
+ e.unshift(t);
+ umami.calls.push(e);
+ return umami;
+ };
+ };
+ for (let t = 0; t < umami.methods.length; t++) {
+ let e = umami.methods[t];
+ umami[e] = umami.factory(e);
+ }
+ umami.load = function(umamiScript, umamiUUID, skipAuto, isDebug) {
+ const scriptElement = document.createElement('script');
+ scriptElement.type = 'text/javascript';
+ scriptElement.defer = true;
+ scriptElement.async = true;
+ scriptElement.setAttribute('data-website-id', umamiUUID);
+ if (skipAuto) {
+ scriptElement.setAttribute('data-skip-auto', 'true');
+ }
+ if (isDebug) {
+ scriptElement.setAttribute('data-debug', 'true');
+ }
+ scriptElement.src = umamiScript;
+ const otherScript = document.getElementsByTagName('script')[0];
+ otherScript.parentNode.insertBefore(scriptElement, otherScript);
+ };
+
+ umami.load('${document.location.origin}/umami.js', '${values.website_uuid}', false, false);
+ }
+ }
+})(window);
\ No newline at end of file
From 241905c5fed9a250f3be4dbb90817794537ff113 Mon Sep 17 00:00:00 2001
From: Bartosz Hernas
Date: Tue, 15 Sep 2020 14:10:01 +0200
Subject: [PATCH 6/8] Fix uuid passing
---
tracker/index.js | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/tracker/index.js b/tracker/index.js
index 6d6886fb..8287b145 100644
--- a/tracker/index.js
+++ b/tracker/index.js
@@ -83,12 +83,9 @@ function log(isDebug, messageFn) {
const scheduledCalls = window.umami.calls;
window.umami = {};
- window.umami.collect = (type, params, id) => {
- if (!id) {
- id = website;
- }
+ window.umami.collect = (type, params, uuid) => {
const payload = {
- website: id,
+ website: uuid,
hostname,
screen,
language,
@@ -106,15 +103,15 @@ function log(isDebug, messageFn) {
payload,
});
};
- window.umami.pageView = (url = currentUrl, referrer = currentRef) => window.umami.collect('pageview', {
+ window.umami.pageView = (url = currentUrl, referrer = currentRef, uuid = website) => window.umami.collect('pageview', {
url,
referrer,
- });
- window.umami.event = (event_type, event_value, url = currentUrl) => window.umami.collect('event', {
+ }, uuid);
+ window.umami.event = (event_type, event_value, url = currentUrl, uuid = website) => window.umami.collect('event', {
url,
event_type,
event_value,
- });
+ }, uuid);
window.umami.registerAutoEvents = () => {
history.pushState = hook(history, 'pushState', handlePush);
history.replaceState = hook(history, 'replaceState', handlePush);
@@ -122,8 +119,6 @@ function log(isDebug, messageFn) {
};
log(isDebug, () => 'Umami, calling scheduled invocations');
- log(isDebug, () => scheduledCalls);
-
scheduledCalls.forEach(([fnName, ...params]) => {
log(isDebug, () => `Umami, calling ${fnName} fn with params: ${JSON.stringify(params)}`);
window.umami[fnName].apply(window.umami, params);
From 5318accc6f6eea5fff8f47f96bde5ea56f4d156b Mon Sep 17 00:00:00 2001
From: Bartosz Hernas
Date: Wed, 16 Sep 2020 12:07:22 +0200
Subject: [PATCH 7/8] Fixed comments
---
components/forms/TrackingCodeForm.js | 3 +-
tracker/index.js | 76 +++++++++++++---------------
tracker/snippet.js | 7 +--
3 files changed, 38 insertions(+), 48 deletions(-)
diff --git a/components/forms/TrackingCodeForm.js b/components/forms/TrackingCodeForm.js
index 36dda30e..9e8e81e2 100644
--- a/components/forms/TrackingCodeForm.js
+++ b/components/forms/TrackingCodeForm.js
@@ -24,8 +24,7 @@ export default function TrackingCodeForm({ values, onClose }) {
rows={3}
cols={60}
spellCheck={false}
- defaultValue={`!function(){"use strict";!function(e){var t=e.umami=e.umami||[];if(!t.registerAutoEvents)if(t.invoked)e.console&&console.error&&console.error("Umami snippet included twice.");else{t.invoked=!0,t.calls=[],t.methods=["registerAutoEvents","event","pageView"],t.factory=function(e){return function(){var r=Array.prototype.slice.call(arguments);return r.unshift(e),t.calls.push(r),t}};for(var r=0;r
diff --git a/tracker/index.js b/tracker/index.js
index 8287b145..2cbc3ce2 100644
--- a/tracker/index.js
+++ b/tracker/index.js
@@ -3,13 +3,6 @@ import 'unfetch/polyfill';
import { doNotTrack, hook, post } from '../lib/web';
import { removeTrailingSlash } from '../lib/url';
-function log(isDebug, messageFn) {
- if (isDebug) {
- return;
- }
- console.log(messageFn());
-}
-
(window => {
const {
screen: { width, height },
@@ -27,7 +20,6 @@ function log(isDebug, messageFn) {
const website = script.getAttribute('data-website-id');
const hostUrl = script.getAttribute('data-host-url');
const skipAuto = script.getAttribute('data-skip-auto');
- const isDebug = script.getAttribute('data-debug');
const root = hostUrl
? removeTrailingSlash(hostUrl)
: new URL(script.src).href.split('/').slice(0, -1).join('/');
@@ -37,26 +29,6 @@ function log(isDebug, messageFn) {
let currentUrl = `${pathname}${search}`;
let currentRef = document.referrer;
- /* Collect metrics */
- const pageViewWithAutoEvents = (url, referrer) => window.umami.pageView(url, referrer).then(() => setTimeout(loadEvents, 300));
-
- /* Handle history */
-
- const handlePush = (state, title, url) => {
- removeEvents();
- currentRef = currentUrl;
- const newUrl = url.toString();
-
- if (newUrl.substring(0, 4) === 'http') {
- const { pathname, search } = new URL(newUrl);
- currentUrl = `${pathname}${search}`;
- } else {
- currentUrl = newUrl;
- }
-
- pageViewWithAutoEvents(currentUrl, currentRef);
- };
-
/* Handle events */
const removeEvents = () => {
@@ -71,7 +43,7 @@ function log(isDebug, messageFn) {
element.className.split(' ').forEach(className => {
if (/^umami--([a-z]+)--([a-z0-9_]+[a-z0-9-_]+)$/.test(className)) {
const [, type, value] = className.split('--');
- const listener = () => window.umami.event(type, value);
+ const listener = () => event(type, value);
listeners.push([element, type, listener]);
element.addEventListener(type, listener, true);
@@ -79,11 +51,7 @@ function log(isDebug, messageFn) {
});
});
};
-
-
- const scheduledCalls = window.umami.calls;
- window.umami = {};
- window.umami.collect = (type, params, uuid) => {
+ const collect = (type, params, uuid) => {
const payload = {
website: uuid,
hostname,
@@ -97,35 +65,61 @@ function log(isDebug, messageFn) {
});
}
- log(isDebug, () => `Umami, collect ${type} with payload: ${JSON.stringify(payload, null, 2)}`);
return post(`${root}/api/collect`, {
type,
payload,
});
};
- window.umami.pageView = (url = currentUrl, referrer = currentRef, uuid = website) => window.umami.collect('pageview', {
+ const pageView = (url = currentUrl, referrer = currentRef, uuid = website) => collect('pageview', {
url,
referrer,
}, uuid);
- window.umami.event = (event_type, event_value, url = currentUrl, uuid = website) => window.umami.collect('event', {
+
+ /* Collect metrics */
+ const pageViewWithAutoEvents = (url, referrer) => pageView(url, referrer).then(() => setTimeout(loadEvents, 300));
+
+ /* Handle history */
+ const handlePush = (state, title, url) => {
+ removeEvents();
+ currentRef = currentUrl;
+ const newUrl = url.toString();
+
+ if (newUrl.substring(0, 4) === 'http') {
+ const { pathname, search } = new URL(newUrl);
+ currentUrl = `${pathname}${search}`;
+ } else {
+ currentUrl = newUrl;
+ }
+
+ pageViewWithAutoEvents(currentUrl, currentRef);
+ };
+
+ const event = (event_type, event_value, url = currentUrl, uuid = website) => collect('event', {
url,
event_type,
event_value,
}, uuid);
- window.umami.registerAutoEvents = () => {
+
+ const registerAutoEvents = () => {
history.pushState = hook(history, 'pushState', handlePush);
history.replaceState = hook(history, 'replaceState', handlePush);
return pageViewWithAutoEvents(currentUrl, currentRef);
};
- log(isDebug, () => 'Umami, calling scheduled invocations');
+
+ const scheduledCalls = window.umami.calls;
+ window.umami = {
+ collect,
+ pageView,
+ event,
+ registerAutoEvents
+ };
scheduledCalls.forEach(([fnName, ...params]) => {
- log(isDebug, () => `Umami, calling ${fnName} fn with params: ${JSON.stringify(params)}`);
window.umami[fnName].apply(window.umami, params);
});
/* Start */
if (!skipAuto) {
- window.umami.registerAutoEvents().catch(e => console.error(e));
+ registerAutoEvents().catch(e => console.error(e));
}
})(window);
diff --git a/tracker/snippet.js b/tracker/snippet.js
index ffb89423..89a3a865 100644
--- a/tracker/snippet.js
+++ b/tracker/snippet.js
@@ -19,7 +19,7 @@
let e = umami.methods[t];
umami[e] = umami.factory(e);
}
- umami.load = function(umamiScript, umamiUUID, skipAuto, isDebug) {
+ umami.load = function(umamiScript, umamiUUID, skipAuto) {
const scriptElement = document.createElement('script');
scriptElement.type = 'text/javascript';
scriptElement.defer = true;
@@ -28,15 +28,12 @@
if (skipAuto) {
scriptElement.setAttribute('data-skip-auto', 'true');
}
- if (isDebug) {
- scriptElement.setAttribute('data-debug', 'true');
- }
scriptElement.src = umamiScript;
const otherScript = document.getElementsByTagName('script')[0];
otherScript.parentNode.insertBefore(scriptElement, otherScript);
};
- umami.load('${document.location.origin}/umami.js', '${values.website_uuid}', false, false);
+ umami.load('${document.location.origin}/umami.js', '${values.website_uuid}', false);
}
}
})(window);
\ No newline at end of file
From 09235ddacf737c08357b89c610f37de034e4d4a9 Mon Sep 17 00:00:00 2001
From: Bartosz Hernas
Date: Fri, 18 Sep 2020 11:33:17 +0200
Subject: [PATCH 8/8] Reverted tracker to old behaviour while still keeping
more advanced use case
---
components/forms/TrackingCodeForm.js | 8 +++-----
tracker/index.js | 23 +++++++++++++----------
tracker/snippet.js | 8 ++++++--
3 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/components/forms/TrackingCodeForm.js b/components/forms/TrackingCodeForm.js
index 9e8e81e2..61df1275 100644
--- a/components/forms/TrackingCodeForm.js
+++ b/components/forms/TrackingCodeForm.js
@@ -17,21 +17,19 @@ export default function TrackingCodeForm({ values, onClose }) {
/>
- {/* Run `npm run build-snippet, and copy paste here the content of public/snippet.js */}
- {/* TODO: use webpack importing function to import the content of the file here ? */}
-
+
diff --git a/tracker/index.js b/tracker/index.js
index 2cbc3ce2..28b8dfca 100644
--- a/tracker/index.js
+++ b/tracker/index.js
@@ -43,7 +43,7 @@ import { removeTrailingSlash } from '../lib/url';
element.className.split(' ').forEach(className => {
if (/^umami--([a-z]+)--([a-z0-9_]+[a-z0-9-_]+)$/.test(className)) {
const [, type, value] = className.split('--');
- const listener = () => event(type, value);
+ const listener = () => collectEvent(type, value);
listeners.push([element, type, listener]);
element.addEventListener(type, listener, true);
@@ -94,7 +94,7 @@ import { removeTrailingSlash } from '../lib/url';
pageViewWithAutoEvents(currentUrl, currentRef);
};
- const event = (event_type, event_value, url = currentUrl, uuid = website) => collect('event', {
+ const collectEvent = (event_type, event_value, url = currentUrl, uuid = website) => collect('event', {
url,
event_type,
event_value,
@@ -107,17 +107,20 @@ import { removeTrailingSlash } from '../lib/url';
};
+ const umamiFunctions = { collect, pageView, collectEvent, registerAutoEvents };
const scheduledCalls = window.umami.calls;
- window.umami = {
- collect,
- pageView,
- event,
- registerAutoEvents
- };
- scheduledCalls.forEach(([fnName, ...params]) => {
- window.umami[fnName].apply(window.umami, params);
+
+ window.umami = event_value => collect('event', { event_type: 'custom', event_value });
+ Object.keys(umamiFunctions).forEach((key) => {
+ window.umami[key] = umamiFunctions[key];
});
+ if (scheduledCalls) {
+ scheduledCalls.forEach(([fnName, ...params]) => {
+ window.umami[fnName].apply(window.umami, params);
+ });
+ }
+
/* Start */
if (!skipAuto) {
registerAutoEvents().catch(e => console.error(e));
diff --git a/tracker/snippet.js b/tracker/snippet.js
index 89a3a865..df1a8eb5 100644
--- a/tracker/snippet.js
+++ b/tracker/snippet.js
@@ -33,7 +33,11 @@
otherScript.parentNode.insertBefore(scriptElement, otherScript);
};
- umami.load('${document.location.origin}/umami.js', '${values.website_uuid}', false);
+ umami.load('[HOST]/umami.js', '[UMAMI_UUID]', false);
}
}
-})(window);
\ No newline at end of file
+})(window);
+// This snippet is for more advanced use case of Umami. If you want to track custom events,
+// and not worry about having blocking script in the header,
+// use this snippet (compiled version available in /public/snippet.js).
+// Just remember to replace [HOST] and [UMAMI_UUID] when pasting it.
\ No newline at end of file