How to add Google Analytics or JS code in a Streamlit app?

Itā€™s not a technical problem so much as it is a question of which features to develop before other ones.

Currently weā€™re working on a couple of performance boosting improvements especially to do with serialization of large datasets, making caching more reliable, and polishing a lot of existing features. Itā€™s all about making good on the promise of being able to do beautiful things with data, first and foremost.

Meanwhile, I personally spent most of December gathering user stories as per desires for the use of HTML and Javascript in Streamlit. We definitely get that these limitations are preventing certain types of uses. And this month we have a couple of PRs in the making in response to those user stories.

Thanks for all your continued bug reports and feature suggestions. We read them all. :heart:

10 Likes

Thanks a million @nthmost for creating the github issue. I appreciate it. I hope we will see this feature added soon. This will be an amazing and much-needed addition to Streamlit. Thanks again for creating such a great framework. :+1:

2 Likes

It would be really awesome to have thisā€¦ really would like to track the users on the site I deployed using streamlit!

7 Likes

Any updates on this request?

2 Likes

Not answers the question on using javascript code from google analytics, but allows measuring traffic by using a tracking pixel code through GA: https://htmlemail.io/blog/google-analytics-email-tracking

2 Likes

I wanted to set up Google Analytics for my Streamlit app. What worked for me was changing the static index.html inside the streamlit package (os.path.dirname(st.__file__)) . Just below the <head> you can add your javascript code for the analytics. This definitely isnā€™t good practice but I needed analytics set up urgently.

Note: I have only one app deployed, so this works great. If you have multiple apps, this might create some problems. In that case, create a different virtual environment for each of them and repeat the same.

10 Likes

Your suggestion works for me. My site at https://covid19.aipert.org now has GA. Many thanks!

4 Likes

Would like to share what worked for me. I made a flask website and put the streamlit app inside an iframe on one of the pages (the ā€¦/ai_app page). This way you have direct access to the head tag and so can easily insert the adsense or analytics code. In case youā€™d like to see how it turned out, the site is at http://deepretouch.com (adsense says itā€™d take ā€œa few daysā€ to show, but analytics fully works right now).

4 Likes

This looks a very good approach. I tried to do it similar way, but while uploading image in the streamlit app from iframe it is giving 403 error. My streamlit app and flask website is running seperately on my lock desktop. Looks like streamlit server is not allowing flask server to upload the file. Am I doing things correctly. Can you please advise and guide me. Thanks !

I remember having a similar problem when uploading big images. Maybe try with a small (<30KB) one. Iā€™m running the flask site with gunicorn and nginx. To allow larger images I had to modify the nginx configuration file.
Also, Iā€™m not using the latest version of streamlit. I recall that one of the changes in more recent versions was that the uploader now requires to explicitly specify the decoding.

@suryatejreddy and @Quoc_Tran is this done through the terminal? I tried going to the path of the repo of my app and tried ls -a. There was not a (st. file) in the directory? Can you please guide me how to find it?

Thanks!

This is done through the terminal via a python session. For me:

import os
import streamlit as st
(os.path.dirname(st.file))
ā€˜anaconda3/envs/st65/lib/python3.7/site-packages/streamlitā€™ If you still need help, we can chat through LinkedIn

suryatejreddy thanks for suggestion, worked great for me.

since I deploy automatically I needed to change the file using code and came up with the following lines in the app code that checks whether there is GA script in the index.html and if not inserts it from the ā€˜codeā€™ variable.

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

a=os.path.dirname(st.__file__)+'/static/index.html'
with open(a, 'r') as f:
    data=f.read()
    if len(re.findall('UA-', data))==0:
        with open(a, 'w') as ff:
            newdata=re.sub('<head>','<head>'+code,data)
            ff.write(newdata)
9 Likes

Hi there, maybe this could be useful streamlit-analytics 0.2.1

1 Like

This wrecked my serverā€¦ Cannot go back the tags are permanently in the static files now, how do we reset them ? Thanks

Edit : For those looking for a way, I resolved it by recreating the conda environment I used for the script. Apparently the static files are stored in it. If itā€™s the base env, youā€™ll need to create a new one.
The right way would be to fix the static index.html but I messed it and got a blank file ^^

1 Like

Has anyone tried to iframe their app to a standalone html page?
You could then add google analytics to the html page containing the iframe.
Just an idea that could work. I myself have not tried it.

Iā€™m really struggling with this, and have seen many different implementations of the Google Analytics code. It seems straightforward until I actually try it.

Iā€™m currently trying this at the end of my .py file:

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

Iā€™ve seen an example that has:

components.html(
        f"""

ā€¦in the HTML method explanation halfway down the official announcement of Streamlit components page. I donā€™t know what that extra 'f" is for, but I tried to add it and didnā€™t fix anything.

I tried three single quotes ''' vs. three double quotes """ to set off the code block. No change.
I tried indenting the code inside the components.html command. No change.
I visit my Google Analytics site and get nothing in the Realtime report.

Not sure if itā€™s related to the ā€œnewā€ Google Analytics G- code vs. the older UA- code.

The f in front of the the string means itā€™s an f-string which ā€œprovide a way to embed expressions inside string literalsā€. Not required in your case. I think that using an f-string would actually thow an exception.

The components.html run the code inside a iframe (see docs). I think the iframes inside Streamlit are sandboxed, which would explain why you donā€™t get any metrics back. Have you tried putting it in a markdown component?

st.markdown(
    """
    <script>Your JS code</script>
    """,
    allow_unsafe_html=True
)

Thanks. I tried using components and markdown, both separately and together on your suggestion but still nothing works. I tried to put in a <head> tag, I moved the code block to the top of the file, I used just the UA- tag, then just the G- tag, then both together. I tried to focus not on my work-hosted website but just on the share.streamlit.io site to simplify.

Iā€™ve looked through Google Analytics 15 different times and it has the correct URL. Iā€™ve tried to visit in my browser, on my phone, and using the Send Test Traffic button in Google Analytics but still no users show up in the Realtime report. I donā€™t understand whatā€™s wrong.

Never did get this to work. Also tried Plausible analytics which also uses JS, and that didnā€™t work either. I did get Clicky and Statcounter to work, neither of which use JS.

3 Likes