Streamlit not recognising changes to st.session_state variable and hard coded variable when redirecting user

Summary

When using st.markdown or components.v1.html in order to redirect my users programmatically to another website or server - mimicking the fact a user has already logged in and so redirect them to the main app page - when I go back to the login page and mimic the change in auth status, it appears the changes are not implemented. Streamlit acts as if the previous value - False is still the same value despite my changing the value to True.

Steps to reproduce

Code snippet:

import streamlit as st

def nav_to(url):
    nav_script = """
        <meta http-equiv="refresh" content="0; url='%s'">
    """ % (url)
    st.write(nav_script, unsafe_allow_html=True)

if "sessionCookie" not in st.session_state:
    st.session_state["sessionCookie"] = None

# value will come from database for example but for this purposes its hard coded.
st.session_state["sessionCookie"] = True

if st.session_state["sessionCookie"]:
   # redirect user to server hosting main app page
   nav_to("www.google.co.uk") # using google for simplicity's sake
else:
    st.write("Need to authenticate") # login page will render here

second run - mimicking a user who has not been authenticated

The same as the above only sessionCookie will be False

# value will come from database for example but for this purposes its hard coded.
st.session_state["sessionCookie"] = False

Expected behavior:

I expect that when I go back to the login page url, with a new sessionCookie value - False it should render the login page.

Actual behavior:

But it still renders the redirect section even when I change its from True to False - again to mimic getting the dynamic data from database. At the initial run, I used a print statement to print out the “cookieSession” from st.session_state and depsite changing the value it still shows the intiial value.

I also tested it with a variable rather than st.session_state for example verified = False instead of st.session_state["sessionCookie"] = False.

Debug info

  • Streamlit version: 1.27.0
  • Python version: 3.9
  • Using Conda
  • OS version: Windows 11
  • Browser version: Version 117.0.5938.92 (Official Build)

Requirements file

conda

Links

  • Link to your GitHub repo:
  • Link to your deployed app:

Additional information

I tested the above using other methods like:

Method #2

Create an a tag then mimic “clicking” it if verified status is True to redirect to main app page. Again using hard coded variable and st.session_state saved variable.


verified = True 
st.markdown("<a class='redirect' href='https://google.co.uk'></a> ", unsafe_allow_html=True)

js = f'''
            <script>
                function redirect(event) {{
                    window.top.parent.document.querySelectorAll('[class="redirect"]')[0].click();
                    event.preventDefault();
                }}
                if ({verified} === True){{
              
                  redirect();
                   }}

           </script>
  '''

st.components.v1.html(js, height=0, width=0)

Method 3

Use javascript to create the meta tag and append to head element. Again using hard coded variable and st.session_state saved variable.

st.session_state["sessionCookie"] = True

  js =  f""" 
        <script>
           if ({st.session_state["sessionCookie"]} === True){{
               const redirect_link = document.createElement('meta');
               redirect_link.httpEquiv = "refresh";
               redirect_link.content = "20; URL='https://google.co.uk'";
               window.top.document.head.appendChild(redirect_link);
           }} else {{
               redirectMeta = window.top.parent.document.querySelectorAll('meta[httpEquiv="refresh"]')[0];
               redirectMeta.remove();
            }}
        </script>
"""
st.components.v1.html(js, height=0, width=0)

In all cases when I change the verified/cookie status the value remained the same as it was upon initiation. Any idea why these changes are not being recognised by streamlit?

Nvm, works as expected. Changes needed to be made whilst the page was active - ie whilst on localhost:8501 for example. I placed a longer delay on the redirect and changed it before it activated and it worked. I also tested it with expiring cookies and it worked when it could not find it in the browser.

All’s good.