Changing the Streamlit Theme with a Toggle Button (SOLUTION)

Saw this mentioned before on another topic.

Thought i should share my workaround.

Officially Streamlit does not have button change theme support/code support to change the theme but you can do it!

By using a session_state to save the current theme state, you can update the config and update the page by doing st.rerun(), this would only run once since it happens when click the button

if you want multiple themes, you could do a drop down list then button to confirm theme change

This works for me so thought i should share :slight_smile:

if st.button(<i use an emote here sun/or moon for light or dark theme> ,help=‘Switch theme’,key=‘switchthemebuttonform’):

        selected = st.session_state['themebutton']
        if selected=='light':
            #st._config.set_option(f'theme.backgroundColor' ,"white" )
            st._config.set_option(f'theme.base' ,"dark" )
            st._config.set_option(f'theme.backgroundColor' ,"black" )
            st._config.set_option(f'theme.primaryColor' ,"#c98bdb" ) 
            st._config.set_option(f'theme.secondaryBackgroundColor' ,"#5591f5" )
            st._config.set_option(f'theme.textColor' ,"white" )
            #st.markdown(dark, unsafe_allow_html=True)
            st.session_state['themebutton'] = 'dark'
        else:
            st._config.set_option(f'theme.backgroundColor' ,"white" )
            st._config.set_option(f'theme.base' ,"light" )
            st._config.set_option(f'theme.primaryColor' ,"#5591f5" )
            st._config.set_option(f'theme.secondaryBackgroundColor' ,"#82E1D7" )
            st._config.set_option(f'theme.textColor' ,"#0a1464")
            
            st.session_state['themebutton'] = 'light'
        st.rerun()
2 Likes

Hi @bpsingh,

Was so impressed with your code, that I wrote it for myself. Adding it here in case someone wants to use it…

import streamlit as st

ms = st.session_state
if "themes" not in ms: 
  ms.themes = {"current_theme": "light",
                    "refreshed": True,
                    
                    "light": {"theme.base": "dark",
                              "theme.backgroundColor": "black",
                              "theme.primaryColor": "#c98bdb",
                              "theme.secondaryBackgroundColor": "#5591f5",
                              "theme.textColor": "white",
                              "theme.textColor": "white",
                              "button_face": "🌜"},

                    "dark":  {"theme.base": "light",
                              "theme.backgroundColor": "white",
                              "theme.primaryColor": "#5591f5",
                              "theme.secondaryBackgroundColor": "#82E1D7",
                              "theme.textColor": "#0a1464",
                              "button_face": "🌞"},
                    }
  

def ChangeTheme():
  previous_theme = ms.themes["current_theme"]
  tdict = ms.themes["light"] if ms.themes["current_theme"] == "light" else ms.themes["dark"]
  for vkey, vval in tdict.items(): 
    if vkey.startswith("theme"): st._config.set_option(vkey, vval)

  ms.themes["refreshed"] = False
  if previous_theme == "dark": ms.themes["current_theme"] = "light"
  elif previous_theme == "light": ms.themes["current_theme"] = "dark"


btn_face = ms.themes["light"]["button_face"] if ms.themes["current_theme"] == "light" else ms.themes["dark"]["button_face"]
st.button(btn_face, on_click=ChangeTheme)

if ms.themes["refreshed"] == False:
  ms.themes["refreshed"] = True
  st.rerun()

All credit goes to B. P. Singh. :slight_smile:

Cheers

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.