-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathindex.html
191 lines (166 loc) · 16.7 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Event-layer.js Demo</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-material-design/4.0.2/bootstrap-material-design.css"/>
<style>
body {
padding: 50px;
}
.anchor {
display: none;
}
.indent {
margin-left: 75px;
}
pre {
background-color: #e9e9e9;
padding: 10px 20px;
font-family: monospace;
}
h2 {
margin-top: 50px;
margin-bottom: 15px;
}
p {
line-height: 1.5;
}
article {
max-width: 800px;
margin: 0 auto;
}
</style>
</head>
<body>
<article class="markdown-body entry-content" itemprop="text">
<!--<h1>-->
<!--<a id="user-content-event-layer" class="anchor" href="#event-layer" aria-hidden="true">-->
<!--<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>-->
<!--</a>-->
<!--Event Layer-->
<!--</h1>-->
<img src="event-layer-logo.png" style="height:110px;margin: 0 auto;display: block;margin-bottom: 50px;" alt=""/>
<hr/>
<p style="margin-top: 50px;">A very very simple abstraction layer for analytics code. Write your events once, then send them where ever you want.</p>
<a href="#demo">Scroll Down for a Demo</a>
<h2><a id="user-content-what-is-it" class="anchor" href="#what-is-it" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>What is it?</h2>
<p><strong>“Event Layer”</strong> is an extensible abstraction layer for working with common third-party Analytics libraries.</p>
<p>Since more or less all analytics libraries work the same way (allowing you to identify and describe users, and track the events which they perform),
<strong>“Event Layer”</strong> creates an abstraction layer and a set of adapters that allow you to write generic Analytics Tracking code once, and update your
configuration later to send your data anywhere you need.</p>
<h2><a id="user-content-how-does-it-work" class="anchor" href="#how-does-it-work" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>How does it work?</h2>
<ol>
<li>Install your third-party analytics libraries in your application or website (you don't need to do anything special)</li>
<li>Install <code>event-layer.js</code> in your website or app.</li>
<li>Instantiate a new instance of <strong>EventLayer:</strong> (e.g. <code>var Analytics = new EventLayer();</code>).</li>
<li>Instead of filling your app or website with service-specific tracking code, write generic code using the <strong>“Event Layer” Javascript API</strong> (described below).</li>
<li><strong>“Event Layer”</strong> will detect the third-party Analytics services you have installed on your website or app, and use it's own, community-maintained adapters to propagate your events, in an identical format, to each third-party service, using the latest version(s) of their APIs.</li>
<li><strong>(Optional):</strong> You can extend <strong>“Event Layer”</strong> by writing your own custom adapters for third-party services not yet supported. Each adapter only requires about 12 lines of Javascript, and the community is available to help you ship your first PR to <strong>“Event Layer”</strong>.</li>
</ol>
<h2><a id="user-content-instantiating-a-new-instance-of-eventlayer" class="anchor" href="#instantiating-a-new-instance-of-eventlayer" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Instantiating a new instance of EventLayer</h2>
<p>We realize that not everyone wants to litter their code with calls to a global named <strong>“Event Layer”</strong>. So you'll probably want to start off by instantiating a new instance of <strong>“Event Layer”</strong>.</p>
<pre><code>var Analytics = new EventLayer();
</code></pre>
<p>You can name it whatever you like, but the examples given below will need to be modified appropriately.</p>
<h2><a id="user-content-eventlayeridentifyuserid-userproperties" class="anchor" href="#eventlayeridentifyuserid-userproperties" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>EventLayer.identify(userId, userProperties)</h2>
<p>This method allows you to identify the current visitor, and (optionally) describe the user.</p>
<p><em>Only identify the user, do not describe any user properties:</em></p>
<pre><code>Analytics.identify('<unique-user-id>');
</code></pre>
<p><em>Identify the user and describe user properties:</em></p>
<pre><code>Analytics.identify('<unique-user-id>', {
name: 'John Doe',
subscribedToNewsletter: false
});
</code></pre>
<p>This is similar to the <code>Identify</code> method found in Mixpanel, Heap, and Analytics.js.</p>
<h2><a id="user-content-eventlayertrackeventname-eventproperties" class="anchor" href="#eventlayertrackeventname-eventproperties" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>EventLayer.track(eventName, eventProperties)</h2>
<p>This method allows you to identify the current visitor, and (optionally) describe the user.</p>
<p><em>Track a simple event, with no event properties:</em></p>
<pre><code>Analytics.track('click_signup_button');
</code></pre>
<p><em>Track a more complex event, with event properties:</em></p>
<pre><code>Analytics.track('purchase', {
amount: 32.00,
itemCount: 4,
shippingSpeed: 'next-day'
});
</code></pre>
<p>This is similar to the <code>Track</code> method found in Mixpanel, Heap, and Analytics.js.</p>
<h2><a id="user-content-writing-an-adapter" class="anchor" href="#writing-an-adapter" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Writing an Adapter</h2>
<p>Below is an example of a blank adapter.</p>
<pre><code>'blank-adapter-template': { // Do not modify this template
enabled: false, // Change to true once you're completed testing
test: function () {},
identify: function (userId, userProperties) {},
track: function (eventName, eventProperties) {}
}
</code></pre>
<div class="indent">
<p>It has three main components:</p>
<h3><a id="user-content-1-test" class="anchor" href="#1-test" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>1. Test:</h3>
<p>This function, once evaluated, should provide an answer to the question “has a specific third-party analytics library been installed on this page? Is it active? Should we try to send events to this service?”</p>
<p>This can be as simple as sniffing the window object for a global variables, and a commonly-used (and not likely to disappear) method or property:</p>
<pre><code>test: function () {
return window.ga && window.ga.loaded;
}
</code></pre>
<p>(A simple example taken from the Google Analytics adapter)</p>
<h3><a id="user-content-2-identify" class="anchor" href="#2-identify" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>2. identify:</h3>
<p>This function takes data from our generic <code>identify</code> method, and passes it along to a third-party library, via an adapter.</p>
<p>This should contain a minimal number of integrity checks and transforms, as well as a lightweight wrapper for the library's identify and/or describe functionality.</p>
<pre><code>identify: function (userId, userProperties) {
// Send the identify call to Mixpanel's JS library
if (window.mixpanel && userId)
mixpanel.identify(userId);
// Set people properties on our identified user
if (window.mixpanel && userProperties)
mixpanel.people.set(userProperties);
}
</code></pre>
<p>(A simple example taken from the Mixpanel adapter)</p>
<h3><a id="user-content-3-track" class="anchor" href="#3-track" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>3. track:</h3>
<p>This function takes data from our generic <code>track</code> method, and passes it along to a third-party library, via an adapter.</p>
<p>This should contain a minimal number of integrity checks and transforms, as well as a lightweight wrapper for the library's event tracking functionality.</p>
<pre><code>track: function (eventName, eventProperties) {
// Send the tracked event to Heap's JS library
if (window.heap && eventName)
heap.track(eventName, eventProperties);
}
</code></pre>
<p>(A simple example taken from the Heap Analytics adapter)</p>
</div>
<h2><a id="user-content-pull-requests" class="anchor" href="#pull-requests" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Pull Requests</h2>
<p><strong>Yes, Please & Thank you!</strong></p>
<p>To keep things organized, please open an issue for discussion before putting too much work into a pull request. I would feel really bad if you put a lot of work into something, only for it to not make sense to include it or merge the Pull Request.</p>
<p>Also, to help keep things organized, try to submit individual pull requests for each issue, and keep the scope of each issue relatively small.</p>
<p>For example, if you wanted to add a couple of new adapters, split them into multiple pull requests so we can review them individually.</p>
<h2><a id="user-content-issues" class="anchor" href="#issues" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Issues</h2>
<p>Something feel broken? Open an issue!
Something you feel is missing? Open an issue (Although we may not be able to get to everything, pull requests are most welcome!)</p>
<h2><a id="user-content-thanks" class="anchor" href="#thanks" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thanks!</h2>
<hr style="margin-top: 100px" />
<h2 id="demo" style="margin-bottom: 15px">Demo:</h2>
<p>For this demo, we include Google Analytics and the <strong>event-layer.js</strong> library, instantiate event-layer as <strong>`Analytics`</strong>, and track an event called <strong>`button_clicked`</strong> when the button is clicked. You can inspect this page to see how the demo works.</p>
<button onclick="Analytics.track('button_clicked');alert('Event `button_clicked` tracked (you can inspect it in the network tab of your console)');">Click me</button>
<p style="margin-bottom: 200px;"> </p>
</article>
<script src="event-layer.js"></script>
<script>
var Analytics = new EventLayer();
window.__debug = true;
</script>
<!-- Google Analytics tracking code -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-36579124-1', 'auto');
//ga('send', 'pageview');
Analytics.page();
</script>
<!-- End Google Analytics tracking code -->
</body>
</html>