Misc Blog

Add analytics to your Phoenix Live View app

It can be difficult to know where to put analytics tracking code on your Phoenix Live View web application. Snippets like Google Analytics don't work with Live Views due to the lack of page refreshes.

Name
Matt
Twitter
@mplatts

1 year ago

Recently I was trying to add Go Squared (a Google Analytics competitor) to our Phoenix Live View application and realised it wasn’t going to work due to the lack of page reloading.

Usually, the analytics snippet does something like this:

ga('send', 'pageview');

Live views don’t make a normal HTTP request (they use websockets) and thus when a user goes from one live route to another the analytics javascript snippet doesn’t run.

Instead, we need to hook into the live view lifecycle. Create a new file next to your app.js file: analytics.js.

In your app.js:

import "phoenix_html";
import { Socket } from "phoenix";
import { LiveSocket } from "phoenix_live_view";
import topbar from "../vendor/topbar";
import Hooks from "./hooks";
import "./analytics.js"; // <--- Add this

Then in you analytics.js:

function trackPageView() {
   yourAnalytics.page();
}

window.addEventListener("phx:page-loading-stop", () => {
  // When someone goes to a different live view page:
  trackPageView();
});

// Run for non-live views
trackPageView();

This mostly works, except I found when doing a live redirect the trackPageView() function was running twice! I have no idea if it was something to do with my app or a live view issue. To fix, I put the last page into a variable, and be sure not to double up with the page views:

window.lastPage = "";

function trackPageView() {
  let pageNotYetTracked = lastPage != window.location.pathname;

  if (pageNotYetTracked) {
    yourAnalytics.page();
  }
   window.lastPage = window.location.pathname;
}

window.addEventListener("phx:page-loading-stop", () => {
  // When someone goes to a different live view page:
  trackPageView();
});

// Run for non-live views
trackPageView();

Now it only gets called once per page!

The end

More posts