add async tracking snippet with command queue exampel

This commit is contained in:
Danny van Kooten 2016-11-25 16:03:47 +01:00
parent 87e7020ce2
commit 31130b8fe4
6 changed files with 71 additions and 26 deletions

0
LICENSE Normal file
View File

View File

@ -4,3 +4,24 @@ Ana. Open Source Web Analytics.
This is nowhere near being usable, let alone stable. Treat as a proof of concept. This is nowhere near being usable, let alone stable. Treat as a proof of concept.
![Screenshot of the Ana dashboard](https://github.com/dannyvankooten/ana/raw/master/assets/img/screenshot.png?2) ![Screenshot of the Ana dashboard](https://github.com/dannyvankooten/ana/raw/master/assets/img/screenshot.png?2)
## Usage
```html
<!-- Ana tracker -->
<script>
(function(d, w, u, o){
w[o]=w[o]||function(){
(w[o].q=w[o].q||[]).push(arguments)
};
a=d.createElement('script'),
m=d.getElementsByTagName('script')[0];
a.async=1;
a.src=u;
m.parentNode.insertBefore(a,m)
})(document, window, '//ana.dev/tracker.js', 'ana');
ana('setTrackerUrl', '//ana.dev/collect');
ana('trackPageview');
</script>
<!-- / Ana tracker -->
```

View File

@ -5,7 +5,6 @@ This is a general draft document for thoughts and todo's. This has no structure.
### What's cooking? ### What's cooking?
- Async tracking snippet.
- Add license file. - Add license file.
- Get DB creds from env. - Get DB creds from env.
- JS client for consuming API endpoints. - JS client for consuming API endpoints.

1
ana.go
View File

@ -39,6 +39,7 @@ func main() {
r.Handle("/api/browsers", api.Authorize(api.GetBrowsersHandler)).Methods("GET") r.Handle("/api/browsers", api.Authorize(api.GetBrowsersHandler)).Methods("GET")
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static/")))) r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static/"))))
r.Path("/tracker.js").Handler(http.FileServer(http.Dir("./static/js/")))
r.Handle("/", http.FileServer(http.Dir("./views/"))) r.Handle("/", http.FileServer(http.Dir("./views/")))
http.ListenAndServe(":8080", handlers.LoggingHandler(os.Stdout, r)) http.ListenAndServe(":8080", handlers.LoggingHandler(os.Stdout, r))

View File

@ -1,7 +1,14 @@
'use strict'; 'use strict';
(function() { var queue = window.ana.q || [];
function jsonToQueryString(json) { var trackerUrl = '//ana.dev/collect';
var commands = {
"trackPageview": trackPageview,
"setTrackerUrl": setTrackerUrl,
};
// convert object to query string
function stringifyObject(json) {
var keys = Object.keys(json); var keys = Object.keys(json);
// omit empty // omit empty
@ -14,14 +21,17 @@
return encodeURIComponent(k) + '=' + return encodeURIComponent(k) + '=' +
encodeURIComponent(json[k]); encodeURIComponent(json[k]);
}).join('&'); }).join('&');
}
function setTrackerUrl(v) {
trackerUrl = v;
}
function trackPageview() {
if( navigator.DonotTrack == 1 ) {
return;
} }
// abort hit if Do Not Track is enabled.
// if( navigator.DonotTrack == 1 ) {
// return;
// }
var i = document.createElement('img');
var d = { var d = {
l: navigator.language, l: navigator.language,
p: location.pathname + location.search, p: location.pathname + location.search,
@ -30,8 +40,17 @@
r: document.referrer r: document.referrer
}; };
var i = document.createElement('img');
i.src = 'http://localhost:8080/collect' + jsonToQueryString(d); i.src = trackerUrl + stringifyObject(d);
document.body.appendChild(i); document.body.appendChild(i);
})(); }
// override global ana object
window.ana = function() {
var args = [].slice.call(arguments);
var c = args.shift();
commands[c].apply(this, args);
};
// process existing queue
queue.map((i) => ana.apply(this, i));

View File

@ -11,7 +11,7 @@ const rename = require('gulp-rename');
const gutil = require('gulp-util'); const gutil = require('gulp-util');
const sass = require('gulp-sass'); const sass = require('gulp-sass');
gulp.task('default', [ 'browserify', 'sass' ] ); gulp.task('default', [ 'browserify', 'sass', 'tracker' ] );
gulp.task('browserify', function () { gulp.task('browserify', function () {
return browserify({ return browserify({
@ -29,6 +29,11 @@ gulp.task('browserify', function () {
.pipe(gulp.dest('./static/js/')) .pipe(gulp.dest('./static/js/'))
}); });
gulp.task('tracker', function() {
return gulp.src('./assets/js/tracker.js')
.pipe(gulp.dest('./static/js'))
});
gulp.task('sass', function () { gulp.task('sass', function () {
var files = './assets/sass/[^_]*.scss'; var files = './assets/sass/[^_]*.scss';
return gulp.src(files) return gulp.src(files)
@ -39,6 +44,6 @@ gulp.task('sass', function () {
}); });
gulp.task('watch', ['default'], function() { gulp.task('watch', ['default'], function() {
gulp.watch(['./assets/js/**/*.js'], ['browserify'] ); gulp.watch(['./assets/js/**/*.js'], ['browserify', 'tracker'] );
gulp.watch(['./assets/sass/**/*.scss'], ['sass'] ); gulp.watch(['./assets/sass/**/*.scss'], ['sass'] );
}); });