npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

footprints-tracker

v0.9.3

Published

A browser analytics tracking library

Downloads

14

Readme

CircleCI

Footprints Tracker

Footprints Tracker is a browser analytics tracking library. It is used to track user actions in the browser and send events to a server. It is backend agnostic and can be configured to work for most tracking use cases. It provides a retry queue for failed sends and a persistent context for identifying users and other state.

Installation

Add the following snippet to your page in the <head> element.

<script type='text/javascript'>
  !(function(w,d,s,o){var fp=w.Footprints=w.Footprints||{};fp.q=fp.q||[];if(fp.initialized||fp.invoked) return;fp.invoked=true;fp.pageTime=new Date();fp.options = o;var m=['user','pageView','track','debug','once','off','on','ready','reset','context'];var pf=function(k){return function(){var a=[].slice.call(arguments);a.unshift(k);fp.q.push(a);}};for(var i=0;i<m.length;i++){fp[m[i]]=pf(m[i]);}var e=d.createElement('script');e.async=1;e.src=s;var t=d.getElementsByTagName('script')[0];t.parentNode.insertBefore(e,t);}
  )(window, document, '<URL OF footprints.min.js ON YOUR SERVER OR CDN>', {
    endpointUrl: '<YOUR ANALYTICS REPORTING ENDPOINT URL>',
  });

  Footprints.pageView();
</script>

CDN Link

Footprints is available via Unpkg at the following URL: https://unpkg.com/[email protected]/release/footprints.min.js

Previous versions can be found here: https://unpkg.com/footprints-tracker@<VERSION>/release/footprints.min.js

Tracking Events

To track a user event, call

Footprints.track('Photo Uploaded');

This will cause a POST with a body like the following to be sent to your endpoint

{
  "pageTime": "2018-05-24T20:30:54.425Z",
  "pageId": "01CE9XHRESP6ZZ3AH8HAD3HXE3",
  "eventId": "01CE9XHREYSMBPNE23M8JZKPYB",
  "eventType":"track",
  "eventTime": "2018-05-24T20:30:54.430Z",
  "eventName": "Photo Uploaded"
}

pageTime: The time the page loaded in the browser
pageId: a ulid representing the page.
This will be the same for all events sent from the same page.
eventId: a ulid unique to this event
eventType: The type of event being sent
eventName: A name identifying the action the user has taken
title: The title of the page
url: the url of the page

User Identification

For a known user

Footprints.user('123abc', { email: '[email protected]' });

The first argument is the user's unique id from your system. The properties in the object passed as the 2nd argument will be added to every subsequent event (pageView, track, etc.)

For an unknown user

Footprints.user({ visitedSignUpPage: true });

All properties will be passed to every subsequent event (pageView, track, etc. )

Footprints.user itself does not send any events to the server, so you should call it before calling Footprints.pageView().

Setting Additional Context

You can set additional properties that will be sent on every event.

Footprints.user('12', { name: 'Brad Urani' })
Footprints.context({ pageType: 'shopping', collection: 'Fall 2018' }),
Footprints.pageView();

will create a POST with the following body:

{
  "collection": "Fall 2018",
  "eventId": "01CE9ZV5F5C8HYQ741YFJ5TNX0",
  "eventType": "pageView",
  "eventTime": "2018-05-24T21:10:59.813Z",
  "name": "Brad Urani",
  "pageId": "01CE9ZV5F47EDX0HHRG7NS4VQ9",
  "pageTime": "2018-05-24T21:10:59.812Z",
  "pageType": "shopping",
  "title": "Real News",
  "url": "http://localhost:8000/",
  "userId": "12"
}

Snippet arguments

The snippet arguments are window, documents, scriptUrl, options

<script type='text/javascript'>
  !(function(w,d,s,o){var fp=w.Footprints=w.Footprints||{};fp.q=fp.q||[];if(fp.initialized||fp.invoked) return;fp.invoked=true;fp.pageTime=new Date();fp.options = o;var m=['user','pageView','track','debug','once','off','on','ready','reset','context'];var pf=function(k){return function(){var a=[].slice.call(arguments);a.unshift(k);fp.q.push(a);}};for(var i=0;i<m.length;i++){fp[m[i]]=pf(m[i]);}var e=d.createElement('script');e.async=1;e.src=s;var t=d.getElementsByTagName('script')[0];t.parentNode.insertBefore(e,t);}
 )(window, document, scriptUrl, options);
 </script>

window: the current window
document: the current document
scriptUrl: the url of where the footprints script is located
options:

  • endpointURL: the http or https endpoint where the analytic events will be POSTed to (required)
  • debug: Enables debug output in the console if set to true
  • intervalWait: the interval at which the script retries failed events (default: 5000)
  • pageId: overrides the automatically generated pageId ulid
  • pageTime: override the automatically generated pageTime
  • successCallback: used to provide a function that is called every time an event is successfully sent
  • errorCallback: used to provide a function that is called every time an event send fails
  • readyCallback: used to provide a function that is called when the footprints script is finished loading
  • transformPayloadFunc: used to transform the POST body JSON that is created by Footprints by default into a POST body that is compatible with your endpoint (see below)
  • uniqueIdFunc: used to provide a function that creates a uniqueId, if you want to use something other than ulids
  • fetchOptions: options passed to fetch (default: { method: 'POST', headers: { 'Content-Type': 'application/json' }})
  • maxAttempts: max number of times to attempt to deliver an event (default: 'unlimited')

Transforming the event payload

If the POST body JSON generated by Footprints by default is not compatible with your endpoint, you can transform it before it is sent by using the transformPayloadFunc option. It is a function that takes the default payload and returns the desired payload and can be used to rename, convert, add or remove payload fields. So, for example, if you wanted to convert the eventTime field to UNIX epoch time, you could do:

<script type='text/javascript'>
  !(function(w,d,s,o){var fp=w.Footprints=w.Footprints||{};fp.q=fp.q||[];if(fp.initialized||fp.invoked) return;fp.invoked=true;fp.pageTime=new Date();fp.options = o;var m=['user','pageView','track','debug','once','off','on','ready','reset','context'];var pf=function(k){return function(){var a=[].slice.call(arguments);a.unshift(k);fp.q.push(a);}};for(var i=0;i<m.length;i++){fp[m[i]]=pf(m[i]);}var e=d.createElement('script');e.async=1;e.src=s;var t=d.getElementsByTagName('script')[0];t.parentNode.insertBefore(e,t);}
  )(window, document, '<URL OF footprints.min.js ON YOUR SERVER OR CDN>', {
    endpointUrl: '<YOUR ANALYTICS REPORTING ENDPOINT URL>',
    transformPayloadFunc: function(defaultPayload) {
      defaultPayload['eventTime'] = Date.parse(defaultPayload['eventTime']);
      return defaultPayload;
    }
  });

Compatibility

Footprints is written in JavaScript 5 for compatibility and to keep file sizes minimal. The only modern feature it uses is the fetch API. If you need to target browsers that don't support fetch, you should use a polyfill.

Development

Install npm and run

npm install

Start the webpack dev server

npm start

and navigate to localhost:8000

Future Improvements

  • Storing an anonymous user id in local storage for unknown users
  • Make event queue and persist between pages with local storage or background workers
  • Debounce and throttle methods
  • Callbacks for all event types
  • Link tracking capabilities
  • Form tracking capabilites
  • Ability to disable the retry timer
  • Event batching
  • Snippet version