How to track video plays in Ghost with Plausible

Open MacBook with multiple hands interacting with keyboard and mouse.
"Wow, look at these analytics," they said.

Plausible comes with the perfect number of metrics out of the box, but if you need a little more, you can track custom goals, such as outbound clicks or file downloads, by adjusting the script embed and including those goals within your site settings.

Now, for additional custom event goals, you can use the global plausible function to push an event, such as Video: Play, with a couple properties, such as page and video, which is what we’re going to do.

Add Plausible to Ghost

Take a look at how to integrate Plausible with Ghost and follow those instructions.

You should end up with a line in Ghost under Settings > Code injection > Site Header that looks something like this:

<script defer data-domain="blog.example.org" src="https://plausible.io/js/script.file-downloads.hash.outbound-links.js"></script>

Be sure to swap blog.example.org with the URL of your Ghost blog.

The example above will also tracks file downloads, hashes, and outbound links, which is apparent by the file-downloads, hash, and outbound-links extensions in the src attribute.

Still on Settings > Code injection, scroll down to Site Footer and paste the script below into the field:

<script>
  // Track video plays in Ghost with Plausible
  document.addEventListener("DOMContentLoaded", trackVideoPlaysWithPlausible);
  function trackVideoPlaysWithPlausible() {
    // If Plausible does not exist, stop
    if (typeof plausible !== "function") {
      return;
    }
    // If there are no videos on page, stop
    const videos = document.querySelectorAll("video");
    if (videos.length === 0) {
      return;
    }
    // Listen for when video starts to play
    videos.forEach((video) =>
      video.addEventListener("play", trackVideoPlayWithPlausible)
    );
  }
  function trackVideoPlayWithPlausible(event) {
    // If video is not at beginning, stop
    if (event.target.currentTime !== 0) {
      return;
    }
    const pagePath = new URL(event.target.baseURI).pathname;
    const videoPath = new URL(event.target.currentSrc).pathname.replace(
      "/content/media",
      ""
    );
    // Track video play with Plausible
    plausible("Video: Play", { props: { page: pagePath, video: videoPath } });
  }
</script>

On every page, the script checks to ensure Plausible is present, because if not, there is no point in executing the rest of the script.

Then the script grabs all of the videos on your page, whether they were added using the built-in Video component, or manually added using the HTML component and a <video> element.

A listener is assigned to each video’s play button, and it does what you think it does: waits and listens for a visitor to play a video.

I don’t want to log additional events in Plausible every time the video is paused and resumed, so the script only logs a play when the video is first played, in other words, when the current time of the video is exactly zero.

Should a visitor go back to the beginning of the video at any point, it will log that as another play, but later you can filter those out by looking at only the unique plays.

Within the event, there is some useful information, such as the current URL the visitor is on and the URL of the video. We take pieces of both and save them as properties within the event that gets sent to Plausible.

Add custom goal to Plausible

Last, we need to make Plausible aware that there is a new goal conversion to be added to the dashboard.

So on your Dashboard, click on the cog wheel of your site, and then Goals in the left menu.

Next, click on the Add Goal button, select Custom event as the goal trigger, and enter Video: Play — exactly like this (unless you changed it in the script).

Test video play tracking

Open a page on your Ghost blog with an embedded video, and press play on it.

Now go to the stats of that site in Plausible, and in the timeframe dropdown select Realtime, or press R on your keyboard.

Scroll to the bottom where it says Goal Conversations, and you should see one entry called Video: Play.

If you click on that, you can see a breakdown of which page the video was played on by clicking on page, or which video was played by clicking on video.

I followed the same naming convention as Plausible’s Outbound Link: Click, because it’s possible some of you might want to extend this further to record when a video was stopped, half way watched, finished, etc, and this could be accomplished with naming goals like Video: Stop, Video: Watch 50%, Video: Finish, and so forth.

Hopefully this helps, and let me know if you have any questions.

Featured image by John Schnobrich.