Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add option to use local storage instead of cookies #200

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Openpixel is a customizable JavaScript library for building tracking pixels. Ope

At Dockwa we built openpixel to solve our own problems of implementing a tracking service that our marinas could put on their website to track traffic and attribution to the reservations coming through our platform.

Openpixel handles the hard things about building a tracking library so you don't have to. It handles things like tracking unique users with cookies, tracking utm tags and persisting them to that users session, getting all of the information about the clients browser and device, and many other neat tricks for performant and accurate analytics.
Openpixel handles the hard things about building a tracking library so you don't have to. It handles things like tracking unique users with browser storage (cookies or local), tracking utm tags and persisting them to that users session, getting all of the information about the clients browser and device, and many other neat tricks for performant and accurate analytics.

Openpixel has two parts, the snippet (`snippet.html`), and the core (`openpixel.min.js`).

Expand All @@ -19,7 +19,7 @@ The openpixel snippet (found at `dist/snippet.html`) is the HTML code that will
The snippet handles things like making sure the core JavaScript will always be loaded async and is cache busted every 24 hours so you can update the core and have customers using the updates within the next day.

### Core
The openpixel core (found at `src/openpixel.min.js`) is the JavaScript code that that the snippet loads asynchronously onto the client's website. The core is what does all of the heavy lifting. The core handles settings cookies, collecting utms, and of course sending beacons and tracking pixels of data when events are called.
The openpixel core (found at `src/openpixel.min.js`) is the JavaScript code that that the snippet loads asynchronously onto the client's website. The core is what does all of the heavy lifting. The core handles settings variables to storage, collecting utms, and of course sending beacons and tracking pixels of data when events are called.

### Events
There are 2 automatic events, the `pageload` event which is sent as the main event when a page is loaded, you could consider it to be a "hit". The other event is `pageclose` and this is sent when the pages is closed or navigated away from. For example, to calculate how long a user viewed a page, you could calculate the difference between the timestamps on pageload and pageclose and those timestamps will be accurate because they are triggered on the client side when the events actually happened.
Expand Down Expand Up @@ -58,12 +58,12 @@ The `src/snippet.js` file is what is compiled into the `dist/snippet.html` file.
You may also need to build different versions of openpixel for different environments with custom options.
Environment variables can be used to configure the build:
```
OPIX_DESTINATION_FOLDER, OPIX_PIXEL_ENDPOINT, OPIX_JS_ENDPOINT, OPIX_VERSIONOPIX_PIXEL_FUNC_NAME, OPIX_VERSION, OPIX_HEADER_COMMENT
OPIX_DESTINATION_FOLDER, OPIX_PIXEL_ENDPOINT, OPIX_JS_ENDPOINT, OPIX_VERSIONOPIX_PIXEL_FUNC_NAME, OPIX_VERSION, OPIX_STORAGE_LIBRARY, OPIX_HEADER_COMMENT
```

You can install openpixel as an npm module `npm i -ED openpixel` and use it from your bash or js code.
```
OPIX_DESTINATION_FOLDER=/home/ubuntu/app/dist OPIX_PIXEL_ENDPOINT=http://localhost:8000/pixel.gif OPIX_JS_ENDPOINT=http://localhost:800/pixel_script.js OPIX_PIXEL_FUNC_NAME=track-function OPIX_VERSION=1 OPIX_HEADER_COMMENT="// My custom tracker\n" npx gulp --gulpfile ./node_modules/openpixel/gulpfile.js build
OPIX_DESTINATION_FOLDER=/home/ubuntu/app/dist OPIX_STORAGE_LIBRARY=cookies.js OPIX_PIXEL_ENDPOINT=http://localhost:8000/pixel.gif OPIX_JS_ENDPOINT=http://localhost:800/pixel_script.js OPIX_PIXEL_FUNC_NAME=track-function OPIX_VERSION=1 OPIX_HEADER_COMMENT="// My custom tracker\n" npx gulp --gulpfile ./node_modules/openpixel/gulpfile.js build
```

## Tracking Data
Expand Down
5 changes: 4 additions & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ var HEADER_COMMENT = process.env.OPIX_HEADER_COMMENT || '// Open Pixel v1.3.
// This is where the compiled snippet and openpixel.js files will be dropped
var DESTINATION_FOLDER = process.env.OPIX_DESTINATION_FOLDER || './dist';

// The library used to storage utm params and user id
var STORAGE_LIBRARY = process.env.OPIX_STORAGE_LIBRARY || 'cookie.js';

// The name of the global function and the cookie prefix that will be included in the snippet and is the client to fire off custom events
var PIXEL_FUNC_NAME = process.env.OPIX_PIXEL_FUNC_NAME || 'opix';

Expand Down Expand Up @@ -36,7 +39,7 @@ function openpixel() {
'./src/config.js',
'./src/helper.js',
'./src/browser.js',
'./src/cookie.js',
'./src/'+STORAGE_LIBRARY,
'./src/url.js',
'./src/pixel.js',
'./src/setup.js',
Expand Down
71 changes: 71 additions & 0 deletions src/localstorage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
class Cookie {
static prefix() {
return `__${pixelFuncName}_`;
}

static set(name, value, minutes) {
var now = new Date()
var ttl = minutes * 60 * 1000;
var item = {
value: value,
expiry: now.getTime() + ttl,
}
localStorage.setItem(`${this.prefix()}${name}`, JSON.stringify(item))
}

static get(name) {
var name = `${this.prefix()}${name}`;
var itemStr = localStorage.getItem(name)
if (!itemStr) {
return null
}
try {
var item = JSON.parse(itemStr)
} catch(e) { //not a json backward compatiblity
localStorage.removeItem(name)
return null
}
const now = new Date()
if (now.getTime() > item.expiry) {
localStorage.removeItem(name)
return null
}
return item.value
}

static delete(name) {
this.set(name,'',-100);
}

static exists(name) {
return Helper.isPresent(this.get(name));
}

static setUtms() {
var utmArray = ['utm_source', 'utm_medium', 'utm_term', 'utm_content', 'utm_campaign'];
var exists = false;
for (var i = 0, l = utmArray.length; i < l; i++) {
if (Helper.isPresent(Url.getParameterByName(utmArray[i]))) {
exists = true;
break;
}
}
if (exists) {
var val, save = {};
for (var i = 0, l = utmArray.length; i < l; i++) {
val = Url.getParameterByName(utmArray[i]);
if (Helper.isPresent(val)) {
save[utmArray[i]] = val;
}
}
this.set('utm', JSON.stringify(save));
}
}

static getUtm(name) {
if (this.exists('utm')) {
var utms = JSON.parse(this.get('utm'));
return name in utms ? utms[name] : '';
}
}
}