An open-source analytics library to measure user events the hassle-free way.

Overview

walker.js

The walker.js is an open-source event tracker for all tools. Easy, standardized & flexible. Capture user events in the browser by setting HTML attributes only.
Explore the docs

Get a Demo · Report Bug · Request Feature

🤓 Usage

You can implement all sorts of front-end user events from e-commerce actions like product add to carts, product usage events, and UX events like visible elements, scrolling, etc. using the walker.

Just set a few HTML attributes

<!-- General usage -->
<div elb="ENTITY" elb-ENTITY="KEY:VALUE" elbaction="TRIGGER:ACTION" />

The result is for example something like this:

dataLayer.push({
  event: 'product add', // combination of entity and action
  data: {
    // all set properties with the elb-product attribute
    name: 'Everyday Ruck Snack',
    price: 220,
  },
  globals: {
    // all set properties with the elbglobals attribute
    language: 'en',
    test: 'darkmode',
  },
  user: {
    // a stored random id in the cookie (manually added once)
    device: 'cookieid',
  },
  nested: [], // all nested entities within the product
  id: '1647968113641-b4b9h9-5', // timestamp, group & count of the event
  trigger: 'click', // name of the trigger that fired
  entity: 'product', // entity name
  action: 'add', // entity action
  timestamp: 1647968113641, // time when the event fired
  timing: 13.37, // how long it took from the page load to trigger the event
  group: 'b4b9h9', // random group id for all events on a page
  count: 2, // incremental counter of the events on a page
  walker: true, // flag to filter events
});

All you need to get started are the entity, action & trigger attributes. You define the entity scope by setting the elb attribute with the name of an entity to an element, e.g. elb="product". An action can be added by setting the elbaction attribute on the same level or all child elements in combination with a matching trigger, e.g. elbaction="click:add" to fire a product add event when a user clicks on the tagged element. To define the entities' properties, set the composited attribute elb-ENTITY with the name and value, e.g. elb-product="name:Everyday Ruck Snack;price:220".

<div elb="product" elb-product="name:Everyday Ruck Snack;price:220">
  <button elbaction="click:add">Add to cart</button>
</div>

Triggers

By using the walker.js you don't have to deal with event listener or mutation observer initialization anymore. The walker comes with a bunch of integrated triggers that will fire your event at the right moment.

Trigger Definition
load after loading a page when DOM is ready
click when the element or a child is clicked
visible after the element has been in viewport for at least 50% for one second
submit on a valid form submission
custom calling elbLayer.push()

For further inspiration, please refer to the industry examples in our docs.

Learn more about the elbwalker event model and background in our blog.

Modes

There are three modes: default, custom, and managed. Modes describe different ways in which the walker.js can be used.

Default

By using the default mode, elbwalker automatically starts and pushes events without further configuration into the dataLayer so that you can use it in Google Tag Manager (GTM).

<script class="elbwalker" src="walker.js"></script>

Custom

By using the custom mode, you can e.g. customize destinations flexibly through code yourself. You can use the elbLayer to do the configuration manually.

<script class="elbwalker" src="walker.js" data-custom="true"></script>

Managed

When using our managed mode, a project ID will be added to the script. You can generate your custom project ID and configure the walker.js through our web app (UI).

<script class="elbwalker" src="walker.js" data-project="W3BSHOP"></script>

🚀 Getting Started

To get a local copy up and running follow these simple steps.

Prerequisites

  • npm
    npm install npm@latest -g

Installation

  1. Clone the repo
    git clone https://github.com/elbwalker/walker.js.git
  2. Install NPM packages
    npm install
  3. Start developing
    npm run dev

🛠 Contributing

Any contributions you make are greatly appreciated.

If you have a suggestion that would make the walker better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement".

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

👩‍⚖️ License

Distributed under the MIT License. See LICENSE for more information.

Contact

Send us an email if you have any questions or feedback at [email protected]

Want to send the data directly to your Google BigQuery instance? Check out our hosted version at https://elbwalker.com/

(back to top)

Comments
  • Nested entites : keyword inside closest parent for data sharing

    Nested entites : keyword inside closest parent for data sharing

    Is your feature request related to a problem? Please describe. By example, a list of products contained in a labeled section, you might be interested in capturing that the user clicked inside a specific section ( e.g: section's ID or section label ) In addition to clicked product

    Describe the solution you'd like With a similar usage as globals, properties will available for the closest nested entities or all the nested entities close or far deep inside the same dom tree branch

    Additional context from the example of nested entitles doc : in the situation where the baby entity send an event be able to have additional information provided thanks to the daughter entity

    v1.6.0 
    opened by Jojoker33 10
  • optionally capture referrer

    optionally capture referrer

    Is your feature request related to a problem? Please describe. Using walker.js on a website for collecting first party data by sending every event to a custom endpoint always needs manual addition of a referrer in order to enable channel attribution for the collected events.

    Describe the solution you'd like It would be great if walker.js would capture a referrer without manual action beyond configuration. This should be an optional feature which is not enabled by default. Otherwise existing setups that capture the whole event would pay with increased storage costs.

    The automatic collection could be added to the event data (in case of an page view or other events as well) or globals by setting an option. A choice between capturing only external referrers (for attribution) and all referrers might be useful, too.

    Describe alternatives you've considered At the moment it seems to be the only option to add the referrer as a DOM element before walker initialization or by code when using elb() function.

    v1.6.0 
    opened by mbaersch 4
  • Documentation: SSR framework behaviour

    Documentation: SSR framework behaviour

    Is your feature request related to a problem? Please describe. In SSR framework :

    • elbWalker usage requires dynamic import otherwise it create an error - ReferenceError: document is not defined

    Describe the solution you'd like Update documentations to help with ssr requirement

    bug v1.6.0 
    opened by Jojoker33 4
  • Limit

    Limit "visible" trigger to fire only once

    I am just getting started to use walker.js in a project and ran into something that might be a feature request for the visible trigger: AFAIK this trigger always fires, whenever the element appears in the viewport for at least 50% and one second. Which might be the case more than once if a user scrolls up and down a page.

    I would prefer to send this event only once per page and element instead. Is there a way to achieve that already? If not, an optional parameter would be great. Some boolean for a "unique" invocation like data-elbaction="visible(true):view" could be a solution (default would be "false" in case there is no parameter).

    opened by mbaersch 3
  • Destination request : Plausible.io

    Destination request : Plausible.io

    Is your feature request related to a problem? Please describe. As nowadays, analytics tool needs to be GDPR, CCPA or PECR compliant in order to be used in some countries : walker.js should be able to offer destinations which respect those compliance.

    Describe the solution you'd like Having Plausible analytics as destination for GDPR, CCPA and PECR compliance.

    enhancement 
    opened by Jojoker33 3
  • Hover trigger

    Hover trigger

    Is your feature request related to a problem? Please describe. The addition of an hover trigger that fires when interaction with components, elements wich expand, show other element such as submenu’s by example

    Describe the solution you'd like With almost the same usage as the already existing click trigger, but it will track only the onmouseenter event on the wanted target

    enhancement 
    opened by Jojoker33 3
  • add

    add "walker globals" command?

    Is your feature request related to a problem? Please describe. AFAIK populating global values requires to add elements to the DOM and there is no way to set globals by using JavaScript.

    Describe the solution you'd like adding a command to change / add walker key / value pairs in globals.

    Describe alternatives you've considered adding stuff to the DOM dynamically - that´s what I do at the moment.

    v1.6.0 
    opened by mbaersch 2
  • Make the destinations more modular

    Make the destinations more modular

    Is your feature request related to a problem? Please describe. When I would add a new feature atm I would simply extend the destinations.ts. But most likely I would like to have multiple destination and define on build time which ones should be active with which configuration. Could be even be extended to handle different configs based on ENV.

    Describe the solution you'd like Destination Modules that take care of the right mapping to the destinations schema. A config that provides the right parameters (eg. write tokens)

    Describe alternatives you've considered Extend the destinations.ts file individually for each project

    Additional context Add any other context or screenshots about the feature request here.

    enhancement 
    opened by deepskydata 2
  • Wait trigger

    Wait trigger

    Is your feature request related to a problem? Please describe. Add a wait trigger that fires after a given time.

    Describe the solution you'd like Like load & click etc. the new trigger should be called wait and needs a parameter about how long it should wait. E.g. elb-action=wait(n) where n is the number of milliseconds.

    Additional context Trigger parameters could be useful for others (#8). Maybe there is a function from action filter that could be used.

    enhancement 
    opened by alexanderkirtzel 2
  • Support for user ids

    Support for user ids

    Is your feature request related to a problem? Please describe. As a data engineer I want more detailed information about the user behind an event.

    • If a user is logged in I want to add the anonymous user id to an event.
    • If a user granted consent I want to use an anonymous device id stored in a cookie
    • If no PII is processed I want to use an anonymous session token

    Describe the solution you'd like I want to set user ids that will be added to each walker Event.

    Describe alternatives you've considered Using global attributes (#1) if available.

    Additional context

    export interface Event {
      entity: string;
      action: string;
      data?: AnyObject;
      trigger?: string;
      nested: Entities;
      user: {
        id?: string;
        device?: string;
        hash?: string;
      }
    }
    

    Setting the user ids to be discussed. Open for recommendations.

    enhancement 
    opened by alexanderkirtzel 2
  • Support for global properties to enhance the context of an event

    Support for global properties to enhance the context of an event

    Is your feature request related to a problem? Please describe. As a data engineer I want to know more about the global state of the website when an event gets triggered. A more detailed context would bring more insights through enhanced segmentation possibilities (e.g. language settings, login state).

    Describe the solution you'd like The walker event should be enhanced by a global property of an AnyObject type. The global state should be walked like the one of an entity. It should be possible to use elbish like an elbglobal attribute to tag elements at any place. And don't slow down the page, please.

    Describe alternatives you've considered None, lol.

    Additional context

    export interface Event {
      entity: string;
      action: string;
      data?: AnyObject;
      global: AnyObject;
      trigger?: string;
      nested: Entities;
    }
    

    enhancement good first issue 
    opened by alexanderkirtzel 2
  • Reset timing base with walker run

    Reset timing base with walker run

    Is your feature request related to a problem? Please describe. The timing is only based on performance.now(). With SPAs, or an elb("walker run") in general, the timing should be measured from that time on.

    Describe the solution you'd like Remember the run command's timestamp and subtract it from performance.now.

    Describe alternatives you've considered Leave it as it is and deal with different timing universes.

    v1.6.1 
    opened by alexanderkirtzel 0
  • Add a measurement plan template

    Add a measurement plan template

    Is your feature request related to a problem? Please describe. Adding a measurement plan type definition to configure the whole implementation.

    Describe the solution you'd like Create a measurementplan.d.ts that can be used to type-safe define the whole tracking setup. It should be walker compliant that the configuration can be used directly.

    Describe alternatives you've considered None, it's a good idea to do that

    documentation 
    opened by alexanderkirtzel 0
  • Conditional properties

    Conditional properties

    Is your feature request related to a problem? Please describe.

    Firing events with properties depending on special conditions

    Example:

    navigation menu

    Tagging:

    A view is fired when the menu is opened, as well as a click is fired when a category is clicked by the user. The nav click event should contain the clicked category.

    Problem:

    The walker is not able to recognize which category got clicked. The click event will always contain the first caught value. So the outcome will stay the same, even if the user clicks on different categories.

    Describe the solution you'd like

    The walker should be able to select the correct data in cases where multiple conditions are possible(click category A or click category B,..). So for the given example: The walker should only push the data of the clicked category and ignore everything else.

    opened by Blubasur 0
  • page click and page clickout events

    page click and page clickout events

    Is your feature request related to a problem? Please describe. Besides the auto event page view I want the page click event that occurs when a user clicked on a page. If it's an external link I want it to be a page clickout event.

    Describe the solution you'd like There are three different options:

    1. Just a click somewhere on the page
    2. A click on an internal link
    3. A click on an external site

    A page click event could contain the following basic data for all the options

    interface PageClick {
      id: string,
      tagName: string,
      className: string
      isLink: boolean;
    }
    

    if isLink is true add these data properties

    interface PageClickLink {
      title: string;
      text: string;
      href: string;
    }
    

    And if it's an external link change the action from click to clickout.

    Describe alternatives you've considered Don't measure it at all. This will lead to a lot of events. I guess people could be annoyed the amount of events and there should be a possibility to disable it (shout out to mapping).

    Additional context Inspiration from a previous beta:

    function isLink(elem) {
      var parent = elem.parentElement;
      if (elem instanceof HTMLAnchorElement) return elem;
      return parent ? isLink(parent) : false;
    }
    
    function isExternalLink(elem) {
      return elem.host !== window.location.host;
    }
    
    enhancement 
    opened by alexanderkirtzel 0
Releases(v1.6.0)
  • v1.6.0(Dec 12, 2022)

    • Scroll trigger support (#8)
    • Update old event values on pushes after consent change (#142)
    • Renamed user.hash to user.session (#137)
    • Added consent and source incl. referrer to event (#132, #115)
    • Added walker config command to update e.g. globals etc. (#129)
    • Enabled scoped inits with walker init command for e.g. async content (#127)
    • Added helpful utils for easier setups e.g. storage or debounce, throttling (#124)
    • Use page entity by default if nothing else set (#122)
    • Added context order (#81)
    • Bugfix: Support for SSR apps like Svelte (#95)
    • Bugfix: Visible trigger can't handle elements larger than viewport (#123)
    • Minified build by >30% (#125)

    Breaking Changes:

    • event.user.hash is now called event.user.session
    • event.context structure is not longer just the value but an array with value and order [value, order]
    Source code(tar.gz)
    Source code(zip)
  • v1.5.3(Oct 19, 2022)

    • Cast property types properly (string, boolean, number, #50)
    • support for array type properties (data-elb-entity="size[]:m;size[]:l", #51)
    • updated elb function usage + definitions (#102)
    • added tagger package, a helper to set walker.js properties
    • handle context on handle context on (pre-)pushes (#103)
    • performance improvements
    Source code(tar.gz)
    Source code(zip)
  • v1.5.2(Oct 17, 2022)

    • Support for additional context (data-elbcontext, #81)
    • fixed elbLayer implementation behaviour bug (#92)
    • Destination Types update for Config and EventConfig (destination.custom)
    • Support for common Destination configurations (loadScript, ignore, name)
    • Renaming of individual Events (mapping.entity.action.name = 'customName')
    • Support to ignore specific events (mapping.entity.action.ignore = true)
    • Switch to custom mode by default (use { default: true } now for the non-custom mode)
    • Removed legacy code for remote configurations
    • Added elb function to import and push events to the elbLayer
    • Updated documentation for walker.js and all destinations
    • Updated react example to TypeScript
    Source code(tar.gz)
    Source code(zip)
  • v1.5.1(Oct 4, 2022)

    • consent queue: save events temporarily while consent state isn't available and retry in given order as soon as it's available for each run
    • event mapping: Each destination can have its own event mapping definitions to validate processing and define handling
    Source code(tar.gz)
    Source code(zip)
  • v1.5.0(Sep 22, 2022)

    • New elbwalker initialization and usage mode as an instance (const elbwalker = Elbwalker({config})
    • Option to disable auto pageview events ({ config: { pageview: false } })
    • Destination mapping to configure events and/or enforce naming schema (destination.mapping[entity][action]: { config })
    • Destination consent mode to require specific consent states to be set before pushing events (destination.config.mapping: { config }), #2
    • Trigger pulse(ms) to set recurring trigger event every ms or 15 seconds by default when page is not hidden (data-elbaction=“pulse(6000):action”), #13
    • Trigger wait(ms) to schedule a trigger in ms or 15 seconds by default (data-elbaction=“wait(6000):action”), #7
    • Destinations moved out of core walker.js src folder and are available as individual npm packages, #68
    • Walker types are now part of this repository
    Source code(tar.gz)
    Source code(zip)
    index.js(10.07 KB)
    walker.js(10.29 KB)
⚡️ Lightning Time: a new way to measure time

Lightning Time ⚡️ Lightning Time ⚡️ is a new way to measure time. It's a spin on hexadecimal time: the day is split into 16 parts over and over. The f

Purdue Hackers 7 Nov 22, 2022
Next-gen mobile first analytics server (think Mixpanel, Google Analytics) with built-in encryption supporting HTTP2 and gRPC. Node.js, headless, API-only, horizontally scaleable.

Introduction to Awacs Next-gen behavior analysis server (think Mixpanel, Google Analytics) with built-in encryption supporting HTTP2 and gRPC. Node.js

Socketkit 52 Dec 19, 2022
An easy way to create a TypeScript library without hassle.

ts-lib-template An easy way to create a TypeScript library without hassle. ts-lib-template is a template for creating a TypeScript library. It comes b

Snehil K 7 Sep 13, 2022
Habitapp is a simple app that helps you build positive habits, measure progress and achieve your goals

habitapp Habitapp is a simple app that helps you build positive habits, measure progress and achieve your goals. ✨ Features Working without registrati

null 6 Sep 11, 2022
A simple, no-hassle library for efficiently querying Your Enrollment Services.

@vanderbilt/yes-api A simple, no-hassle library for efficiently querying Your Enrollment Services. Created by Dylan Hanson (jovialis) NOTE: THIS MODUL

Dylan Hanson 2 Jan 25, 2022
It shows an effective way to correct bus arrival information using data analytics based on Amazon Serverless such as Kiness Data Stream, Kinesis Data Firehose, S3, and Lambda.

Amazon Serverless를 이용한 실시간 버스 정보 수집 및 저장 본 github repository는 버스 정보를 주기적으로 수집하여 분석할 수 있도록, Amazon Serverless인 Amazon Kinesis Data Stream, Kinesis Data

John Park 4 Nov 13, 2022
This will create a REST API using Express JS and MongoDB removing the hassle of creating everything from scratch.

rest-api-init Fastest way to create REST API with Node.js, Express.js & MongoDB. Prerequisites Node.js needs to be installed. MongoDB Compass needs to

Souvik Das 7 Dec 3, 2022
Reference for How to Write an Open Source JavaScript Library - https://egghead.io/series/how-to-write-an-open-source-javascript-library

Reference for How to Write an Open Source JavaScript Library The purpose of this document is to serve as a reference for: How to Write an Open Source

Sarbbottam Bandyopadhyay 175 Dec 24, 2022
Free, open-source client or server-side APIs to "lint" user input.

passbird Free, open-source client or server-side APIs to lint user input. Right now, you can check type for an email address i.e., either of disposabl

Vaibhav Pandey 1 Dec 26, 2021
Analyzify's open-source guide & codes on Shopify Pixels & Customer Events. Follow this repo to stay up-to-date with the new pixels.

Shopify Customer Events & Shopify Pixels Shopify has announced yet another phenomenal feature: Shopify Customer Events also known as Shopify Pixels. O

Analyzify 8 Dec 8, 2022
A project for experimenting with Server Sent Events (SSE), a way of communication going from server to client.

A project for experimenting with Server Sent Events (SSE), a way of communication going from server to client.

Italo Menezes 4 May 16, 2022
An Open-Source Platform to certify open-source projects.

OC-Frontend This includes the frontend for Open-Certs. ?? After seeing so many open-source projects being monetized ?? without giving any recognition

Open Certs 15 Oct 23, 2022
Shikhar 4 Oct 9, 2022
This is a project for open source enthusiast who want to contribute to open source in this hacktoberfest 2022. 💻 🎯🚀

HACKTOBERFEST-2022-GDSC-IET-LUCKNOW Beginner-Hacktoberfest Need Your first pr for hacktoberfest 2k22 ? come on in About Participate in Hacktoberfest b

null 8 Oct 29, 2022
Apilytics for Node.js - Easy API analytics for Node backends

apilytics-node Apilytics is a service that lets you analyze operational, performance and security metrics from your APIs without infrastructure-level

Apilytics 9 Sep 2, 2022
Send data to Google Analytics with Measurement Protocol.

Strapi Measurement Protocol Send data to Google Analytics with Measurement Protocol. Table of Contents ?? Current Status ✨ Features ?? Installation ??

Strapi Community 7 Sep 16, 2022
Credence Analytics - REST- API - Assignment

Backend Assignment Position: Software Developer REST API Server ● You’ll need to create an API server with CRUD based routes using NodeJS/Python ● Using your API, users can Create, Read, Update or Delete data from the database

Arya Shah 8 Nov 14, 2022
Minimal versions of popular analytics libraries. Reduce the impact of third-party scripts on your application.

minimal-analytics This project aims to provide minimal implementations of popular analytics libraries. It's aimed at users who want to reduce the impa

James Hill 32 Dec 25, 2022