How-to: Add Google Analytics to App

I figured out a way to make this work - it took a little tinkering, but it seems to work great.  So, in your app's javascript code block you will want to use the wrapper that gets called anytime a scene is rendered, and then call the google analytics code: 

$(document).on('knack-scene-render.any', function(event, scene) {

// GOOGLE ANALYTICS

// set variables to be used as the page URL and Title -
// you can customize these using jquery if you want to pull something different than I did.
var pagetitle = $(’.kn-crumbtrail a:first-child’).text()+’ - ‘+$(’.kn-scene h1’).text();
var pageurl = window.location;

// this part needs to all be on one line - be sure to replace your ga ID/code
$("#knack-body").append("<script>\n\n(function(i,s,o,g,r,a,m){i[‘GoogleAnalyticsObject’]=r;i[r]=i[r]||function(){\n(i[r].q=i[r].q||).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\nm=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n})(window,document,‘script’,’//www.google-analytics.com/analytics.js’,‘ga’);\n\nga('create’, ‘UA-XXXXXXXX-X’, ‘auto’);\nga(‘send’, ‘pageview’, {\n ‘page’:’"+pageurl+"’,\n’title’:’"+pagetitle+"’\n});\n\n</script>");

});

Please note - you will need to replace the google analytics ID with your own - I changed it to “UA-XXXXXXXX-X” in my sample above.

This code will take the proper URL (with all the query parameters) and send it along, and it makes a title out of the first section on the breadcrumb to give you context for the page name, which it pulls from the H1. On the top level it will include an errant " - " after the section name, but that won’t really affect the usefulness of using Google Analytics.  I set the url and title before calling the big ugly string in case you want to customize what gets sent to gA.

I hope someone else finds this helpful.

Benjamin

Hope this helps someone.
If you want your Analytics to show the actual URLs instead of your app name (mine just said "App" a thousand times) then copy this: 
 
/* Replace measurement ID with yours */

$(document).on('knack-scene-render.any', function(event, scene) {

var measurementID ='INSERT YOUR MEASUREMENT ID HERE';

if (typeof gtag ==='function'){

gtag('js', new Date());

gtag('config', measurementID, {

// disable the default pageview hit

send_page_view: false

});

gtag('event', 'page_view', {

page_title: location.pathname + location.search + location.hash,

page_location: location.search,

page_path: location.pathname

});

} else {

window.dataLayer = window.dataLayer || [];

LazyLoad.js([`https://www.googletagmanager.com/gtag/js?id=${measurementID}`],function(){

window.gtag = window.gtag || function gtag() { dataLayer.push(arguments); }

gtag('js', new Date());

gtag('config', measurementID, {

// disable the default pageview hit

send_page_view: false

});

// Manually send page_view events

gtag('event', 'page_view', {

page_title: location.pathname + location.search + location.hash,

page_location: location.search,

page_path: location.pathname

});

});

}

});
 
I followed the instructions from Google here:
https://developers.google.com/analytics/devguides/collection/gtagjs/pages#manual_pageviews
 
Thanks 

Wanted to share this, hope it helps:

So I got an email from google, asking to migrate from analytics.js to the latest tag gtag.js.

My previous code in my Knack app looked like this:

$(document).on('knack-scene-render.any', function(event, scene) {
  if (typeof ga === 'function') {
    ga('send', 'pageview', "/" + window.location.href.split('#')[1]);
  } else {
    LazyLoad.js(['https://www.google-analytics.com/analytics.js'], function () {
    window.ga = window.ga || function() { (ga.q=ga.q||[]).push(arguments) };
    ga.l=+new Date;
    ga('create', 'GA-appcode', 'auto');
    ga('send', 'pageview', "/" + window.location.href.split('#')[1]);
  });
}
});

The new gtag code, looks like this:

$(document).on('knack-scene-render.any', function(event, scene) {
if (typeof gtag === 'function') {
  gtag('event', 'page_view', { page_path: "/" + window.location.href.split('#')[1] });
} else {
  window.dataLayer = window.dataLayer || [];
  LazyLoad.js(['https://www.googletagmanager.com/gtag/js?id=GA-appcode'], function () {
    window.gtag = window.gtag || function gtag() { dataLayer.push(arguments); }
    gtag('js', new Date());
    gtag('config', 'GA-appcode');
    gtag('event', 'page_view', { page_path: "/" + window.location.href.split('#')[1] });
  });
  }
});

The GA-appcode remained the same, didn't need to change/create a new one for this migration.

My app is find.knack.com, if you need the reference.

Nir

 

 

How to still implement this?

The 'script' tag has been blacklisted by Knack!

Hi Benjamin - I'm trying your method for including in an embedded app but not having much luck. Is there an updated way I should be trying to achieve this?

I too am confused as to where to paste Stevan's javascript code into my existing app code.

In example, below is my existing embed code.

< script type = "text/javascript" > app_id = "5a2605205fefa7542cff760c";
distribution_key = "dist_2"; < /script><script type="text/javascript
" src="
https: //loader.knack.com/5a2605205fefa7542cff760c/dist_2/knack.js"></script><div id="knack-dist_2">Loading...</div>

Where would I paste the code block?

Hi all, Can anyone help me with WHERE to paste this? I have tried a couple of times, but each time it kills my app (all the loads is the header, no menu, no scenes). 

This is what was in there when i started... 

// This will re-write any relative links into absolute links based on the current URL
$(document).on('knack-page-render.any', function(event, page) {
var url = window.location.href;
var baseUrl = url.split("#");
// Ignore this if the domain contains knackhq.com e.g. using hosted
if (url.indexOf("knackhq.com") < 1) {
$('a').not('[href^="http"],[href^="https"],[href^="mailto:"]').each(function() {
if (typeof $(this).attr("href") === "undefined") { } else {
if ($(this).attr("href").length > 1) {
$(this).attr('href', function(index, value) {
return baseUrl[0] + value;

});
}
}
});
}

})

Hi there

 

Many thanks for the reply.  I have been playing around with this for a while - I haven't got it working but I have discovered -

  • If I use google tag assist and view the page via the knack build it picks up the analytics UA code.
  • If I use google tag assist and view the 3rd party site it picks up only the 3rd party code and not X2 codes ie one for the 3rd party site and another from the embedded site.
  • If I print to the console the code runs when viewed on the 3rd party site ie javascript is actually running.
  • If I change analytics.js to analytics_debug.js and view via the builder I get all of the debug information however when viewed in the 3rd party site I get nothing.

I tried using the following code for the time being - 

$(document).on('knack-scene-render.any', function(event, scene) {

// GOOGLE ANALYTICS

// set variables to be used as the page URL and Title -
// you can customize these using jquery if you want to pull something different than I did.
var pagetitle = $('.kn-crumbtrail a:first-child').text()+' - '+$('.kn-scene h1').text();
var pageurl = window.location;
console.log('HELLO!');
// this part needs to all be on one line - be sure to replace your ga ID/code
$("#knack-body").append("<script>\n\n(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\nm=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n})(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\nga('create', 'UA-XXXXXXX-X', 'auto');\nga('send', 'pageview', {\n 'page':'"+pageurl+"',\n'title':'"+pagetitle+"'\n});\n\n</script>");

});

 

I checked and the 3rd party site is using analytics.js and not ga.js - apparently you can only have x1 ga.js per page.  The code from the 3rd party site is below.  I also tried setting up a simple site (with no analytics setup on the site) at wix.com and embedded my project (with analytics javascript present) into it and found I came across the same problem/behavior on it as the 3rd party site. 

<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-60358483-1', 'auto');
ga('send', 'pageview');

</script>

Im at a bit of a loss of what the issue is.  The analytics code does work when viewed via the builder but something is happening when embedded into another site.  Does anyone have any ideas of anything else to try/test?

 

David

   

I have it working on an embedded site. Here is the function I use outside of any handler:

function trackPageView(pagetitle, pageurl) {

if (! pagetitle) { var pagetitle = 'Inside DelVal'; }
if (! pageurl) { var pageurl = window.location.href; }

_gaq.push(['_setAccount', 'UA-XXXXX-1']);
_gaq.push(["_set", "title", pagetitle]);
_gaq.push(['_trackPageview', pageurl]);

}

And here is the call within a handler - sometimes it is generic and uses the defaults, and sometimes I override if I want it to be tracked a specific way.

trackPageView('Stories - Inside DelVal','http://www.delval.edu/inside');


var use_pagetitle = $("#inside_story_wrap .story_headline h2").text() + ' - Inside DelVal';
var use_pageurl = window.location.href;
trackPageView(use_pagetitle, use_pageurl);

One thing to note is that this makes the page not load correctly if you are viewing it on the knack site directly. I'm sure there is a way to check the condition and make it smarter, but it wasn't relevant for us as this is only ever viewed embedded. If I ever need to work in the raw knack interface I just comment out the gaq pushes temporarily.

I hope this helps!

Benjamin

Just wondering if anyone has this working on an embedded site?  I can see that the code is running in the console yet I don't get any data through.

If I access it through the URL given by knack the data comes through.  However if I access it using the embedded version using the javascript which embeddeds it into a 3rd party site no data comes through.  I checked the main website in which the knack database is embedded and the data is not captured through the main analytics account ie the account belonging to the 3rd party site.

I printed pagetitle and pageurl to the console and it looks good.  I have tried setting pageurl to the address where the knack database is embedded ie - www.mywebsite/client-login/ but this makes no difference.

Does anyone have any ideas?

Regards

David

Thanks for sharing, this is AWESOME! I have been planning the 2.0 version of my app and this gives me great information to make the next version much more user friendly.

Are there any javascript errors in the console? Do you see the call to analytics.js in the network pane of the inspector?

Hi Ben!

Yes I did change

$(document).on('knack-scene-render.any', function(event, scene) {
   
// GOOGLE ANALYTICS
 
// set variables to be used as the page URL and Title -
// you can customize these using jquery if you want to pull something different than I did.
var pagetitle = $('.kn-crumbtrail a:first-child').text()+' - '+$('.kn-scene h1').text();
var pageurl = window.location;
 
// this part needs to all be on one line - be sure to replace your ga ID/code
$("#knack-body").append("<script>\n\n(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\nm=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n})(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\nga('create', 'UA-80671667-1', 'auto');\nga('send', 'pageview', {\n 'page':'"+pageurl+"',\n'title':'"+pagetitle+"'\n});\n\n</script>");
   
});

 

Hi Usha, did you change the account code to your account? UA-XXXX-X is just a placeholder.

Hi Ben,

I added the code at the top of java script. I dont see the tracking in Google Analytics.

Anything else we need to do?

$(document).on('knack-scene-render.any', function(event, scene) {
   
// GOOGLE ANALYTICS
 
// set variables to be used as the page URL and Title -
// you can customize these using jquery if you want to pull something different than I did.
var pagetitle = $('.kn-crumbtrail a:first-child').text()+' - '+$('.kn-scene h1').text();
var pageurl = window.location;
 
// this part needs to all be on one line - be sure to replace your ga ID/code
$("#knack-body").append("<script>\n\n(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\nm=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n})(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\nga('create', 'UA-XXXX-X', 'auto');\nga('send', 'pageview', {\n 'page':'"+pageurl+"',\n'title':'"+pagetitle+"'\n});\n\n</script>");
   
});

 

Hi,

I am looking to do something similar with InfusionSoft Tracking Code. Would any of you know how to get individual page visitor data to be collected in InfusionSofts tracking system. The tracking code InfusionSoft gives only tracks the domain name and not the specific page when simply inserted into the Javascript of my Knack app. 

Is there a way to turn this GA code into something that can work with InfusionSoft code? 

Here the InfusionSoft script (modified for privacy):

<script type="text/javascript" src="https://texxx.infusionsoft.com/app/webTracking/getTrackingCode?trackingId=32d0407e437xx9d48cx454cd453d0caxb6"></script>

I think that given the way the application works (asynchronously), some kind of deliberate page-tracking call needs to happen, but the the way we recommended above shows it like any other standard HTML pages. I think events are great, but you have to navigate them differently and the same types of things are tracked. I prefer the page tracking version.

Attached are a couple views that I hope are helpful in addition to Stevan's. Let me know if you have any questions.

If you do implement something, I think it would be great to improve your page title options as now the actual page TITLE attribute doesn't change - this makes bookmarks less useful too. An enhancement there would feed directly into gA tracking. Maybe it could be concocted based on page hierarchy, page title, and for those detail views some combo of the page title as section and the primary display field for the object who's page you are viewing the detail.

For example (in reverse order):

{Object's primary display field} - {Page title of the parent listing} - {App name}:

The Beatles - Bands - History of Rock and Roll

Benjamin

and one more


Hi.

I hope that helps


Would anyone care to take a screenshot of how this renders in GA or fill me in on how it's working? I'd be interested in seeing if what's being collected is comparable to a regular HTML page (e.g. what the referrer is, is the hashtag being tracked as a distinct page, etc.).

We've been considering baking in an "Add your GA credentials" to track analytics (as well as mixpanel), but our initial thoughts were that we'd need to use custom events.