Local Storage with LocalStore.js

Quick overview of Local Storage in Pokki

Local Storage is an HTML5 standardized way to store and access data on a local machine and it's fully supported in Pokki. It's like an improved version of cookies, and because cookies are not really available in Pokki (given Pokki apps do not run on domains), it's the only reliable method for storing data locally.

Pokki apps are sandboxed meaning only your Pokki can access your locally stored data. That said, locally stored data ends up sitting on a user's hard drive and is not protected. If you want to store sensitive data locally you should be sure.

Using LocalStore.js

LocalStore.js is a little wrapper we built to make dealing with localStorage as easy as possible.You can grab it from GitHub.

new LocalStore(str key, obj options)
Instantiates a new LocalStore object

// Instantiating a LocalStore object without options
var local = new LocalStore('local_key');
// Instantiating a LocalStore object explicitly with options (these are their default values)
var local  = new LocalStore('local_key', {
    defaultVal: null,
    scrambled: false

LocalStore.set(var data)
Stores data in LocalStore objects

// Examples of storing data
local.set({complex: 'stuff'});

Returns data stored in a LocalStore object

var data = local.get();

Removes data stored in a LocalStore object


Add LocalStore.js to your Pokki

To get started, add LocalStore.js to your Pokki and load it in your window and background page.

  <script href="js/lib/LocalStore.js"></script>

LocalStore in practice

First run example

From the window, let's create our first LocalStore object:

var first_run = new LocalStore('first_run', {defaultVal: true});
if (first_run.get()) {
    console.log("It's the first time your Pokki has run!");

This is a simple and useful trick to execute logic the first time your Pokki runs.

Storing scrambled data

var user_session = new LocalStore('user_session', {scrambled: true});
if (valid_session(user_session.get())) {
    // this is a valid user...
else {
    // this user is invalid, lets remove the session

Accessing a LocalStore from both window and background_page

// window:
var local_window = new LocalStore('this_is_the_key');

var local_background = new LocalStore('this_is_the_key');

Both of these variables share the same LocalStore key this_is_the_key and thus access the same data. There's no reason they have different variable names other than for the explicit sake of this example.

Google Analytics

Why a custom Google Analytics implementation?

We had to create a custom implementation because Pokkies do not run from a domain and therefore do not support cookies (we use localStorage instead). With that, GAPokki.js is unofficial and based on an older version of Google Analytics. It may stop working in the future and data collected may be inaccurate so please use it with those warnings in mind. You can grab our implementation from GitHub.

Adding GAPokki.js to your Pokki

Using GAPokki.js is very easy and similar to how Google Analytics is used on the web. First, add GAPokki.js to your window with a script tag in the <head> . Second, set your GA Account ID and Domain with ga_pokki._setAccount and ga_pokki._setDomain. You can do this in a <script>  tag at the bottom of your window's body or from a Javascript file included after GAPokki.js.

Example window page:

<!doctype html>
    <script type="text/javascript" src="js/lib/GAPokki.js"></script>
    <script type="text/javascript">
        // GOOGLE ANALYTICS: Enter your real settings below


Default tracking

By default GAPokki.js tracks three User events (no pageviews are tracked):

  1. FirstRun
  2. IconClick
  3. AppHidden

These are tracked to ensure Google Analytics understands each visit. We consider every time a user clicks on a window to be a visit. When the user minimizes the window or clicks away from it their visit ends.

Custom tracking
ga_pokki._trackPageview(str path, str optional title)

Used to track your page views. Examples:

ga_pokki._trackPageview('/my-feed', 'My Feed');
ga_pokki._trackEvent(str category, str action, str optional label, int optional value)

Used to track custom events.

  1. category - The name you supply for the group of objects you want to track.
  2. action - A string that is uniquely paired with each category, and commonly used to define the type of user interaction for the web object
  3. label (optional) - An optional string to provide additional dimensions to the event data.
  4. value (optional) - An integer that you can use to provide numerical data about the user event.


ga_pokki._trackEvent('Click', 'Logo');
ga_pokki._trackEvent('Share', 'Twitter', '/post/41');
Custom Variables

Custom variables allow you to refine Google Analytics tracking. For example, you can segment your user base by account type - Trial Members, Subscribers, etc. - and view Google Analytics stats based on each one. For guidelines on how and when you would use custom variables, see the Google Analytics Custom Variables reference.

ga_pokki._setCustomVar(int index, str name, str value, int optional scope)

Make sure to set custom variables before you call ga_pokki._trackEvent or ga_pokki._trackPageView if you want the subsequent data points to be refined by your custom variables.

  1. index - The slot for the custom variable. This is a number whose value can range from 1-5, inclusive. A custom variable should be placed in one slot only and not be re-used across different slots.
  2. name - The name for the custom variable. It appears in the top-level Custom Variables report of Google Analytics.
  3. value - The value for the custom variable. The value appears in the table list of the UI for a selected variable name.
  4. scope (optional) - The scope defines the level of user engagement with your site. Possible values are1 (visitor-level), 2 (session-level), or 3 (page-level). When left undefined, the custom variable scope defaults to page-level interaction.


// User 1 logs in
ga_pokki._setCustomVar(1, 'AccountType', 'Trial', 2); // Logged in user is a trial user
ga_pokki._trackEvent('Share', 'Twitter', '/post/41'); // Now we can filter shares by trial users

// User 2 logs in
ga_pokki._setCustomVar(1, 'AccountType', 'Subscriber', 2); // Logged in user is a subscriber
ga_pokki._trackEvent('Share', 'Twitter', '/post/41'); // Now we can filter shares by account types

Analytics Event Extensions


We've extended the Google Event Tracker wrapper library for TimeTracker to work with the Pokki Google Analytics implementation. TimeTracker wraps the logic required for tracking elapsed time durations and segmenting elapsed time into a histogram. PokkiTimeTracker can be found inlib/GAPokkiTimeTracker.js from our github repo.

Simply instantiate a new PokkiTimeTracker, with an optional array of buckets for the histogram. The default time unit is in milliseconds.

var tracker1 = new PokkiTimeTracker(); // Uses the default bucket of [100, 500, 1500, 2500, 5000]
var tracker2 = new PokkiTimeTracker([1000, 2000, 4000, 8000, 16000]); // Use a custom bucket
_recordStartTime(int optional time)

Records the start time.

time (optional) - Start time as specified by the user

_recordEndTime(int optional time)

Records the end time. Start and stop must be called before calling _track to record the value.

time (optional) - Start time as specified by the user

_setHistogramBuckets(array buckets)

Sets the bucket for histogram generation in GA, or you can alternatively pass this value in when instantiating a tracker object.

buckets - An array of bucket values, in milliseconds unless you plan on tracking time with another unit (see _track)

_track(str optional event_name, str optional event_label, function optional time_func)

Tracks the event. Calculates the time and sends the information to ga_pokki._trackEvent

  1. event_name (optional) - Events will be reported under this name, defaults to 'TimeTracker'
  2. event_label (optional) - A label for applying the time tracker functionality across multiple dimensions and viewing those different dimensions in the report
  3. time_func (optional) - A function to transform the time difference into another unit of time since by default all time is tracked in milliseconds. As an example, if you wanted to track in minutes, you'd pass in a function to return the equivalent value in minutes. Also make sure your bucket values match the units of time.


//Default usage:
var tracker1 = new PokkiTimeTracker(); // Use the default buckets
// some time has elapsed
tracker1._track(); // Records the duration using default buckets in milliseconds with name 'TimeTracker'
A more specific use-case:
var tracker2 = new PokkiTimeTracker([15,30,60,120,180]); // Custom buckets, in minutes
// some time has elapsed
// Record duration in minutes, under the event name 'Playback' and label 'Streamed'
tracker2._track('Playback', 'Streamed', function(t) {
    var val = t / (1000 * 60); // convert to minutes
    return Math.ceil(val); // return rounded conversion