Skip to content

Commit

Permalink
Merge pull request umami-software#178 from mikecao/dev
Browse files Browse the repository at this point in the history
v0.39.0 - Tracker updates
  • Loading branch information
mikecao authored Sep 18, 2020
2 parents f98f66a + b198896 commit 238251a
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 52 deletions.
2 changes: 1 addition & 1 deletion components/forms/TrackingCodeForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useRef } from 'react';
import { FormattedMessage } from 'react-intl';
import Button from 'components/common/Button';
import FormLayout, { FormButtons, FormRow } from 'components/layout/FormLayout';
import CopyButton from '../common/CopyButton';
import CopyButton from 'components/common/CopyButton';

export default function TrackingCodeForm({ values, onClose }) {
const ref = useRef();
Expand Down
1 change: 1 addition & 0 deletions lib/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const useSession = use(async (req, res, next) => {
try {
session = await getSession(req);
} catch (e) {
console.error(e);
return serverError(res, e.message);
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "umami",
"version": "0.38.0",
"version": "0.39.0",
"description": "A simple, fast, website analytics alternative to Google Analytics. ",
"author": "Mike Cao <[email protected]>",
"license": "MIT",
Expand Down
12 changes: 11 additions & 1 deletion pages/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ export default function Test() {
return <h1>No id query specified.</h1>;
}

function handleClick() {
window.umami('Custom event');
window.umami.pageView('/fake', 'https://www.google.com');
window.umami.pageEvent('pageEvent', 'custom-type');
}

return (
<>
<Head>
Expand All @@ -20,7 +26,7 @@ export default function Test() {
</Head>
<Layout>
<p>
Here you can test if your umami installation works. Open the network tab in your browser's
Here you can test if your umami installation works. Open the network tab in your browser
developer console and watch for requests to the url <b>collect</b>. The links below should
trigger page views. Clicking on the button should trigger an event.
</p>
Expand All @@ -40,6 +46,10 @@ export default function Test() {
>
Button
</button>
<h2>Manual trigger</h2>
<button id="manual-button" type="button" onClick={handleClick}>
Button
</button>
</Layout>
</>
);
Expand Down
8 changes: 1 addition & 7 deletions rollup.tracker.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
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';

Expand All @@ -10,10 +9,5 @@ export default {
file: 'public/umami.js',
format: 'iife',
},
plugins: [
replace({ __DNT__: !!process.env.ENABLE_DNT }),
resolve(),
buble(),
terser({ compress: { evaluate: false } }),
],
plugins: [resolve(), buble(), terser({ compress: { evaluate: false } })],
};
126 changes: 84 additions & 42 deletions tracker/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import 'promise-polyfill/src/polyfill';
import 'unfetch/polyfill';
import { post, hook, doNotTrack } from '../lib/web';
import { doNotTrack, hook } from '../lib/web';
import { removeTrailingSlash } from '../lib/url';

(window => {
Expand All @@ -13,28 +11,42 @@ import { removeTrailingSlash } from '../lib/url';
} = window;

const script = document.querySelector('script[data-website-id]');
const attr = key => script && script.getAttribute(key);

// eslint-disable-next-line no-undef
if (!script || (__DNT__ && doNotTrack())) return;
const website = attr('data-website-id');
const hostUrl = attr('data-host-url');
const autoTrack = attr('data-auto-track') !== 'false';
const dnt = attr('data-do-not-track') === 'true';

if (!script || (dnt && doNotTrack())) return;

const website = script.getAttribute('data-website-id');
const hostUrl = script.getAttribute('data-host-url');
const root = hostUrl
? removeTrailingSlash(hostUrl)
: new URL(script.src).href.split('/').slice(0, -1).join('/');
const screen = `${width}x${height}`;
const listeners = [];

let currentUrl = `${pathname}${search}`;
let currentRef = document.referrer;

/* Collect metrics */

const collect = (type, params) => {
const post = (url, data, callback) => {
const req = new XMLHttpRequest();
req.open('POST', url, true);
req.setRequestHeader('Content-Type', 'application/json');

req.onreadystatechange = () => {
if (req.readyState === 4) {
callback && callback();
}
};

req.send(JSON.stringify(data));
};

const collect = (type, params, uuid) => {
const payload = {
url: currentUrl,
referrer: currentRef,
website,
website: uuid,
hostname,
screen,
language,
Expand All @@ -52,14 +64,55 @@ import { removeTrailingSlash } from '../lib/url';
});
};

const pageView = () => collect('pageview').then(() => setTimeout(loadEvents, 300));
const pageView = (url = currentUrl, referrer = currentRef, uuid = website) =>
collect(
'pageview',
{
url,
referrer,
},
uuid,
);

const pageEvent = (event_value, event_type = 'custom', url = currentUrl, uuid = website) =>
collect(
'event',
{
event_type,
event_value,
url,
},
uuid,
);

const pageEvent = (event_type, event_value) => collect('event', { event_type, event_value });
/* Handle events */

const loadEvents = () => {
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('--');
const listener = () => pageEvent(value, type);

listeners.push([element, type, listener]);
element.addEventListener(type, listener, true);
}
});
});
};

const removeEvents = () => {
listeners.forEach(([element, type, listener]) => {
element && element.removeEventListener(type, listener, true);
});
listeners.length = 0;
};

/* Handle history */
/* Handle history changes */

const handlePush = (state, title, url) => {
removeEvents();

currentRef = currentUrl;
const newUrl = url.toString();

Expand All @@ -70,40 +123,29 @@ import { removeTrailingSlash } from '../lib/url';
currentUrl = newUrl;
}

pageView();
};

history.pushState = hook(history, 'pushState', handlePush);
history.replaceState = hook(history, 'replaceState', handlePush);
pageView(currentUrl, currentRef);

/* Handle events */

const removeEvents = () => {
listeners.forEach(([element, type, listener]) => {
element && element.removeEventListener(type, listener, true);
});
listeners.length = 0;
setTimeout(loadEvents, 300);
};

const loadEvents = () => {
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('--');
const listener = () => pageEvent(type, value);
/* Global */

listeners.push([element, type, listener]);
element.addEventListener(type, listener, true);
}
});
});
};
if (!window.umami) {
const umami = event_value => pageEvent(event_value);
umami.pageView = pageView;
umami.pageEvent = pageEvent;

window.umami = umami;
}

/* Start */

pageView();
if (autoTrack) {
history.pushState = hook(history, 'pushState', handlePush);
history.replaceState = hook(history, 'replaceState', handlePush);

if (!window.umami) {
window.umami = event_value => collect('event', { event_type: 'custom', event_value });
pageView(currentUrl, currentRef);

loadEvents();
}
})(window);

0 comments on commit 238251a

Please sign in to comment.