GithubHelp home page GithubHelp logo

jahilldev / minimal-analytics Goto Github PK

View Code? Open in Web Editor NEW
109.0 4.0 6.0 402 KB

Minimal versions of popular analytics libraries. Reduce the impact of third-party scripts on your application.

License: MIT License

JavaScript 4.42% TypeScript 95.41% Shell 0.17%
analytics ga4 minimal performance tiny google-analytics heap javascript lightweight

minimal-analytics's Introduction

minimal-analytics

CI

This project aims to provide minimal implementations of popular analytics libraries. It's aimed at users who want to reduce the impact of third-party JavaScript on their project, without losing core analytics data. If you require more advance tracking, it's recommended to use the official library instead.

Getting Started

Depending on your preferred service, visit the relevant package below and follow setup instructions:

Library Package Ready
GA4 @minimal-analytics/ga4 Yes
Heap @minimal-analytics/heap No (TBD)

minimal-analytics's People

Contributors

jahilldev avatar rbn30117 avatar sifigi4335 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

minimal-analytics's Issues

gtag() compatibility

Hello!

We'd like to start using this library for GA4 on our site(s), but we're hitting a big snag right now: having to restructure all of our tracking calls to use mostly custom code.

Is there a plan to add gtag() or even dataLayer compatibility in the future?

Minimal Analytics are getting blocked by Ad Blockers + Firefox Private Mode

Thank you @jahilldev,

I have created the Analytic Endpoint, but still, the Firefox Private Mode browser is not working.

Here is my website: https://charbelnemnom.com

You access it via Firefox Private Mode and then open the web developer tool, then click on Network.
Yes, you will see a Warning message on the page, but you can disregard it.

Refresh the page and then you can see POST: blog.charbelnemnom.com/collect is blocked.

If we look at the Headers, we can see the following:

Status: 302
Found: VersionHTTP/3
Transferred: 885 B (0 B size)
Referrer Policy: strict-origin-when-cross-origin
Request Priority: Lowest

If I access it from a normal browser, I can see real-time data so the endpoint that I created is working.

I checked https://dariusz.wieckiewicz.org/ with Firefox Private Mode, and he was able to bypass the Ad blocking mode:

Status: 204
No Content: VersionHTTP/2
Transferred: 652 B (0 B size)
Referrer Policy: strict-origin-when-cross-origin
Request Priority: Lowest

More details here: https://dariusz.wieckiewicz.org/en/minimal-google-analytics-4-snippet/#minimal-analytics-4---masking-hiding-requests

However, I am not using https://www.netlify.com/, (https://docs.netlify.com/routing/redirects/redirect-options/#query-parameters), so I cannot configure this 200 status code,

I am redirecting with 302 status with Cloudflare Workers.

https://blog.charbelnemnom.com/collect ==> https://www.google-analytics.com/g/collect

Any help is highly appreciated.

Many Thanks!!!

Unable to override default parameters

I'm testing out @minimal-analytics/ga4 on KaiOS apps but I'm running into an issue with because package apps are served with an origin like app://myapp.com/. The document location includes the app: protocol, and Google Analytics appears to discard the page path (but not page title) as a result. In Universal Analytics, I replaced the app: protocol with https: and it worked well.

Looking at getQueryParams, the event parameters are concatenated with the default parameters. If I pass { dl: 'https://myapp.com/index.html' }, it sends two dl parameters because of the behavior of URLSearchParams.

Would you consider changing the behavior to allow overriding default parameter values? This should be a non-breaking change, since anyone attempting to override default parameters now would have a bad request anyway.

Using jsDelivr?

Using the Hugo method I told you about which imports the CDN file automatically during build, sometimes the build fails due to timeout when trying to fetch the file. Is there a way to have the code hosted on jsDelivr too or any other CDN?

require.min.js:17 Uncaught Error: Mismatched anonymous define() module:

I have tested the minimal analytics script for GA4 in a Magento shop with the default installation instruction:

<script src="https://cdn.jsdelivr.net/npm/@minimal-analytics/ga4/dist/index.js" async</script> <script> window.minimalAnalytics = { trackingId: 'my tracking ID', autoTrack: true, }; </script>

I get this error in the browser console:

require.min.js:17 Uncaught Error: Mismatched anonymous define() module: ()=>(()=>{"use strict";var e={508:(e,t,n)=>{function o(e,t=300,n=0){return(...o)=>

.......................

analytics.com/g/collect";navigator.sendBeacon(${r}?${s}),k(t),m=!0}e.track=D,r&&(window.track=D),a&&D()})(),o})()
https://requirejs.org/docs/errors.html#mismatch
at makeError (require.min.js:17:53)
at intakeDefines (require.min.js:81:132)
at require.min.js:104:45
makeError @ require.min.js:17
intakeDefines @ require.min.js:81
(anonymous) @ require.min.js:104
setTimeout (async)
req.nextTick @ require.min.js:123
localRequire @ require.min.js:104
defContext.require @ mixins.min.js:11
requirejs @ require.min.js:123
(anonymous) @ (index):1593

How to use the code

Hi. I installed node.js and run the command you provided.

  1. Is the index.js file the complete code I should copy to my site?
  2. How do I add GA4 tracking ID?
  3. My site is based on Hugo if it matters.
  4. I am a JS noob, let alone typescript. So, kindly bear with me

Tracking code

Your example is GX-XXXXX but in my GA4 property it is G-XXXXX.

Add a note about what options to toggle in GA4

Hi. While this might seem obvious to others, could you kindly add a note in the readme file about what options users need to toggle in their GA4 property? (I think pageview, scroll and search?). Perhaps as a new paragraph just before or after the "Getting Started" heading.

Inline onclick event tracking

@jahilldev Bugging you here in a new thread instead.

I look for a html onclick action, so we dont have to run the javascript event listner globally when its not needed. We run it only when the user clicks on the action.

@jahilldev Any process on inline event tracking like the onclick="ga('send', 'event', 'eventCategory', 'eventAction', 'eventLabel');"

Basically all I want is to do as you had in universal Event: ma.trackEvent('Category', 'Action', 'Label', 'Value')

How would it look for example on a link element.

<a href="https://example.com/link/">Visit</a>

or am I seeing this wrong and this should work?

<a class="button" href="#" onclick="gtag('event', <action>, {
		  'event_category': <category>,
		  'event_label': <label>
		});">
	<span class="button_label">Start now
	</span>
</a>

Not tracking downloads through form submit

Hello!

We have a form, to enforce captcha and/or CSRF tokens on download. However, this library doesn't track those as downloads - even though they do result in a download, and the link the form submits to ends in a supported file ext.

Is this intended behavior, or a missing feature?

Unable to make it work with CDN implementation

Thanks for your script!

I tried to implement the simplest solution for me, by adding just the following lines to my pages' head:

<script src="https://unpkg.com/@minimal-analytics/ga4/dist/index.js" async />

<script>
  window.minimalAnalytics = {
    trackingId: 'G-XXXXX', // <-- replace with your GA4 property ID
    autoTrack: true,
  };
</script>

But I get now hits. Of course, I have replaced the 'G-XXXXX' with my GA4 property ID. Is there anything else I need to do/add?

Beacon parameter inconsistencies from their original GA4 specs

Context: Derived from the jsDeliver source of minimal-analytics, I created tag.js which has evolved into a more advanced self-hosted substitute with basic dataLayer functionality and most gtag() configuration fields, with roughly 90% web features, including all GA4 Enhanced Measurements, combined into a light 5.5k gzipped size (10KB minified original).

My goal is not to ask for changes, or to submit pull request; as I am not very savvy in Typescript anyway, and there are many fundamental flaws to address... This is a tweet follow-up, to try and point out the core issues I encountered along the way, working from the minimal-analytics js source. (For helpful reference, I posted tag.js as a private gist at the moment.)

Current GA4 mismatch or misconceptions:

  1. sessionStorage is not adequate as it's not multi-tab compatible (single window only). GA4 cookies provide full compatibility with multiple tabs or windows. localStorage only is better suited for all parameters that need storage.

  2. The fv firstVisit is a function of is_new_to_site not is_new_session.

  3. The _s hit count is the number of events sent during a page view session. Not just a static 1. e.g. A scroll event after page_view would qualify as _s=2

  4. The sid sessionId does not change until a new session starts. It's the last part of the permanent _ga cookie representing the sessionStart timestamp. @thyngster has a lot of helpful references on his Google Analytics 4 Measurement Protocol CheatSheet.

  5. The sct session count is accurately stored. However the way it works, is that it's only incremented on inactivity after a 30 minutes default from the sessionStart (sid) timestamp. See this tweet for additional context.

  6. seg sessionEngagement is complex. In brief, it starts with 0 and keeps switching, with 'conversion' event exceptions.

  7. The beforeunload event is not reliable. I opted with pagehide at the moment, alongpageshow for auto page_view(s).

  8. Unless I am missing something, you can much simplify that overkill scroll percentage function with the following:
    Math.round(100 * Math.abs(document.documentElement.scrollTop / (document.documentElement.scrollHeight - document.documentElement.clientHeight)))

  9. Per my tests and implementation, ep.search_term is not a parameter sent along other events (such as page_view), and only one event name at a time is supported. ep.search_term is either sent in the beacon payload as a batched parallel event, or a separate view_search_results event but not together by default, as it is now.

Direct localStorage/ sessionStorage access prevents usage from Worker context or Safari Private tab

WorkerGlobalScope (which ServiceWorkerGlobalScope inherits from) does not include localStorage or sessionStorage, but using @minimal-analytics@gav4 in a ServiceWorker context throws a ReferenceError because of this hard dependency. It also throws a QuotaExceededError in a Safari Private tab when attempting to call setItem.

Instead, using a wrapper like storage-factory would prevent these runtime errors. Developers in a Worker context would then need to manually set the Client ID cid value, i.e. by copying the clientId value on the main thread between localStorage and indexedDB.

Customize analytics endpoint

I would like to reverse proxy calls to the GA server through my own domain using a Cloudflare worker in order to prevent ad blockers from blocking the request, so I would appreciate if you could add the ability to customize analyticsEndpoint. Thanks!

Not measuring engagement time

I created a new GA4 instance but the CDN code is not recording the average engagement time anymore. https://prnt.sc/mckg9ky5d20j

Edit: I compared my previous GA4 instance and I found there is a greater discrepancy in engagement time between the two instances with regards to average engagement time. The previous one (which I used with the early versions of GA4 code you made) shows everything as I would expect (e.g reading time of 3 minutes), but the latest code has lots of erratic instances like 00 seconds or at most 9 seconds for similar posts.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.