New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@visual-framework/vf-analytics-google

Package Overview
Dependencies
Maintainers
4
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@visual-framework/vf-analytics-google - npm Package Compare versions

Comparing version 1.0.4 to 1.1.0-rc.0

4

CHANGELOG.md

@@ -0,1 +1,5 @@

### 1.1.0-rc.0
* Adds gtag (GA4) support.
### 1.0.4

@@ -2,0 +6,0 @@

4

package.json
{
"version": "1.0.4",
"version": "1.1.0-rc.0",
"name": "@visual-framework/vf-analytics-google",

@@ -23,3 +23,3 @@ "description": "vf-analytics-google component",

],
"gitHead": "6059bda1bd78e57943b66be03c3f0208399d0afd"
"gitHead": "c4365e2c15b7c6c6a6459564d78da5d7a7868248"
}

@@ -11,2 +11,15 @@ # Google Analytics Enhancements component

### GA4
As of 1.1.0-rc.0 this contains gtag and GA4 support. The basics of vf-analytics-google are plug-and-play, but to get the full value out if you need to add (currently) 4 "custom definitions":
1. `event_category`
2. `event_type`
3. `page_container`
4. `vf_analytics`
[You can see a screenshot of the configuration here](https://user-images.githubusercontent.com/928100/193329800-4c750a70-1d77-4623-ba00-87db4d608511.png) and here is Google's documentation on [adding the custom dimensions to your GA4 property](https://support.google.com/analytics/answer/10075209?hl=en#new-custom-dimension) (this step is not needed in a UA property).
For more info see issue [#1428](https://github.com/visual-framework/vf-core/issues/1428)
### User actions

@@ -35,7 +48,11 @@

How to add dimension to your property?
For GA4 users, be sure to set this when using `vfGaIndicateLoaded()`:
- https://developers.google.com/analytics/devguides/collection/analyticsjs/custom-dims-mets
- https://support.google.com/analytics/answer/2709829?hl=en
```js
vfGa4MeasurementId: "G-YOUR-GA4-ID-if_using_gtag"
```
And [add the custom dimension to your property](https://support.google.com/analytics/answer/10075209?hl=en#new-custom-dimension).
### Page region tracking

@@ -55,2 +72,10 @@

### Not intended for use with Google Tag Manager
You should not use `vf-analytics-google` with Google Tag Manager. The combination makes `vf-analytics-google` unreliable and often leads to race conditions where the gtag tracking may fail to work. This is not an issue with this code, rather it is consistent with most of my reading on best practice. It is summed up well at https://measureschool.com/google-tag-manager-vs-global-site-tag/
> Both these tools utilize some common resources that can lead to conflict in some cases. For example, the data layer is one such resource that is used by both tools. Therefore, it is important to be careful while adding both of them together. You will also need to test the implementation of tools by checking whether the correct data is sent to these tools. Overall, the process is doable but complicated. That’s why I would recommend not to install them together on the same page.
That is: if you want to use Google Tag Manager, you should use that for your events. If you want to use gtag.js + custom JS, then vf-google-analytics is good for you. This code will provide particular value if you need a consistent way to collect event data across many websites, which is what we're after.
### Verbose logging

@@ -71,2 +96,3 @@

vfGaTrackPageLoad: true,
vfGa4MeasurementId: "G-YOUR-GA4-ID-if_using_gtag"
vfGaTrackNetwork: {

@@ -81,3 +107,4 @@ serviceProvider: 'dimension2',

`vfGaIndicateLoaded()` is the primary function and awaits and checks to see if Google Analytics client side JS has loaded. If it does, sets `<body data-vf-google-analytics-loaded='true'>`
In parallel, you need to load and initialize the Google Analytics script you use (analytics.js or gtag.js).
`vfGaIndicateLoaded()` is the primary function and awaits and checks to see if Google Analytics script has loaded. If it does, sets `<body data-vf-google-analytics-loaded='true'>`

@@ -84,0 +111,0 @@ #### Options

@@ -41,2 +41,3 @@ // vf-analytics-google

* @param {binary} [vfGaTrackOptions.vfGaTrackPageLoad=true] If true, the function will track the initial page view. Set this to false if you track the page view in your HTML.
* @param {string} [vfGaTrackOptions.vfGa4MeasurementId] The GA4 site measurement ID.
* @param {number} [numberOfGaChecksLimit=2]

@@ -66,3 +67,3 @@ * @param {number} [checkTimeout=900]

// debug
// console.log('checking',numberOfGaChecks,numberOfGaChecksLimit)
vfGaLogMessage('checking ' + numberOfGaChecks + ", limit: " + numberOfGaChecksLimit)

@@ -74,8 +75,21 @@ numberOfGaChecks++;

// unset our check
vfGaIndicateUnloaded();
if (el.getAttribute("data-vf-google-analytics-loaded") != "true") {
vfGaIndicateUnloaded();
}
if (ga && ga.loaded) {
el.setAttribute("data-vf-google-analytics-loaded", "true");
vfGaInit(vfGaTrackOptions);
// check to see if gtag is loaded, and then if UA is loaded, and if neither, check once more (to a limit)
if (typeof gtag !== "undefined") {
vfGaLogMessage('ga4 found');
if (el.getAttribute("data-vf-google-analytics-loaded") != "true") {
el.setAttribute("data-vf-google-analytics-loaded", "true");
vfGaInit(vfGaTrackOptions);
}
} else if (ga && ga.loaded) {
vfGaLogMessage('ua found');
if (el.getAttribute("data-vf-google-analytics-loaded") != "true") {
el.setAttribute("data-vf-google-analytics-loaded", "true");
vfGaInit(vfGaTrackOptions);
}
} else {
vfGaLogMessage('GA tracking code not ready, scheduling another check');
if (numberOfGaChecks <= numberOfGaChecksLimit) {

@@ -88,2 +102,3 @@ setTimeout(function () {

} catch (err) {
vfGaLogMessage('error in vfGaIndicateLoaded');
if (numberOfGaChecks <= numberOfGaChecksLimit) {

@@ -123,4 +138,6 @@ setTimeout(function () {

* @param {binary} [vfGaTrackOptions.vfGaTrackPageLoad=true] If true, the function will track the initial page view. Set this to false if you track the page view in your HTML.
* @param {string} [vfGaTrackOptions.vfGa4MeasurementId] The GA4 site measurement ID.
*/
function vfGaInit(vfGaTrackOptions) {
vfGaLogMessage('initing vfGaInit')
/* eslint-disable no-redeclare*/

@@ -130,4 +147,3 @@ var vfGaTrackOptions = vfGaTrackOptions || {};

if (vfGaTrackOptions.vfGaTrackPageLoad == null) vfGaTrackOptions.vfGaTrackPageLoad = true;
// Need help
// Need help?
// How to add dimension to your property

@@ -137,5 +153,18 @@ // https://developers.google.com/analytics/devguides/collection/analyticsjs/custom-dims-mets

if (typeof gtag === "undefined") {
// if the site is still using legacy GA, set a dummy gtag function so we don't have to add a bunch of if statements
vfGaLogMessage('GA4 dummy function has been set.');
window.gtag = function() {};
}
if (typeof ga === "undefined") {
// if the site is still using legacy GA, set a dummy gtag function so we don't have to add a bunch of if statements
vfGaLogMessage('GA UA dummy function has been set.');
window.ga = function() {};
}
// standard google analytics bootstrap
// @todo: add conditional
ga("set", "anonymizeIp", true);
// For Gtag you should do this in your tracking snippet
// https://developers.google.com/analytics/devguides/collection/gtagjs/ip-anonymization

@@ -154,2 +183,5 @@ // Use the more robust "beacon" logging, when available

ga("set", dimension, pageTypeName);
gtag('config', vfGaTrackOptions.vfGa4MeasurementId, {
'custom_map': { dimension: pageTypeName }
});
}

@@ -160,4 +192,6 @@

// - view the directions in README.md
// note: this feature may be broken out as a seperate dependency if the code size needs to grow further
if (vfGaTrackOptions.vfGaTrackNetwork != null) {
// note: this feature may be broken out as a separate dependency if the code size needs to grow further
// note: the VF has not yet added support for this using gtag
// https://ipmeta.io/instructions/google-analytics-4
if (vfGaTrackOptions.vfGaTrackNetwork != null && ga) {
// a copy of https://ipmeta.io/plugin.js

@@ -200,3 +234,5 @@ // included here to simplify usage and reduce external requests

if (vfGaTrackOptions.vfGaTrackPageLoad) {
vfGaLogMessage('sending page view');
ga("send", "pageview");
gtag("event", "page_view");
}

@@ -210,2 +246,3 @@

vfGaLogMessage('prepare vfGaLinkTrackingInit');
vfGaLinkTrackingInit();

@@ -218,6 +255,8 @@ }

function vfGaLinkTrackingInit() {
vfGaLogMessage('vfGaLinkTrackingInit');
document.body.addEventListener("mousedown", function (evt) {
// Debug event type clicked
// console.log(evt.target.tagName, evt.target);
vfGaLogMessage(evt.target.tagName);
vfGaLogMessage(evt.target);

@@ -228,3 +267,3 @@ // we only track clicks on interactive elements (links, buttons, forms)

let clickedElementTag = evt.target.tagName.toLowerCase();
let actionElements = ["a", "button", "label", "input", "select", "textarea", "details"];
let actionElements = ["a", "button", "label", "input", "select", "textarea", "details", "area"];
if (actionElements.indexOf(clickedElementTag) > -1) {

@@ -320,2 +359,8 @@ vfGaTrackInteraction(evt.target);

if (typeof gtag === "undefined") {
// if the site is still using legacy GA, set a dummy gtag function so we don't have to add a bunch of if statements
window.gtag = function() {};
vfGaLogMessage('GA4 dummy function has been set.');
}
if (customEventName.length > 0) {

@@ -356,3 +401,3 @@ linkName = customEventName;

// special things for gloabl search box
// special things for global search box
// if (parentContainer == 'Global search') {

@@ -399,2 +444,10 @@ // linkName = 'query: ' + jQuery('#global-search input#query').value;

ga && ga("send", "event", "Email", "Region / " + parentContainer, mailLink);
gtag && gtag("event", "Region / " + parentContainer, {
"vf_analytics": "true",
"page_container": parentContainer,
"event_label": mailLink,
"event_category": "UI",
"event_type": "Email",
"email_address": mailLink
});
vfGaLogMessage("Email", "Region / " + parentContainer, mailLink, lastGaEventTime, actedOnItem);

@@ -406,2 +459,11 @@ } else if (href && href.match(filetypes)) {

ga && ga("send", "event", "Download", "Type / " + extension + " / " + parentContainer, filePath);
gtag && gtag("event", "Type / " + extension + " / " + parentContainer, {
"vf_analytics": "true",
"page_container": parentContainer,
"event_label": filePath,
"file_extension": extension,
"event_category": "UI",
"event_type": "Download",
"link_url": filePath
});
vfGaLogMessage("Download", "Type / " + extension + " / " + parentContainer, filePath, lastGaEventTime, actedOnItem);

@@ -417,2 +479,10 @@ }

ga && ga("send", "event", "External links", "External link / " + linkName + " / " + parentContainer, href);
gtag && gtag("event", "External link / " + parentContainer, {
"vf_analytics": "true",
"page_container": parentContainer,
"event_category": "UI",
"event_type": "External link or button",
"link_text": linkName,
"link_url": href
});
vfGaLogMessage("External links", "External link / " + linkName + " / " + parentContainer, href, lastGaEventTime, actedOnItem);

@@ -454,7 +524,25 @@ }

ga && ga("send", "event", "UI", "UI Element / " + parentContainer, linkName);
vfGaLogMessage("UI", "UI Element / " + parentContainer, linkName, lastGaEventTime, actedOnItem);
gtag && gtag("event", "UI Element / " + parentContainer, {
"vf_analytics": "true",
"page_container": parentContainer,
"event_label": linkName,
"event_category": "UI",
"event_type": "Webform",
"link_text": linkName
});
vfGaLogMessage("UI Form", "UI Element / " + parentContainer, linkName, lastGaEventTime, actedOnItem);
} else {
// generic catch all
vfGaLogMessage("vfGaTrackInteraction: generic catch all")
ga && ga("send", "event", "UI", "UI Element / " + parentContainer, linkName);
vfGaLogMessage("UI", "UI Element / " + parentContainer, linkName, lastGaEventTime, actedOnItem);
gtag && gtag("event", "UI Element / " + parentContainer, {
"vf_analytics": "true",
"page_container": parentContainer,
"event_label": linkName,
"event_category": "UI",
"event_type": "Link, button, image or similar",
"link_text": linkName,
"link_url": href
});
vfGaLogMessage("UI Catch all", "UI Element / " + parentContainer, linkName, lastGaEventTime, actedOnItem);
}

@@ -481,5 +569,10 @@ }

/* eslint-disable */
console.log("%c Verbose analytics on ", "color: #FFF; background: #111; font-size: .75rem;");
console.log("clicked on: %o ", actedOnItem);
console.log("sent to GA: ", "event ->", eventCategory + " ->", eventAction + " ->", eventLabel, "; at: ", lastGaEventTime);
if (eventAction == undefined) {
// It's a simple message debug
console.log("Verbose analytics: %o ", eventCategory);
} else {
console.log("%c Verbose analytics on ", "color: #FFF; background: #111; font-size: .75rem;");
console.log("clicked on: %o ", actedOnItem);
console.log("sent to GA: ", "event ->", eventCategory + " ->", eventAction + " ->", eventLabel, "; at: ", lastGaEventTime);
}
/* eslint-enable */

@@ -486,0 +579,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc