Tracking your XPages app’s usage with Google Analytics

google-analytics-logoOne of the latest requirements from one of my customers was to be able to track the usage of their application. My first though was (obviously): let’s use Google Analytics for that.

The application is almost completely built as a Single Page Application (SPA) using one of my favorite ExtLib components: Dynamic Content. That means that for every change in content, only a part of the page is updated. That also means that the URL of the page is never updated. Those two things are important to remember.

Including Google Analytics in an application is simple: just include the script block that you can get after setting up an Analytics account. It looks similar to this:

<!-- Google Analytics -->
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
<!-- End Google Analytics -->

This script is standard, except for the line that says ga(‘create’, ‘UA-XXXXX-Y’, ‘auto’); In that line a unique identifier is set that identifies your own Google Analytics property.

When you change the content (facet) of a Dynamic Content component, it also automatically executes any JavaScript blocks that are part of the new content. That happens every time the content is shown again. Very convenient. So I just had to add the script block to all the content that I’m showing and wanted to track.

Now we’re left with only one problem. The Google Analytics script will automatically include the current URL and page title when registering a page view. But since the URL of the SPA is never updated, Google Analytics cannot register requests for different content. Luckily Analytics offers some additional features for Single Page Applications. By making an extra call to the ga() function (before the ga(‘send’, ‘pageview’) call is made) you can set (or fake) the current page’s URL and title:

ga('create', 'UA-XXXXX-Y', 'auto');
ga('set', { page : '/9F2', title : 'Title that identifies the dynamic content'});
ga('send', 'pageview');

The ‘page’ property identifies the ‘URL’. It doesn’t have to be a real URL, just use something unique that’s the same every time that specific dynamic content section is shown. The application features (amongst other things) a CMS where I’ve created documents for every unique page. I computed the ‘page’ property to be the document’s NoteID and the ‘title’ as the subject of the content.

Dropzone.js in XPages: it doesn’t get easier than this

After reading this question on StackOverflow by Daniele Grillo I decided to have a quick shot myself at integrating dropzone.js with XPages. Daniele already gave the solution to his issue himself (no bonus points for me today), but maybe others can benefit from a full example.

Source | Database


Dropzone.js is a JavaScript library that allows you to easily add a drop area to your web page where users can drop files. Files dropped there are automatically uploaded to the server. Integration is really simple: add the Dropzone JS file to your XPage (I’ve also included a Dropzone sample CSS file from their demo page for some styling), create an XPage and accompanying Java class to handle the uploaded files (see here), and write some JavaScript to enable and configure the dropzone:

<xp:scriptBlock id="scriptBlock1">
Dropzone.autoDiscover = false;

var myDropzone = new Dropzone(".dropzone", {
url: "uploadHandler.xsp",
paramName: "uploadedFile", //used to transfer the file
maxFilesize: 2

It doesn’t get easier than this!

Quick tip: updating URL hashes in XPages

I’m a big fan of the ExtLib Dynamic Content control. Use it in probably all my single-page XPage apps. Recently I was working on a page that had 2 nested Dynamic Content controls. I wanted to allow users to bookmark the page, including the state of both controls. I wanted to use a URL hash to do that. The useHash option apparently only supports one level, so I had to write a solution involving some client side JavaScript to update the URL hash. Here’s what I used to access the URL hash and update it:

//get the current hash value as a JavaScript object
var hash = dojo.queryToObject( dojo.hash() );

//add a parameter
hash['newParam'] = newValue;

//update the hash
dojo.hash( dojo.objectToQuery(hash) );