Are you using HTML in Markdown? Tell us why!

Thanks. I may have mischaracterized things with the graphs looking bad. It was just that we previously set widths that made sense for desktop, and they were (as one would expect) too wide to look good on mobile.

So, the only issue was wanting the responsiveness we get from that css hack. Glad to hear there’s good solutions in the works =)

Thanks again for all the thought you’re putting into this


I just used html and css to generate a legend for pydeck charts. My map shows concentrations with a color gradient going from blue to green. I have not found a way in pydeck to generate this, so I included the code below, that renders a blue and a green dot with the corresponding value interval. Ideally of course, I could generate the legend with pydeck directly (maybe this is possible and I just did not find out how :smile:). Second best solution would be if I could generate Unicode symbols directly from streamlit:
st.write(st.symbol(#9679, blue) + ‘10-15’)
st.write(st.symbol(#9679, green) + ‘15-20’)
so something like this is shown:
:large_blue_circle: 10-15
:green_circle: >15-20

However, I find HTML/CSS very handy and fear it will be difficult to replace it by something similarly flexible.

legend = """
                .bdot {{
                height: 15px;
                width: 15px;
                background-color: Blue;
                border-radius: 50%;
                display: inline-block;
                .gdot {{
                height: 15px;
                width: 15px;
                background-color: #4DFF00;
                border-radius: 50%;
                display: inline-block;
                <div style="text-align:left">
                <span class="bdot"></span>  {} - {}<br>
                <span class="gdot"></span>  &#62;{} - {}
                """.format(round(min_val), round((max_val - min_val) / 2), round((max_val - min_val) / 2), round(max_val))
            st.markdown(legend, unsafe_allow_html=True)

I’m starting to experiment with converting an app to something that feels like dark mode.

body {
    color: #fff;
    background-color: #111;
    """, unsafe_allow_html=True)

There’s still some work needed to update all the colors like I’d want them, as well as adjusting the color pallete in plots so they don’t fry my corneas against the black background.

I may put it on hold until I there’s more info about how much CSS control we’ll have after the relevant changes. But it’d be nice to be able to do this.


I want to use html not due to formatting reasons, but because more and more python libraries render the output of analysis in HTML format.

As such, these are not html injected by me, but are directly generated by those packages after me inputting some legit input. They could be interactive charts or rich-formatted tables.

Without html function one would go extreme length to reverse-engineer the original package, by stopping the function one step short of the html output, then plot one’s own chart, basically re-do a lot of things already in those packages. Many times that’s not feasible.


I wanted to insert script tag with JS code. The code adds keyboards shortcuts to buttons in my Streamlit app.

Update: We heard you, and have no plans to deprecate allow_unsafe_html ! :champagne:

Thank you for sharing your thoughts. It’s really useful!! :pray:t2:


i just try ur code, but the maps didnt show, how ?thanks

1 Like

That’s great to hear, I had some nightmares about html being disabled :wink:

1 Like

I converted an ipynb notebook to a local html file and displayed it in streamlit.

    HtmlFile = open("sales_impact_report.html", 'r', encoding='utf-8')
    source_code = 
    st.markdown(source_code, unsafe_allow_html=True)

However, my output gives me this, how can i hide/remove the blocks before my header?

1 Like

Hi @Chris_Brake,
Thanks for your contribution.

I’m having trouble trying to make this work here. If I just use st.write(m.repr_html()), then copy the code and inject it manually in the page source code, my map shows ok.

But if I try to use st.markdown(m.repr_html(), unsafe_allow_html=True) the object uses the space in the page but shows nothing.

Did you face a similar problem? I can’t figure out what is going wrong.

If I inspect the page source code, all js code is missing after using st.markdown. For instance, if I add onload=“;this.contentDocument.write(atob(this.getAttribute(‘data-html’)));this.contentDocument.close();” before allowfullscreen the map is correctly shown.

This is the file I’m trying to replicate - (version 0.53.0):

import streamlit as st
import pandas as pd
import folium

all_cities = pd.DataFrame(
    [(40.7127837, -74.0059413),(34.0522342, -118.2436849),(41.8781136, -87.6297982)],
    ['New York', 'Los Angeles', 'Chicago'],

selected_city = st.selectbox('Select city', all_cities.index)

route_map = folium.Map(location=(all_cities.loc[selected_city]), zoom_start=9, control_scale=True)

aux = route_map._repr_html_()
st.markdown(aux, unsafe_allow_html=True)
1 Like

Hi @dqniellew1,

You may be in a bit of a bind with trying to display this HTML in Streamlit, because it looks a lot like those scripts are needed to make the exported HTML code work.

You could attempt to strip this entire header out of the HTML you’re reading with something like this:

HtmlFile = open("sales_impact_report.html", 'r', encoding='utf-8')
source =
end_tag = "</head>"
source = source[source.find(end_tag)+len(end_tag):]
st.markdown(source, unsafe_allow_html=True)

Since I don’t know what the entire HTML looks like, I can only guess at what will happen if you strip the header out, but I know that your header is not being interpreted as HTML right now (because it’s being displayed). So it’s worth a try.

Conceptually speaking, if you want to get Streamlit to take an entire pre-constructed page of HTML via the markdown processor, you’re going to have to feed any Javascript or styling in on a block-by-block basis.

This is because the Markdown processor will respect the “unsafe_allow_html” flag for the first chunk of code it encounters, but not after the first newline. (This causes other problems as well, and we really want to fix this. See :bow_and_arrow: )

Thanks for your question. I promise this will get easier in the near future. :heavy_heart_exclamation:

1 Like


First of all, I have to thank you for streamlit, such a great and beautiful library and it works perfectly.

On the other hand, I am facing a problem such as @Lazaro_Pinheiro_Domi . I have tried his code and also the following:

import streamlit as st
import folium

m = folium.Map([38.8934, -76.9470], tiles=’stamentoner’,   zoom_start=12)
st.markdown(m._repr_html_(), unsafe_allow_html =True)

Firstly, I tried that way, but, as Lazaro mentioned, it just returns an empty white box. I have tried working with previous versions of Streamlit and Folium but no satisfactory result was obtained. I also tried to manually add the .html file that it is generated when you do'./map.html') with the following:

st.markdown('<iframe src="./STREAMLIT/img/map.html"> </iframe>', unsafe_allow_html=True)

However, it did not work (perhaps because my HTML knowledge is limited), it does not seem able to find the path, and I have tried many approaches. Note that img is a folder where I have put the map and that in the STREAMLIT folder is where it is the

One last approach I have thought about is maybe introducing a button that redirects to the HTML map (locally stored, because I am actually running this locally, I am not either planning to deploy this into a server yet), however, I cannot make it work.

Here is some more info:

Python: 3.6
Ubuntu: 18.04
Google Chrome 80.0, Mozilla 73.0

Thanks in advance and have a nice day!

1 Like

Hi @Adri_Lopez,

I really respect how much problem-solving you’re putting into this!

The issue with where you put the output HTML file is that Streamlit has no map to finding this. What you should be able to do (and this isn’t “recommended”, but if you’re intent on hacking a solution for this anyway) is place your HTML file under the “static” folder in the installed streamlit package for your virtual environment.

For example, my static folder for when I’m experimenting with Streamlit features is here:


Yours should look like mine after the st_sandbox-D9fr_O3a.

Put an HTML page in there and test it out by doing streamlit hello and then changing the url to your test page, e.g. http://localhost:8501/test.html

I can promise you this is not going to be a supported way to do things in the future, and we’re working on incorporating 3rd party HTML outputs in Streamlit in a more formal manner. But this should work for you in the short term.

Thanks for your interest!


@Adri_Lopez @Lazaro_Pinheiro_Domi did you guys find a good workaround to render folium maps?

I have just tried it and it works perfectly. I really appreciate your effort in answering and understanding everyone’s problems. I still don’t understand why the _repr_html_.() function doesn’t work on my case, but anyway, if I can figure it out, I will tell you all. :slight_smile:

Thanks a lot!


Thanks so much @Adri_Lopez! It feels good to have effort appreciated and I really needed to hear that today. :heart:

Hope you and everyone you know are keeping safe! :mask:

1 Like

Hello, do you have any idea how could we use folium in streamlit? I don’t understand why it doesn’t work with st.markdown(m.repr_html(), unsafe_allow_html =True). And I don’t have any other solutions for now to display my folium result with streamlit. Tks for your reply

Hello, I have the same problem in using folium in streamlit, could you please tell me how you fix this problem?

Hi @jwei,

I’m sorry to say that direct support for Folium is still an open issue, and when you try to display an HTML dump from Folium it will fail probably for the same reason that LIMEexplainer fails.

You can use the workaround that I posted above. So you’d do something like this:

import streamlit as st
import folium

STREAMLIT_STATIC_PATH = "/Users/nthmost/.local/share/virtualenvs/st_sandbox-D9fr_O3a/lib/python3.7/site-packages/streamlit/static/"

map_path = STREAMLIT_STATIC_PATH + 'map.html'

m = folium.Map([38.8934, -76.9470], tiles=’stamentoner’,   zoom_start=12)
open(map_path, 'wb').write(m.repr_html())

st.markdown('<iframe src="/map.html"> </iframe>')

Give that a try and see if it does the trick…!

Yes, it’s a solution for using on my end, but it won’t work if I want put this web in Cloud, for example, Heroku, is it?