Google Analytics in R Shiny app blog hero banner with white text "R Shiny and Google Analytics" with Shiny and GA logos

R Shiny Google Analytics: How to Add GA to Shiny Apps


User adoption is an important metric for any application’s success. But measuring adoption hasn’t always been a priority for Shiny developers. We think it’s time to change this. So today we’ll show you how to add Google Analytics to R Shiny apps.

In this article, we’ll cover how to combine R Shiny and Google Analytics by adding a Google Analytics tracker to your Shiny application. We’ll also present a real Google Analytics example in Shiny from our recent, Forest Ranges application.

Is your Shiny app succesful? Explore these top 3 tools for monitoring user adoption in Shiny.

Note: Before setting up Google Analytics, you should consider the legal implications of improper configuration, data protection, and GDPR compliance. There is a complicated and evolving situation with legal action being taken on EU and US companies failing to adhere to GDPR (also known as DSGVO or RGPD).

Finding Google Analytics Tracking Code

First, you’ll need to register a Google Analytics account and log in.

Once inside, find the `Admin` button and click to enter the administration panel.

Google Analytics Admin button

From there you need to create a new property. Think of a property as an individual website (an application in our case) that you want to track.

It’s convenient to name the property after the app, hence the name “Forest App” below. But the naming convention can follow whatever you’re comfortable with.

Google Analytics new property view for Shiny app

Follow the instructions and you will be rewarded with a small chunk of HTML code that should look something like this:

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-ThisIsNotReal">
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-ThisIsNotReal');
</script>

Adding Google Analytics Tracking Code to Shiny App

There are many ways to include arbitrary HTML code into a Shiny app. But before we do that, notice that the suggested HTML code contains two script tags. Instead of adding this HTML as-is, you might find it beneficial to add two separate JS scripts.

Need a quick dashboard? Download a free Shiny dashboard template from Appsilon.

For the first one, we’ll add a URL, but for the second one, we’ll create a local JS script. If we decide to extend its functionality, this method will pay off for us in the end.

In this example, I created a gtag.js script in static/js folder:

$(() => {

  /* Default installation */

  window.dataLayer = window.dataLayer || [];
  function gtag() {
    dataLayer.push(arguments);
  };
  gtag('js', new Date());
  gtag('config', 'G-XC5N93969C');

});

Notice that everything we’ll write in the gtag.js script will be wrapped in $( () => {} );. This is the JQuery way of making sure that this code runs after the page has been loaded.

Now, this is how I add the scripts to the Shiny App:

# somewhere inside the UI
shiny::tags$head(
  shiny::tags$script(
    src = "https://www.googletagmanager.com/gtag/js?id=G-ThisIsNotReal",
    async = ""
  ),
  shiny::tags$script(
    src = "static/js/gtag.js"
  )
)

At this point, you should run the app and go to the Google Analytics page. Here, you’ll want to check if the events are being recorded in real-time (the lag here should not exceed 1-2 minutes).

Extend Google Analytics Tracker with Custom Events

That was fairly straightforward; nothing too complex going on. But there would be no reason to write this article if it was only about adding a GA tracker to the app.

The interesting and most important part is being able to track certain events that we’re interested in. For instance, in our Forest Ranges app, users can select a tree species to check its future conditions. What we would like to know, is what species draw the most attention. 

New to Shiny? See what’s possible with Appsilon’s Shiny demos

To do that, we obviously need to know which specimen was selected.

After this point, things may differ from app to app, because everything depends on what you choose to track and how you choose to do it. 

Following our example, we have a dropdown input with tree species options:

shiny.semantic::dropdown_input(
  input_id = ns("tree_specie"),
  choices = trees_human,
  choices_value = trees_abr,
  default_text = "Tree species",
  value = trees_abr[1]
)

Here, ‘trees_human is a character vector of “human-readable” tree names (e.g. “European silver fir”), and ‘trees_abr’ is a character vector of corresponding scientific abbreviations (e.g. “abal” form “Abies Alba”)

In order for the GA tracker to know which species the user selected, we need to do three things:

  • Find the required element in the HTML structure of the app
  • Add a proper event listener to this element
  • Send the event’s data to GA with a function provided by Google

Let’s jump into it!

Finding the element

To “find” the element in the HTML structure of the app, recall that shiny.semantic::dropdown_input generates a dropdown menu where each element has a class item. Because this is the only dropdown menu in our app, we can refer to these elements with a simple css selector .item.

Finding this element jQuery style looks like this:

$('.item')

This selector will find every element of class item on the page. It’s pretty useful because we won’t need to iterate over an array of elements to add event listeners. However, because our selector finds all elements, we’ll need to use the .currentTarget property of the event inside a callback function to make sure we refer only to the element that emitted an event.

Speaking of the event, let’s add an event listener now.

Adding an event listener

We want something to happen when a user clicks on the item of interest:

$('.item').on('click', (event) => {
  const selectedSpecie = $(event.currentTarget).data().value;
  console.log(selectedSpecie);
});

This obscure jQuery code finds an element stored in the currentTarget property of the event object (the event is passed as an argument to a callback function), executes data() method on it, and extracts the value property. This value should contain an actual tree abbreviation.

To check that everything is done correctly, run the app and open it in the browser. Then, open developer tools and navigate to the console. You should now see species abbreviations in the console every time we select a tree.

This is neat, but we want to send this data to Google Analytics, not to the console. So let’s learn how, next.

Sending data to Google Analytics

To send this data to GA, we will use the gtag function that Google has already provided. According to the official documentation, we can specify an event name and pass some data to it. We can now replace console.log with gtag:

$('.item').on('click', (event) => {
  const selectedSpecie = $(event.currentTarget).data().value;
  gtag('event', 'specie_selected', {
    selected_specie: selectedSpecie
  });
});

Check out custom events in Google Analytics for Shiny

Now we’re finally able to take a look at the results of our efforts! Go to the Google Analytics page, navigate to the Reports section, and select Realtime. Scroll down until you find a panel with Event count by Event name. This is the place where we will track our event.

Google Analytics realtime report for Shiny app

If you were able to follow all the steps in this blog post, you will ultimately see something like this. Congratulations!

If you were able to follow all the steps in this blog post, you will ultimately see something like this.

Google Analytics realtime summary of Shiny app in use

Congratulations! You’ve now successfully implemented Google Analytics in a Shiny app.

Why use Google Analytics in a Shiny App?

Shiny user metrics with Google Analytics

I know it seems out of place to ask this after we’ve gone through the trouble. But it’s important to emphasize the ‘why’ of monitoring user metrics in Shiny.

First, you’ve worked hard on your application and it’s out there. Sitting on the world wide web or helping your colleagues solve problems in their team. But is it really solving ‘all’ of their needs?

Google Analytics makes monitoring user adoption of your application easy and straightforward. It helps answer questions like:

  • How many users are there?
  • How often are they using it?
  • And how long are they using it for?

These are all important pieces of the informational pie that construct your overall user adoption.

Is your UX holding you back? Follow these 7 steps to design dashboards that people will love.

Shiny project benefits

Adding custom events, allows you to not only monitor session counts but also gain additional insights from your users’ behavior and interests.

What if you spent a lot of time and effort on developing a certain feature (say this dropdown menu with tree species), but it turns out that the users don’t even need it?

By discovering what users do and do not use, you can now adjust the development process and de-prioritize features. Saving your team time and resources. 

Concluding Google Analytics in R Shiny apps

Of course, this was a simple example, but the real applications of this approach go far beyond what we showed. You can track any number of different events, and send different data parameters to Google Analytics to achieve your goals.

Let us know how you use GA in your Shiny app in the comments section below. 

Want to learn more about how to use tools like Hotjar, shiny.stats, and shinylogs? Explore the Appsilon blog and consider subscribing to the Shiny Weekly newsletter – where we collect the latest Shiny news from the R community. 

And of course, if you need help with getting your enterprise Shiny app from PoC to production-ready, reach out to Appsilon. We’ll help you scale, design, and succeed with Shiny.