Hey Streamlit community!
I’ve seen many people struggling with adding Google Tag Manager, analytics, or custom HTML to their Streamlit apps, especially when running in Docker. After trying multiple approaches (monkey patching, runtime injection, etc.), I finally found a reliable solution that I want to share.
The Problem
Streamlit doesn’t provide a native way to modify the HTML <head>
or <body>
sections. This makes it challenging to add:
- Google Tag Manager
- Analytics tracking (GA4, Facebook Pixel, etc.)
- SEO meta tags
- Custom scripts
The challenge is even bigger with Docker due to read-only filesystems and container isolation.
The Solution
Thanks to @snehankekre’s suggestion in this thread about using SED to modify index.html
, I expanded on this approach to create a comprehensive, production-ready solution for Docker environments.
The build-time injection approach using SED modifies Streamlit’s static HTML during Docker image build. This means:
No runtime overhead
Works with read-only containers
100% reliable
Production-ready
How It Works
Simply add this to your Dockerfile:
# Inject GTM using sed
ARG GTM_ID
RUN sed -i "/<\/head>/i\
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':\
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],\
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=\
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);\
})(window,document,'script','dataLayer','${GTM_ID}');</script>" \
$(python -c "import streamlit, os; print(os.path.join(os.path.dirname(streamlit.__file__), 'static', 'index.html'))")
Then build with:
docker build --build-arg GTM_ID=GTM-YOURCODE -t your-app .
Complete Solution
Building on @snehankekre’s SED approach, I’ve created a comprehensive repository with:
Modular injection scripts (GTM, Analytics, SEO, custom HTML)
Ready-to-use Dockerfiles
Examples and documentation
Makefile for easy operations
GitHub Repository: streamlit-html-injection-docker
The repo includes scripts for:
- Google Tag Manager
- Google Analytics 4
- Facebook Pixel
- Microsoft Clarity
- SEO meta tags (Open Graph, Twitter Cards)
- Custom HTML injection from files
Example Use Cases
-
Adding GTM to your app:
docker build --build-arg GTM_ID=GTM-ABC123 -t my-app .
-
Full SEO + Analytics:
docker build \ --build-arg GTM_ID=GTM-ABC123 \ --build-arg SEO_TITLE="My Dashboard" \ --build-arg SEO_DESCRIPTION="Analytics dashboard" \ -t my-app .
Why This Approach?
After testing runtime patching, monkey patching, and various other methods suggested in different threads, the build-time SED injection (as suggested by @snehankekre) proved to be the most reliable. It works every time, has zero runtime overhead, and is compatible with any Docker deployment.
Credits
Special thanks to @snehankekre for the original SED suggestion that inspired this complete solution!
Hope this helps others facing the same challenge! Feel free to contribute or suggest improvements on GitHub.