{"id":24633212,"url":"https://github.com/kidgodzilla/event-layer","last_synced_at":"2025-08-01T06:36:37.317Z","repository":{"id":45340981,"uuid":"87873010","full_name":"kidGodzilla/event-layer","owner":"kidGodzilla","description":"A very simple analytics abstraction layer. Write your events once, then send them where ever you want.","archived":false,"fork":false,"pushed_at":"2024-08-01T04:27:56.000Z","size":274,"stargazers_count":61,"open_issues_count":2,"forks_count":8,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-01-31T01:31:17.099Z","etag":null,"topics":["abstraction","analytics","analytics-library","federation","generic","google-analytics","heap","mixpanel","simple"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kidGodzilla.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-04-11T01:14:10.000Z","updated_at":"2024-08-01T04:27:59.000Z","dependencies_parsed_at":"2024-08-01T06:30:28.481Z","dependency_job_id":"9b0169c1-228d-4ee7-b86e-4c4c64695c11","html_url":"https://github.com/kidGodzilla/event-layer","commit_stats":{"total_commits":115,"total_committers":5,"mean_commits":23.0,"dds":"0.13913043478260867","last_synced_commit":"eca98aae8b3aa6ae99e2dbdaa6004b4e9dc51a90"},"previous_names":["kidgodzilla/electric-love"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kidGodzilla%2Fevent-layer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kidGodzilla%2Fevent-layer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kidGodzilla%2Fevent-layer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kidGodzilla%2Fevent-layer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kidGodzilla","download_url":"https://codeload.github.com/kidGodzilla/event-layer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236745689,"owners_count":19198060,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abstraction","analytics","analytics-library","federation","generic","google-analytics","heap","mixpanel","simple"],"created_at":"2025-01-25T08:14:11.590Z","updated_at":"2025-02-02T03:15:29.828Z","avatar_url":"https://github.com/kidGodzilla.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Event Layer](https://raw.githubusercontent.com/kidGodzilla/event-layer/master/event-layer-logo.png)\n\n-----\n\n[![npm version](https://badge.fury.io/js/event-layer.svg)](https://www.npmjs.com/package/event-layer)\n[![License](https://img.shields.io/badge/license-MIT%20License-blue.svg)](https://opensource.org/licenses/MIT)\n![Contains](https://img.shields.io/badge/contains-badges-orange.svg)\n\nA very very simple abstraction layer for analytics code. Write your events once, then send them where ever you want.\n\n### [Demo](https://kidgodzilla.github.io/event-layer/)\n\n## Stats\n\n**Number of integrations:** 32\n\n**Number of tested integrations fully tested / considered stable \u0026 production-ready:** 14\n\n__Would you like to request an integration?__ We'd love to help out! [Open an issue](https://github.com/kidGodzilla/event-layer/issues/new) to get started. \n\nIf the docs are publicly available or it's supported by Analytics.js, it should be even easier. Link any docs you may have for Analytics.js or the Javascript API, where available.\n\n## Installation via NPM\n\n```\nnpm install event-layer\n```\n\nOnce installed, you'll need to include `event-layer.js` in your project, and then (optionally) instantiate a new object (aliasing it to a new global, if you prefer). Continue reading to see how that might work.\n\n## Installation via CDN\n\nInclude the following scripts in your project:\n\n`https://cdn.jsdelivr.net/npm/event-layer@latest/event-layer.js`\n\nThen follow the instructions below.\n\n## What is it?\n\n**“Event Layer”** is an extensible abstraction layer for working with common third-party Analytics libraries.\n\nSince more or less all analytics libraries work the same way (allowing you to identify and describe users, and track the events which they perform), \n**“Event Layer”** creates an abstraction layer and a set of adapters that allow you to write generic Analytics Tracking code once, and update your\nconfiguration later to send your data anywhere you need.\n\n\n## How does it work?\n\n1. Install your third-party analytics libraries in your application or website (you don't need to do anything special)\n2. Install `event-layer.js` in your website or app.\n3. Instantiate a new instance of **EventLayer:** (e.g. `var Analytics = new EventLayer();`).\n4. Instead of filling your app or website with service-specific tracking code, write generic code using the **“Event Layer” Javascript API** (described below).\n5. **“Event Layer”** will detect the third-party Analytics services you have installed on your website or app, and use it's own, community-maintained adapters to propagate your events, in an identical format, to each third-party service, using the latest version(s) of their APIs.\n6. **(Optional):** You can extend **“Event Layer”** by writing your own custom adapters for third-party services not yet supported. Each adapter only requires about 12 lines of Javascript, and the community is available to help you ship your first PR to **“Event Layer”**.\n\n\n## Integrations / Services Currently Supported\n\nIntegration | Stable\n------------ | -------------\nSegment.com | ✔️\nMixpanel | ✔️\nGoogle Analytics | ✔️\nPostHog | ✔️\nBeam Analytics (New!) | ✔️\nJune.so (New!) | ✔️\nCrisp.chat | ✔️\nIntercom | ✔️\nSentry | ✔️\nFacebook Tracking Pixel | ✔️\nGoogle Tag Manager | ✔️\nHeap | ✔️\nAmplitude | ✔️\nKeen.io | ✔️\nRollbar | ✔️\nTalkus | ✔️\nCrazy Egg | ✔️\nElev.io | ✔️\nDrift | ✔️\nDrip | ✔️\nHello Bar | ✔️\nImprovely | ✔️\nHelpscout | \nFullstory | \nOlark | \nCalq | \nCastle | \nLucky Orange | \nBugHerd | \nBugsnag | \nChameleon | \nInspectlet | \nQualaroo | \nCustomer.io | \nLogspot.io |\n\n*We rely on users to report their usage. Feel free to open an issue just to say \"I tested ____, and it works!\"\n\n## Creating a new instance of EventLayer\nWe realize that not everyone wants to litter their code with calls to a global named **“Event Layer”**. So you'll probably want to start off by instantiating a new instance of **“Event Layer”**.\n\n```\nvar Analytics = new EventLayer();\n```\n\nYou can name it whatever you like, but the examples given below will need to be modified appropriately.\n\n## EventLayer.identify(userId, userProperties)\n\nThis method allows you to identify the current visitor, and (optionally) describe the user.\n\n_Only identify the user, do not describe any user properties:_\n\n```\nAnalytics.identify('\u003cunique-user-id\u003e');\n```\n\n\n_Identify the user and describe user properties:_\n\n```\nAnalytics.identify('\u003cunique-user-id\u003e', {\n    name: 'John Doe',\n    subscribedToNewsletter: false\n});\n```\n\nThis is similar to the `Identify` method found in Mixpanel, Heap, and Analytics.js.\n\n\n## EventLayer.track(eventName, eventProperties)\n\nThis method allows you to identify the current visitor, and (optionally) describe the user.\n\n_Track a simple event, with no event properties:_\n\n```\nAnalytics.track('click_signup_button');\n```\n\n_Track a more complex event, with event properties:_\n\n```\nAnalytics.track('purchase', {\n    amount: 32.00,\n    itemCount: 4,\n    shippingSpeed: 'next-day'\n});\n```\n\nThis is similar to the `Track` method found in Mixpanel, Heap, and Analytics.js.\n\n## EventLayer.page(category, name, properties)\n\n_This method has been implemented identically to Analytics.js. See documentation for more details. Feel free to open an issue if you have any questions!_\n\n## EventLayer.alias(userId, previousId)\n\n_This method has been implemented identically to Analytics.js. See documentation for more details. Feel free to open an issue if you have any questions!_\n\n## EventLayer.group(groupId, traits)\n\n_This method has been implemented identically to Analytics.js. See documentation for more details. Feel free to open an issue if you have any questions!_\n\n## EventLayer.fbTrack(eventName, eventProperties)\n\n_Send track events to the facebook tracking pixel_\n\nThis method implements a copy of the track() method above, but it supports events specific to the Facebook Tracking Pixel as well. \n\nSee documentation https://developers.facebook.com/docs/facebook-pixel/api-reference for more details on implementing the Facebook tracking pixel on your website.\n\n\n\n## Writing an Adapter\n\nBelow is an example of a blank adapter.\n\n```\n'blank-adapter-template': { // Do not modify this template\n    enabled: false, // Change to true once you're completed testing\n    test: function () {},\n    identify: function (userId, userProperties) {},\n    track: function (eventName, eventProperties) {}\n}\n```\n\nIt has three main components:\n\n### 1. Test:\nThis function, once evaluated, should provide an answer to the question “has a specific third-party analytics library been installed on this page? Is it active? Should we try to send events to this service?” \n\nThis can be as simple as sniffing the window object for a global variables, and a commonly-used (and not likely to disappear) method or property:\n\n```\ntest: function () {\n    return window.ga \u0026\u0026 window.ga.loaded;\n}\n```\n\n(A simple example taken from the Google Analytics adapter)\n\n### 2. identify:\nThis function takes data from our generic `identify` method, and passes it along to a third-party library, via an adapter.\n\nThis should contain a minimal number of integrity checks and transforms, as well as a lightweight wrapper for the library's identify and/or describe functionality.\n\n```\nidentify: function (userId, userProperties) {\n    // Send the identify call to Mixpanel's JS library\n    if (window.mixpanel \u0026\u0026 userId) \n        mixpanel.identify(userId);\n\n    // Set people properties on our identified user\n    if (window.mixpanel \u0026\u0026 userProperties) \n        mixpanel.people.set(userProperties);\n}\n```\n\n(A simple example taken from the Mixpanel adapter)\n\n### 3. track:\nThis function takes data from our generic `track` method, and passes it along to a third-party library, via an adapter.\n\nThis should contain a minimal number of integrity checks and transforms, as well as a lightweight wrapper for the library's event tracking functionality.\n\n```\ntrack: function (eventName, eventProperties) {\n    // Send the tracked event to Heap's JS library\n    if (window.heap \u0026\u0026 eventName) \n    heap.track(eventName, eventProperties);\n}\n```\n\n(A simple example taken from the Heap Analytics adapter)\n\n## Adding or modifying an adapter on the fly\nYou can add or modify an adapter on the fly, after you instantiate EventLayer, by calling the `addAdapter` method.\n\n```\nAnalytics.addAdapter('my-analytics', {\n    enabled: true,\n    test: function () { return true },\n    track: function (eventName, eventProperties) { console.log('tracking') }\n});\n```\n\n## Debugging\n\nYou can set `window.__debug` to `true` to enable debugging (console output) for EventLayer.\n\n```\nwindow.__debug = true;\n```\n\n\n## Pull Requests\n\n**Yes, Please \u0026 Thank you!**\n\nTo keep things organized, please open an issue for discussion before putting too much work into a pull request. I would feel really bad if you put a lot of work into something, only for it to not make sense to include it or merge the Pull Request.\n\nAlso, to help keep things organized, try to submit individual pull requests for each issue, and keep the scope of each issue relatively small.\n\nFor example, if you wanted to add a couple of new adapters, split them into multiple pull requests so we can review them individually.\n\n\n## Issues\n\nSomething feel broken? Open an issue!\nSomething you feel is missing? Open an issue (Although we may not be able to get to everything, pull requests are most welcome!)\n\n\n## Thanks!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkidgodzilla%2Fevent-layer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkidgodzilla%2Fevent-layer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkidgodzilla%2Fevent-layer/lists"}