Social shares tracking in GA - google-analytics

This is pretty much covered topic for original FB/Twitter buttons. But what if I have my own "share on fb" button? Like this:
<div id="fb_share"><a target="_blank" href="http://www.facebook.com/share.php?u=blah-blah">Share on FB</a></div>
so I've come up with the folloing solution:
var FBbtn = document.getElementById("fb_share");
FBbtn.addEventListener('click', function() {
ga('send', 'social', {
'socialNetwork': 'facebook',
'socialAction': 'share',
'socialTarget': window.location
});
//console.log('tracked');
});
That is placed AFTER the Google Analytics code.
Despite the fact it wont catch FB callback - it is supposed to do the trick but for some reason I still cannot see any results in Analytics so the question is this: will the solution actually work? In fact it could be even like this I believe:
FB

Your 'share on Facebook' links causes the page to navigate (and not open a new window/tab). When this navigation happens, most mainstream browsers cancel all pending HTTP requests for the current page and then navigates to the new page (fb.com)
In this scenario, one of the pending HTTP requests will be the GA event tracking call which will therefore never complete and never be received by the GA servers.
What you need to use is the GA hit callback functionality, this essentially cancels the native navigation (to FB), sends the tracking call and waits enough time for it to complete and then does a JavaScript redirection to the next page.
You should read the google docs here
In your case your event tracking function should be similar to this:
var FBbtn = document.getElementById("fb_share");
FBbtn.addEventListener('click', function() {
ga('send', 'social', {
'socialNetwork': 'facebook',
'socialAction': 'share',
'socialTarget': window.location,
'hitCallback': function(){
window.location = this.href;
}
});
//console.log('tracked');
return false;
});
So I've made the following changes:
Added the hitCallback property to the event tracking call. this is an anonymous function that is called once the GA servers have sent their response to the event tracking.
added a 'return false' statement which cancels the native functionality and then relies on the hitCallback function to do the navigating.

Related

Google analytics 4 events sometimes not arriving

I am tracking purchases on a site in google analytics by sending a custom event from JavaScript to Google Tag Manager on the "successful purchase" page. Most of the time this works perfectly, but in some cases it seems the event just doesn't arrive to Google Analytics.
Initially I thought that maybe visiting the success page couldn't be relied on, but then I added an additional call after triggering the event that logs the sending of the event to my database. To my surprise, the events so far always get logged to my database, but they still sometimes don't show up in analytics. This is the code that does this:
const event = {
'event': 'purchase',
'ecommerce': {
'transaction_id': orderData.id,
'value': orderData.price,
'currency': 'EUR',
'coupon': orderData.CouponCode,
"items": orderData.services.map(elem => ({
'item_id': elem.id,
'item_name': elem.name,
'price': elem.price,
'item_type': elem.type,
'quantity': 1,
})),
}
};
// Send GA4 purchase event
dataLayer.push(event);
// Log to my db
fetch("/ajax/trackAnalytics", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
event,
cleaning_id: orderData.id
})
})
Let's take the 2nd of December as an example. According to google analytics these were the incoming purchases:
But in my database I received the following logs (I redacted the "items" field because it contained customer information but it shouldn't matter):
{
"event":"purchase",
"ecommerce":{
"transaction_id":6520,
"value":73.89,
"currency":"EUR",
"coupon":null
},
"timestamp":"2022-12-02T15:10:47+00:00"
}
{
"event":"purchase",
"ecommerce":{
"transaction_id":6519,
"value":67.99,
"currency":"EUR",
"coupon":null
},
"timestamp":"2022-12-02T15:57:44+00:00"
}
{
"event":"purchase",
"ecommerce":{
"transaction_id":6487,
"value":197.05,
"currency":"EUR",
"coupon":null
},
"timestamp":"2022-12-02T19:17:54+00:00"
}
As you can see, everything matches up except the transaction with ID 6520.
I tried creating orders that contained the exact elements 6520 did but I wasn't able to reproduce the issue that way. I also tried doing the same with a tracker blocker enabled on my browser but still the data came through.
The tag manager setup is the following:
Purchase trigger:
Purchase tag:
Sometimes if the user installed the ad block extension on their browser.
These kind of the analytic tags will not fire at all.
You said you tried installed some kind of this and it will work. This mean you might installed the different blocker as the user's.
Not every kind of blocker will block GA request. But still some of them did.
There are still many reasons cause the GA4 hit not sent. But if we are using the client side GTM container. It will always have some different with backend data. Just more or less.
As Darrellwan suggested, adding the line window.dataLayer = window.dataLayer || []; before dataLayer.push seems to have solved the problem, but it's not 100% clear.

Track GA4 custom event

I am sending a custom event ("ebook") with a parameter ("titolo") to GA4. After that, I have set the parameter as a Custom Dimension in GA UI.
I am sending the event from my website with this code:
function ebooksGA4new(title) {
gtag('event', 'ebooks', {
'titolo': title
});
}
Then I have set an Exploration on the custom dimension, but after 3 days it still reports "not_set. If I fire the event, I can see it in the real-time report.
Here are 2 ways to find out why
Modify the code a bit, make sure it won't trigger the event if it doesn't have title parameter.
But please make sure this is what you want. You need to decide it is ok or not to receive the event without title parameter.
function ebooksGA4new(title) {
if(!title || title=="")
return false;
gtag('event', 'ebooks', {
'titolo': title
});
}
Open the chrome devtool or something similar with it. Here is the screenshot about how to check it. This should appear on your GA4 real time report as well.

Is there any way to detect when ga send is finished (promise, callback, event, etc.)?

I need to send an event using ga(), then immediately redirect to another page. If the ga() send isn't complete it is cancelled by the redirect. Is there any mechanism (such as a callback) that I can use to detect when the event has been delivered to GA (or errored out)? I am currently just delaying for a small period of time, but that is non deterministic.
There is (and it is even called callback): Hit Callback. Redirecting after the tracking call indeed the major usecase. E.g the documentation from the example deals with intercepting a form submit, and resubmitting after the form has been sent:
// Gets a reference to the form element, assuming
// it contains the id attribute "signup-form".
var form = document.getElementById('signup-form');
// Adds a listener for the "submit" event.
form.addEventListener('submit', function(event) {
// Prevents the browser from submitting the form
// and thus unloading the current page.
event.preventDefault();
// Sends the event to Google Analytics and
// resubmits the form once the hit is done.
ga('send', 'event', 'Signup Form', 'submit', {
hitCallback: function() {
form.submit();
}
});
});

Branch Deep Linking not working in Google Analytics hitCallback

I'm using both Google Analytics and branch.io in this website.
The website is designed for mobile.
The problem is that when clicking the banner with text "OPEN", the app cannot be opened.
Here is the code for the click:
$scope.openApp = () => {
let appOpened = false;
const open = () => {
if (!appOpened) {
appOpened = true;
branch.deepviewCta();
}
};
$timeout(open, 1000);
ga('send', 'event', 'homepage', 'download', {
hitCallback() {
open();
}
});
};
If I get rid of the GA code, it works fine:
$scope.openApp = () => {
let appOpened = false;
const open = () => {
if (!appOpened) {
appOpened = true;
branch.deepviewCta();
}
};
$timeout(open, 1000);
open();
};
The reason I put open() in hitCallback is to make sure GA sends out the hit because open() will redirect to another page.
Can you help me?
Alex from Branch.io here:
The Branch deepviewCta() function works on iOS 9+ by triggering an automatic redirect to a Universal Link URL (which opens the app) and then going to a fallback URL if that fails. But Apple is very specific about the situations in which a Universal Link is allowed to launch the app (including things like how long of a pause is allowed before redirection). Of course these restrictions are not public, so all we can do is guess. My suspicion is that putting the deepviewCta() function inside a GA callback is falling outside of Apple’s rules, so the app never opens and you are instead being sent to the fallback URL.
I can think of two options here:
You can build some way to trigger the GA and Branch functions separately so that they don’t conflict with Apple’s requirements.
We actually have a brand new, one-click integration with Google Analytics, which you can read about here and here. If you set that up, you’ll get all Branch-related events automatically instead of needing to manually collect link click data.
Hopefully that helps!

React + Router + Google Tag Manager

I've been spending a bit of time developing an MVP at quickcypher.com. I wanted to start putting in some analytics, and it worked great for just tracking total visits, but things went south when I tried to track different URLs on my site that uses React Router.
My approach was this: Setup a GA tag that fires on some pages, using a trigger for a custom "pageview" event. When things did fire, I would set the field page to "/rap" for example. I was firing the event in the "componentDidMount" method of the top level component for each of my views. Using the debugger, I saw the event fire as expected, but for the life of me I can't get GA to acknowledge the event. GA works as expected when I simplify the tag to fire on "all pages", so I'm assuming it has something to do with React.
Has anyone successfully implemented this or run into similar problems? Is my approach all wrong? Hoping for some guidance...cheers!
A bit late to the party here, but react router should need no special code to integrate with GTM. Just drop the GTM script on your page (immediately after the opening <body> tag as recommended) and let your app run as normal.
In GTM create a custom trigger for history change.
You can fire it on all history changes.
Or only on some of them. Only on your production hostname, for example.
Then add a tag for your google analytics (or whatever) and configure it to fire on your history change event by clicking "More" under "Fire On" and selecting the trigger created above.
It's also important to change the Advanced Settings of our tag to fire once per event instead of once per page. Without this, the tag will only fire on the initial page load.
This could be due to misconfiguration of your google analytics account, but assuming that you can fire the initial pageview event back to GA, here is a recipe that taps into react-router's willTransitionTo hook. It also uses react-google-analytics. First npm install react-google-analytics.
Then configure your app like so:
var React = require('react');
var Router = require('react-router');
var Route = Router.Route;
var DefaultRoute = Router.DefaultRoute;
var RouteHandler = Router.RouteHandler;
var ga = require('react-google-analytics');
var GAInitiailizer = ga.Initializer;
// some components mapped to routes
var Home = require('./Home');
var Cypher = require('./Cypher');
var App = React.createClass({
mixins: [Router.State],
statics: {
willTransitionTo: function(transition, params, query, props) {
// log the route transition to google analytics
ga('send', 'pageview', {'page': transition.path});
}
},
componentDidMount: function() {
var GA_TRACKING_CODE = 'UA-xxxxx';
ga('create', GA_TRACKING_CODE);
ga('send', 'pageview');
},
render: function() {
return (
<div>
<RouteHandler />
<GAInitiailizer />
</div>
);
}
});
var routes = (
<Route path="/" handler={App} >
<DefaultRoute handler={Home} />
<Route name="cypher" path="/cypher" handler={Cypher} />
</Route>
);
Router.run(routes, function (Handler) {
React.render(<Handler />, document.body);
});
module.exports = App;

Resources