Skip to content

πŸ” Track user interactions with Mixpanel in Shiny apps or R scripts

License

Notifications You must be signed in to change notification settings

daattali/shinymixpanel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

34 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

shinymixpanel

πŸ” Track user interactions with Mixpanel in Shiny apps or R scripts

by Dean Attali

R Build Status CRAN version


Mixpanel is an analytics platform allowing you to track user interactions (called events) on your web apps. The {shinymixpanel} package provides an easy way to track events to Mixpanel from R. For Shiny developers, this means you can track events in Shiny apps, such as when a user clicks on a button, types into an input, selects a tab, or any other action you want to track.

All events data for all users can be viewed on Mixpanel's dashboard.

Need Shiny help? I'm available for consulting.
If you find {shinymixpanel} useful, please consider supporting my work! ❀

This package is part of a larger ecosystem of packages with a shared vision: solving common Shiny issues and improving Shiny apps with minimal effort, minimal code changes, and clear documentation. Other packages for your Shiny apps:

Package Description Demo
shinyjs πŸ’‘ Easily improve the user experience of your Shiny apps in seconds πŸ”—
shinyalert πŸ—―οΈ Easily create pretty popup messages (modals) in Shiny πŸ”—
shinyscreenshot πŸ“· Capture screenshots of entire pages or parts of pages in Shiny apps πŸ”—
timevis πŸ“… Create interactive timeline visualizations in R πŸ”—
shinycssloaders βŒ› Add loading animations to a Shiny output while it's recalculating πŸ”—
colourpicker 🎨 A colour picker tool for Shiny and for selecting colours in plots πŸ”—
shinybrowser 🌐 Find out information about a user's web browser in Shiny apps πŸ”—
shinydisconnect πŸ”Œ Show a nice message when a Shiny app disconnects or errors πŸ”—
shinytip πŸ’¬ Simple flexible tooltips for Shiny apps WIP
shinyforms πŸ“ Easily create questionnaire-type forms with Shiny WIP

Table of contents

Sponsors πŸ†

Become a sponsor for {shinymixpanel} and unlock special rewards!

Installation

For most users: To install the stable CRAN version:

install.packages("shinymixpanel")

For advanced users: To install the latest development version from GitHub:

install.packages("remotes")
remotes::install_github("daattali/shinymixpanel")

One-time setup

To use {shinymixpanel}, you must first have a Mixpanel account (you can sign up for free), create a project, and obtain the Project Token from the Project Settings page. Keep this project token handy as it's required in order to use {shinymixpanel}.

How to use

To use {shinymixpanel} in a shiny app, you must first call mp_init() anywhere in the app's UI. Then you can call mp_track() in the server to track any user interaction. The first argument to mp_track() is the event name, and you can optionally also pass a list of additional properties that will get recorded with this event. Below is a simple example:

library(shiny)
library(shinymixpanel)

mixpanel_token <- "PROJECT_TOKEN_HERE"

ui <- fluidPage(
  mp_init(mixpanel_token),
  textInput("name", "name", ""),
  actionButton("btn", "btn")
)

server <- function(input, output, session) {
  mp_track("app started")
  
  observeEvent(input$btn, {
    mp_track(
      "clicked button",
      list(num = btn, name = input$name)
    )
  })
}

shinyApp(ui, server)

Project token

A project token must either be passed to mp_init() as the token parameter, or you can set the SHINYMIXPANEL_TOKEN environment variable.

Identifying users

All events tracked to Mixpanel from the same browser will be associated with the same user ID. By default, Mixpanel will use a random ID for each user. If you want to set your own user ID for the current user, you can either provide the user ID to mp_init() via the userid parameter, or by calling mp_userid() in the server.

Once a user ID is set (whether randomly or explicitly), all subsequent mp_track() calls in the same browser will be associated with that user, until a new user ID is set.

Event properties

Any event that gets tracked to Mixpanel can include additional information, called Properties. This is usually either extra information about the event itself, or about the user. Mixpanel automatically attaches many properties to events, and you can also send additional custom properties. For example:

mp_track("submit form", properties = list(name = input$name, form_version = 2))

Default properties

If there are any properties that you want to attach to all subsequent events, you can define a set of default properties either using the default_properties parameter of mp_init(), or by calling mp_default_props() at any time in the server. Below is an example of how default properties work:

ui <- fluidPage(
  mp_init(mixpanel_token, default_properties = list(a = 1, b = 1))
)

server <- function(input, output, session) {
  mp_track("one")
  mp_default_props(list(a = 2, c = 2))
  mp_track("two")
  mp_track("three", list(a = 3, d = 3))
}

shinyApp(ui, server)

The app above makes three event tracking calls, and sets default properties twice: first in the initialization (mp_init()), and later with a server call (mp_default_props()). The following screenshot shows the results that are recorded by Mixpanel (it might be easier to read from bottom to top since the last event is on top):

Default properties

As you can see, any time that default properties are set, it overwrites any previous default properties. Additionally, if a property name is duplicated in the default properties and in the mp_track() call, the property in mp_track() takes precedence.

Default JavaScript properties

There may be some information you'd like to track that's only accessible from the client side (from the browser, not from R). To retrieve properties from the client and attach them to any mp_track() call, you define the properties in the default_properties_js parameter of mp_init(). The difference between default_properties_js and the regular default properties is that default_properties_js takes JavaScript code, and it's computed as soon as Mixpanel is initialized.

For example, using the following call:

mp_init(mixpanel_token, default_properties_js = list(
  size = "screen.width", ua = "navigator.userAgent", domain = "location.hostname"))

Will result in 3 variables getting computed right away in the user's browser: "size" (the screen's width), "ua" (the browser's user-agent string), and "domain" (the current webpage's domain). These 3 properties will be sent along with any mp_track() calls.

Client-side vs server-side tracking

When calling mp_track() inside a Shiny app, events data can be sent to Mixpanel in one of two ways: using client-side or server-side tracking.

Client-side tracking is done via the user's browser (with Javascript). This is generally the preferred way to use Mixpanel, since Mixpanel automatically collects some additional information from the web browser. However, some users may disable tracking in their browser (for example using an ad blocker), and for these users it's not possible to perform client-side tracking.

With server-side tracking, {shinymixpanel} will send events to Mixpanel via R API calls. The benefit of server-side tracking is that it's unaffected by ad blockers. However, when using server-side tracking, Mixpanel does not automatically collect the same attributes that it does in client-side. To compensate for that, {shinymixpanel} will try to detect some browser data and send it along with any event: user's operating system, browser name, screen size, and current URL (these are a subset of the attributes that client-side tracking detects).

The parameters track_client and track_server of mp_init() are both set to TRUE by default, and they can be used to disable one of the two tracking methods: - If both are set to FALSE, then Mixpanel tracking is essentially turned off - If only track_client is TRUE, then {shinymixpanel} will only attempt to use client-side tracking. Note that this means that if the user has an ad blocker, then no events will be tracked. - If only track_server is TRUE, then all event tracking will be done with server-side tracking. - If both are TRUE, then {shinymixpanel} will prioritize trying to use client-side tracking. If an ad blocker is present, then it will automatically switch to using server-side tracking.

Using {shinymixpanel} during development/testing

While developing or testing your Shiny app, you may not want to have Mixpanel tracking turned on. You have two options:

  1. Mixpanel tracking can be temporarily disabled by setting the SHINYMIXPANEL_DISABLE environment variable to "1". When this environment variable is set, any calls to mp_init() and mp_track() are ignored.

  2. You may prefer to still use Mixpanel, but send the data to a different "test" project rather than the real production Mixpanel project. This is supported via the test_token and test_domains parameters of mp_init().

    When both of these parameters are provided, if the Shiny app is in a domain that's listed in the test_domains list, then data will be sent to the test_token project instead. Note that the domains in test_domains are assumed to be suffixes. This means that if you provide "example.com" as a test domain, then any user on example.com or test.example.com will use the test project.

    By default, test_domains is set to 127.0.0.1 and localhost, which means that if you provide a test_token, that project will receive all data while you're running the Shiny app locally.

Outside of Shiny apps

Even though {shinymixpanel} was mainly developed with Shiny apps in mind, it can also be used in any R code. When used outside of Shiny, server-side tracking is always used.

To use {shinymixpanel} in a non-Shiny context, you don't need to call mp_init(). Rather, you can just call mp_track() at any time. A token must be provided, either via the token argument or by setting the SHINYMIXPANEL_TOKEN environment variable. If you call mp_userid() or mp_default_props(), then all subsequent event trackings will use the corresponding user ID and properties.

Here is an example of using {shinymixpanel} outside of Shiny:

Sys.setenv("SHINYMIXPANEL_TOKEN" = YOUR_PROJECT_TOKEN)
mp_userid("abcd1234")
mp_default_props(list("foo" = "bar", "text" = "hello"))
mp_track("greet", list(name = "dean"))

The above code will send a "greet" event to Mixpanel, associate it to user "abcd1234", along with properties {"foo" = "bar", "text" = "hello", "name" = "dean"}.