Tracking Discourse User ID's with Piwik

Piwik is an opensource alternative to Google Analytics which I've already blogged about before. It has, like Google Analytics, the ability to assign User ID's to your visitors, allowing you to track visitors across multiple devices. Discourse is a Rails app, forum for the next 30 years and what I plan on using for comments on this blog one day.

Combining Piwik and Discourse is pretty easy, but getting User ID tracking takes a tiny bit more config. Using the Discourse plugin API (like we have to for Piwik integration anyway) its just as easy as adding a couple of extra lines.

if (currentUser) {
    _paq.push(['setUserId', currentUser.id.toString()]);
}

This works out if there is a current user or not (currentUser is null if the user isn't logged in), and sets the User ID if they are. currentUser is already set for tracking the custom variable for their logged in status.

All up the content you want to put into the </head> section in Discourse looks like this:

<script type="text/discourse-plugin" version="0.2">
    api.onPageChange((url, title) => {
        if (_paq) {
            try {
                var currentUser = api.getCurrentUser();
                _paq.push(['setCustomVariable', 1, 'Forum status', !currentUser ? 'Anonymous' : 'LoggedIn user', 'visit']);
                if (currentUser) {
                    _paq.push(['setUserId', currentUser.id.toString()]);
                }
            } catch(e) {}
            _paq.push(["setCustomUrl", url]);
            _paq.push(["setDocumentTitle", title]);
            _paq.push(["trackPageView"]);
        }
    });
</script>

And the section you want to put into the </body> section looks like this:

<script type="text/javascript">
    var _paq = _paq || [];
    _paq.push(["enableLinkTracking"]);
    (function() {
        var u="//<replace me with your domain>/";
        _paq.push(["setTrackerUrl", u+"piwik.php"]);
        _paq.push(["setSiteId", <replace me with your site id>]);
        var d=document, g=d.createElement("script"), s=d.getElementsByTagName("script")[0]; g.type="text/javascript";
        g.defer=true; g.async=true; g.src=u+"piwik.js"; s.parentNode.insertBefore(g,s);
    })();
</script>

Just remember to set your domain and Site ID!

The currentUser variable should be set and evaluated within the </head> section of the code so that it runs on every page change. When placed in the </body> section it is only run upon first page load.

James Loh

I'm a Sysadmin for a web solutions company deploying clouds across the globe. I learn new things every day.

Byte by Byte

A weekly newsletter with 5 articles on tech from the past week. No spam, I promise!


or checkout our previous issues on our website!