Why do UI analytics libraries separate pageview events from other events? - javascript

Most UI analytics libraries (e.g googleAnalytics) seem to differentiate between tracking pageViews and other events.
For example, this is from the Google Analytics page.
The Google Analytics client side browser plugin works with these
analytic api methods:
analytics.page - Sends page views into Google Analytics
analytics.track - Track custom events and send to Google Analytics
Why can’t a pageView be considered just another event such as a click, a loginEvent, etc?
This would eliminate the need for the analytics.page method.

There's no real technical need to separate them since the payload of an event is of the same structure. Even if you look at the network request sent, you're likely to notice that page/screenview events are exactly the same as normal events, maybe lacking a few dimensions if anything but that's it.
It's mostly due to how the business sees and analyses these. The core reason for it is that events are seen to be fired in a context of a page. It's very common for the business to analyze what pages the events have fired on. Even though you can normally override the page/screen dimension of an event, a tracking library will tend to inject the last page/screen that was sent with the page/screen track method.
So it looks something like this with default tracking:
Event 0: page null
Page A
Event 1: page A
Event 2: page A
Event 3: page A
Page B
Event 4: page B
Event 5: page B
Page C
Page D
Event 6: page D
Now if Pages and Events would be in the same method, the whole page dimension inheritance would have to be implemented differently.
Moreover, there are small technical details like the method can throw an error or a warning when the client attempts to send a pageview/screenview event with no page/screen dimension set. Or issue warnings when sending repeated page events with the same dimension as the previous one.

Related

Content scripts sendMessage receives null back if options page has onMessage listener

I have a web-extension adddon that's comprised of my Background Script, Content Scripts and an options_ui page. The Content Scripts message the Background script using browser.runtime.sendMessage and expect a response back from that with the information it needs, quite often. The Background script listens with browser.runtime.onMessage.addListener.
The options page preforms an action that can take between 1 to 5 minutes, so it tells the Background script to do it, and the background script response with a progress update every 1% through browser.tabs.sendMessage. The options pager registers a browser.runtime.onMessage listener to listen for this update.
The problem is that as long as the options page is open, the content scripts are unable to receive any responses from the background script. Any response it gets is always null. The Background script definitely receives the request from the content script, and response with the correct information, but the script doesn't receive the response. Even if I have multiple content-scripts open, and if I register a browser.runtime.onMessage listener on each of them the way I do for the options page, it work as long as the options page is closed.
I'm not really sure what's going on here or what the next steps are. I know that the documentation for runtime.onMessage say that only one listener may respond if two are registered on the same document, but unless the options page counts as the same document as the background script, that doesn't really make sense. I know it's not a Firefox only issue, as the exact same behavior occurs in Chrome as well.
I couldn't find any documentation which explains or documents that Option page is also part of the pages
Note: If multiple pages are listening for onMessage events, only the first to call sendResponse() for a particular event will succeed in sending the response. All other responses to that event will be ignored.
But as mentioned in the documentation
https://developer.chrome.com/extensions/messaging#connect
Long-lived connections
Sometimes it's useful to have a conversation that lasts longer than a single request and response. In this case, you can open a long-lived channel from your content script to an extension page , or vice versa, using runtime.connect or tabs.connect, respectively . The channel can optionally have a name, allowing you to distinguish between different types of connections.
You should be using connect for your use-case

JAVASCRIPT: How to track and log user events on a website(like Google Analytics)

I want to create an application like Google Analytics. I have taken Analytics.js code from Segment(open source analytics application Segment.com) which contains all the in-built functions to track User Events. I have also added async code to load Analytics.js into my website. Now I am Stuck. How can I collect those Event details occurring on my website and send it to my own server?
I assume your are collecting pageview data but you are stuck on event data, right? Try using event listeners in order to be able to collect whatever action takes place on the site.
For example, if you want to register when someone is using a textarea:
textarea.addEventListener(
'keyup',
sendInfoToAnalytics(),
true
);

any reason not to send data with events as opposed to custom dimensions?

It seems that Custom Dimensions are the new way to send custom data from a website to GA. I'm new to GA but my manager has used GA in the past and I'm guessing this was before the CD structure existed in GA. Do you know when the CD structure was introduced in GA?
He has sent custom data to GA in the past using events. This seems like a viable way of sending data and another manager at my company had referred to this approach last week so it seems like maybe this was a standard approach before GA introduced CD's. So given the following request:
var myRequest =
{
UserID:1234,
SelectedReportType:1,
};
What are the tradeoffs between sending this request data to GA as a CD like this:
ga('set', 'dimension1', JSON.stringify(myRequest));
ga('send', 'pageview');
Vs sending this request data to GA as event data like this:
ga('send', 'event', {
'eventCategory':'MyWidgetUserSelection',
'eventAction':JSON.stringify(myRequest)
});
?
Custom dimension where introduced with the switch from "classic" Analytics to Universal Analytics (IIRC that was in 2012), where they replaced (more or less) custom variables.
"Classic Analytics" (not an official name, AFAIK the previous GA version did not have a name other than GA) was a pretty messy thing that pretty much used the technology of the original Urchin tracker (Urchin was a web tracking company Google acquired in the early 2000s and rebranded their product as Google Analytics). Classic analytics pre-computed a lot of data on the client side (using up to five different cookies), including traffic source attribution, before it made a rather convoluted image request to the Google server.
In contrast Universal Analytics was designed on top of a clean protocol, the measurement protocol. It is "universal" because any device or program that can make a http request can now send data to Google Analytics. Universal Analytics does not compute any data on the client side, the data is processed only after it arrives at the Google tracking servers.
"Classic" Analytics had up to five custom variables in different scopes (hit, session,user)). They were displayed in the "custom" menu item of the GA interface (which is still there, but is now useless unless you have old data that was collected with classic analytics). Five variables posed a pretty tight limit, plus it was not always easy to understand how exactly they were supposed to work. So people developed a habit of storing additional data not in custom variables, but in events.
Universal Analytics in the free (commercial) version offers 20 (200) custom dimensions in four different scopes, to wit hit, session, user and product (and an additional 20 (200) custom metrics, although very few people seem to use custom metrics). "Hit scope" means you can add a dimension to every single interaction. "Session scope" only retains the last value for a session. "User scope" is primarily for values that are set once per recurring user (i.e. a user turns into a customer). With the product scope you can add additional properties to the products in an ecommerce-transaction (or production impression etc. if you are using enhanced e-commerce tracking).
Conceptually event tracking and custom dimensions are not remotely comparable. A dimension is a property that is connected to an interaction hit (or a collection of interaction hits like a session or a user) and allows to break down metrics into indivual rows. For example the "pageview" metric can be broken down by page path or page title, which are automatically collected. You might add a custom dimension "page category" and you can break down your total number of pageviews into separate rows that show the number of pageviews per category.
Custom dimensions do not have their own report; you can select them as secondary dimension in a standard report, or create custom reports based on them. You can also use custom dimensions to segment sessions or users by the respective values for the dimension.
Events on the other hand are interactions in their own right, with their own set of default metrics and dimensions (in fact you can amend events with their own custom dimensions). Proper usage of events is to track interactions that not load a new page (or do not change the page content enough to warrant a pageview call).
You can use events for segmentation (i.e. "show only sessions where the user had a certain event"), but you cannot break down pageview metrics by event properties. That is actually the main difference.
A more practical concern is that events, unlike custom dimensions, count toward you data collection limit (the free version of Google Analytics allows for 10 mio hits per month only, although the limit is so far not strictly enforced). Since custom dimension are not interactions by themselved they do not count towards the quota.

Analytics on a bootstrap modal with pageview and time related metrics

I have a page (let's name it the overview page) with a lot of images of projects that on a click open a bootstrap (v3) modal with more info about that project. Each project also has its own page (single page).
I'd like to track pageviews for the projects when a user opens the modal with Google (universal) analytics. Now I'm planning on doing this by adding the following code to each link on the overview page:
onClick="ga('send','pageview','/url-to-project-page');"
I expect this works fine since I've seen this method in other posts regarding tracking pageviews on AJAX calls.
But I'm wondering how this affects time related metrics like average time on page, since analytics can't know when the modal is closed (the same as leaving a single page).
Does anyone know if the metrics will be comparable to a normal single page view, or will some parts of the metrics (I'm guessing time related metics) be off because analytics isn't able to track them?
If I understand it right, you want to track the opening of the modal as a pageview of the projects page. This can be accomplished with what you just said, but using a direct URL would be unwise in my humble opinion. You would be better off using a virtual URL(VURL) instead. Read more about virtual URLs here.
It is also available in Universal Analytics(UA) (analytics.js) and when you are sending such a pageview as you mentioned above, you are forcing GA to report a pageview of the specified URL. Your code,
(1) ga('send','pageview','/url-to-project-page'); will work.
In UA, ga('send','pageview'); is used to send the current pageview. If you need to send a virtual pageview (or a pageview which has not happened but you want to be recorded), you can also send it as:
(2)
ga('send', 'pageview', {
'page': '/url-to-project-page'
});
or as
(3)
ga('set', 'page', '/url-to-project-page');
ga('send', 'pageview');
or as
(4)
ga('send', {
'hitType': 'pageview',
'page': '/url-to-project-page'
});
The implementations 1, 2 and 4 are same, but 3 is different.
You can read more about the implementations here, here and here.
This would affect your pageviews count (you will see an increase), but would not increase your visits (as no user can 'land' on a virtual page (unless you make them do so)). This will impact your bounce rates, but it will not be 'off' in the sense that if they view your project in a modal, it means they have interacted with your site hence they should not be marked as a bounce, and this is what happens when you send a virtual pageview.
Though what you wanted to do was correct, your implementation suffers from not being able to differentiate modal views from actual project page views. I would overcome this by organising the VURL structure in a way that it makes sense and is semantic. As an example, instead of sending a VURL which corresponds directly to your project single page url, I would send it like: ga('send','pageview','/virtual/modal/url-to-project-page');
This way, you can filter out the VURLs by adding an exclude filter for /virtual from pageviews so that virtual pageviews are not shown. Also, you can view total pageviews for project pages by using /url-to-project-page. Also, you can view all virtual pageviews resulting from the opening of modals by using /virtual/modal.
Time on Page and Pageviews/Visit and such metrics will change, but it depends on how you see it, whether as an error or improvement in accuracy. Time on Page is recorded for the virtual pageviews until the user navigates to a new page, or a request to report a VURL is sent, or until the session is closed (whichever happens first).
Hope that helps! :)

Javascript Detect All Images (Including Asynchronous)

Is there a way in javascript to detect all images in a document, including those that may be loaded asynchronously (and maybe after the DOM is ready)?
I'm looking to create a function that can detect if Google Analytics has been loaded by searching through the DOM looking for "__utm.gif". document.images doesn't seem to hold this image as it's loaded asynchronously and not displayed.
Is there any reason you don't want to implement GA detection by checking for the HTTP request to which this gif (i.e., __utm.gif) is appended?
It's this request that's responsible for sending all of the data GA collects to the GA servers, and of course the request is made every time the page is requested or an event is fired on that page.
Again, this request has a very distinct signature--it always begins like this:
http://www.google-analytics.com/__utm.gif?utmwv=4&utmn
Here's a complete example from the GA Site.
If you're looking to detect GA, you can simply test for window._gat and window._gaq.

Categories

Resources