I have very long web pages paths reported to google analytics:
/#/legends_g01/games/legends_g01_02_academy_i-170909-55/notes/1/dynamics
/#/legends_02_academy_i/games/legends_g01_02_academy_i-170912-64/notes/12/players
/#/legends_05/games/legends_05-170912-84/notes/22/players
/#/legends_g01_02_academy_i/games/legends_g01_02_academy_i-170919-78/notes/34/levels
I'm using Core API to create a query where I need to have a metric ga:users with dimension by the last path part (7th). The starting part of the path doesn't matter here and should be ignored.
So if there is ga:pagePathLevel7 then I can use
dimension: ga:pagePathLevel7
metrics: ga:users
And see the result like this:
dynamics: 34
players: 45
levels: 87
How can I do this without ga:pagePathLevel7?
It seems that I'm the only one here with such a problem.
As I failed to find a direct solution I ended up adding custom dimensions to my google analytics. I added the dimensions for the last important path parts and changed the code on the site to supply this data together with the pageView url.
import ReactGA from 'react-ga';
export const statDimension = (dimensionName, value) => {
if(value)
{
let obj = {};
obj[dimensionName] = value;
ReactGA.set(obj);
}
};
export const statPageView = (url, game_id, clip_num) => {
if(!url)
{
url = window.location.hash;
}
//set game_id
statDimension(STAT_DIM_GAME_ID, game_id);
//set clip number
statDimension(STAT_DIM_CLIP_NUM, clip_num);
ReactGA.pageview(url);
return null;
};
I use react-ga npm module for submitting data to google analytics.
Now I can use custom dimensions together with filters on my urls to get stats based on the parts of the path with depth > 4.
May be that's not an elegant solution but is a working one.
Hope this will be helpful for somebody like me.
Related
Our GA4 property in Google analytics is showing our own website as a referral source. Normaly, in ga3 property there is a filter where you can exclude sites like payment portals and such. In the new property this feature is not yet available.
We tried using the following script to workaround the problem
var ref = {{Referrer}};
// don't bother if there is no referrer
if (!ref) return ref;
var newref;
// place your external referrers here (domain names)
// adding 'foo.bar.com' matches 'www.foo.bar.com' too
var domains = [
// banks
'rabobank.nl', 'ing.nl', 'abnamro.nl', 'regiobank.nl', 'snsbank.nl',
'asnbank.nl', 'triodos.nl', 'vanlanschot.nl', 'knab.nl', 'bunq.com',
'frieslandbank.nl', 'snsreaal.nl', 'secure-ing.com',
// payment providers, cards, foreign banks
'mollie.nl', 'mollie.com', 'paypal.com', 'paypal.nl', 'adyen.com',
'multisafepay.com', 'visa.com', 'wlp-acs.com', 'belfius.be', 'payin3.nl',
'icscards.nl', 'arcot.com', 'securesuite.co.uk', 'hsbc.com.hk',
'cm-cic.com', 'pay.nl', 'redsys.es', 'tatrabanka.sk'
];
domains.forEach(function(x) {
// loop through domains,
if(ref.match(RegExp('^https?://([^.]+\.)?'+ x +'/')))
newref = x;
})
// return referrer, or the new one
return newref ?
'https://' + {{Page Hostname}} + '/excluded-referrer/' + newref
: ref
}
The script does not work though. Could you give me any new recommendation on how to solve this issue or tell me if the code might be wrong?
Thanks
Update: Google actually releases gradually a referral exclusion feature in GA4, which you can find here:https://support.google.com/analytics/answer/10327750?ck_subscriber_id=750579406
Thankfully this will help with this problem.
I'm noticing double entry in google analytics. I have multiple ocurrences where it looks like the user came from the CPC campaign (which always has a 0s session duration) but that very same user also has an entry for "organic" and all the activities are logged under that.
My site is not ranked organically for those keywords. Unless a so many users come to my site, leave, and google for my "brand name" on google and revisits, this doesn't make sense.
I'm a little confused. Here's the report:
preview from google analytics dashboard
Based on the additional information in your comment, that the sites is a Single Page Application (SPA), you are most likely facing the problem of 'Rogue Referral'.
If this is the case, what happens, is that you overwrite the location field in the Analytics hit, losing the original UTM parameters, whereas referral is still sent with the hit, so Analytics recognizes the second hit as a new traffic source. One of the solutions is to store the original page URL and send it as the location, while sending the actual visited URL in the page field.
A very good article on this topic with further tips, by Simo Ahava, is available for your help.
Also please note, that as you have mentioned, that the first hit shows 0 second time on page, you might need to check, whether the first visited page is sent twice. E.g. sending a hit on the traditional page load event, and sending a hit for the same page as a virtual page view.
I have come up with a solution to this problem in a Gatsby website (a SPA), by writing the main logic in the gatsby-browser.js file, inside the onRouteUpdate function.
You can use this solution in other contexts, but please note that the code needs to run at the first load of the page and at every route change.
If you want the solution to work in browsers that do not support URLSearchParams I think you can easily find a polyfill.
Function to retrieve the parameters
// return the whole parameters only if at least one of the desired parameters exists
const retrieveParams = () => {
let storedParams;
if ('URLSearchParams' in window) {
// Browser supports URLSearchParams
const url = new URL(window.location.href);
const params = new URLSearchParams(url.search);
const requestedParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'gclid'];
const hasRequestedParams = requestedParams.some((param) => {
// true if it exists
return !!params.get(param);
});
if (hasRequestedParams) {
storedParams = params;
}
}
return storedParams;
}
Create the full URL
// look at existing parameters (from previous page navigations) or retrieve new ones
const storedParams = window.storedParams || retrieveParams();
let storedParamsUrl;
if (storedParams) {
// update window value
window.storedParams = storedParams;
// create the url
const urlWithoutParams = document.location.protocol + '//' + document.location.hostname + document.location.pathname;
storedParamsUrl = `${urlWithoutParams}?${storedParams}`;
}
Send the value to analytics (using gtag)
// gtag
gtag('config', 'YOUR_GA_ID', {
// ... other parameters
page_location: storedParamsUrl ?? window.location.href
});
or
gtag('event', 'page_view', {
// ... other parameters
page_location: storedParamsUrl ?? window.location.href,
send_to: 'YOUR_GA_ID'
})
I've looked extensively and tried to modify multiple sample sets of codes found on different posts in Stack Overflow as well as template documents in Google App Maker, but cannot for the life of me get an export and en email function to work.
UserRecords table:
This is the area where the data is collected and reviewed, the populated table:
These are the data fields I am working with:
This is what the exported Sheet looks like when I go through the motions and do an export through the Deployment tab:
Lastly, this is the email page that I've built based on tutorials and examples I've seen:
What I've learned so far (based on the circles I'm going round in):
Emails seem mostly straight forward, but I don't need to send a message, just an attachment with a subject, similar to using the code:
function sendEmail_(to, subject, body) {
var emailObj = {
to: to,
subject: subject,
htmlBody: body,
noReply: true
};
MailApp.sendEmail(emailObj);
}
Not sure how to change the "body" to the exported document
To straight up export and view the Sheet from a button click, the closest I've found to a solution is in Document Sample but the references in the code speak to components on the page only. I'm not sure how to modify this to use the table, and also what to change to get it as a sheet instead of a doc.
This may seem trivial to some but I'm a beginner and am struggling to wrap my head around what I'm doing wrong. I've been looking at this for nearly a week. Any help will be greatly appreciated.
In it's simplest form you can do a Google sheet export with the following server script (this is based on a model called employees):
function exportEmployeeTable() {
//if only certain roles or individuals can perform this action include proper validation here
var query = app.models.Employees.newQuery();
var results = query.run();
var fields = app.metadata.models.Employees.fields;
var data = [];
var header = [];
for (var i in fields) {
header.push(fields[i].displayName);
}
data.push(header);
for (var j in results) {
var rows = [];
for (var k in fields) {
rows.push(results[j][fields[k].name]);
}
data.push(rows);
}
if (data.length > 1) {
var ss = SpreadsheetApp.create('Employee Export');
var sheet = ss.getActiveSheet();
sheet.getRange(1,1,data.length,header.length).setValues(data);
//here you could return the URL for your spreadsheet back to your client by setting up a successhandler and failure handler
return ss.getUrl();
} else {
throw new app.ManagedError('No Data to export!');
}
}
I have a Data Layer that is giving me information like this from Drupal
dataLayer = [{
"entityType":"node",
"entityBundle":"article",
"entityTaxonomy":
{"funnel_path":{"2":"Find a Park"},
"byline":{"4":"Name1","5":"Name2"}},"drupalLanguage":"en",
"userUid":"1"}
];
</script>
I can easily use GTM's Data Layer variable to pull in entityBundle. How do I set it to pull in the information in byline? I tried entityTaxonomy.byline, but that give me an array. I can set to do entityTaxonomy.byline.4 to get Name1, but that would be silly since the editors would be regularly adding things.
I am planning to add the byline, ultimately, into Custom Dimension 2 in Google Analytics.
I am looking to have the data that goes to Custom Dimension 2 to be Name1, Name2 . Sometimes this will be just one value. Sometimes it can be up to 20 values.
What do I need to do in GTM to get it to register that information?
entityTaxonomy.byline actually gives you an object. You would need to do a bit of processing to get an array that you can join into a string. One possible way would be
temp = [];
Object.keys(test.entityTaxonomy.byline).map(function(key, index) {
temp.push(test.entityTaxonomy.byline[key]);
});
bylines = temp.join(",")
(I'm sure that could be done much more concise). In GTM you would need to create a variable that contains the objects with the bylines, then you could do the processing in a custom javascript variable (which is by definition an anonymous function with a return value)
function() {
var byLineObject = {{bylines}} // created as datalayer var beforehand
temp = [];
Object.keys(byLineObject).map(function(key, index) {
temp.push(byLineObject[key]);
});
return temp.join(",")
}
There are many QR codes that contains URL of website such as:(it just demos link)
http://www.popupstore.com/index.php?qrcode_type=magazine&location=Singapore
http://www.popupstore.com/index.php?qrcode_type=banner&location=Vietnam
I need a way can summary to know that where customer come from (nearly same as source/channel in Google Analytics):
Type: Mazazine, banner, etc.
Location: Vietnam, Singapore, etc.
Can anyone help me please :)
You could create two Custom Dimensions, each for Type and another for Country
As per your need define the appropriate Scope of the dimension, a Hit level or Session level scope would be appropriate.
You need to push custom dimensions into Google Analytics i.e. additonal JS code in your site.
ga('send', 'pageview', {
'dimension1': 'Magzine',
'dimension2': 'Singapore'
});
How this works
User scans the code and visits the store
Site has a JS code snippet that would get the query parameters from the URL and sets a custom dimension for each parameter
Setting the custom dimension would let Google Analytics know the value of the Type and Country
It is your JS code that tells Google Analytics what value to take for custom dimension. Google Analytics would not know that the value came from the URL.
To get a query parameter value via javascript you can refer to this answer, If you take the function provided there by Jan Turon (head over and give him an upvote of this helps you):
function getJsonFromUrl() {
var query = location.search.substr(1);
var result = {};
query.split("&").forEach(function(part) {
var item = part.split("=");
result[item[0]] = decodeURIComponent(item[1]);
});
return result;
}
You can use this to dynamically set the dimensions based on the url. You first call the function to return an JSON object that has the key/value pairs from the query parameters, then you insert the needed values to set the dimensions:
result = getJsonFromUrl();
ga('send', 'pageview', {
'dimension1': result.qrcode_type,
'dimension2': result.location
});