Problem:Share session_state on multipages

I just found out about Streamlit recently.

This framework is exactly what I have wanted.
I love the new multipage feature.

But, I’m stumbling sharing session_state between pages.

When jump to each page from the sidebar menu,
The value of session_state is preserved.
But,if I jump to each page from the link set in HTML with st.markdown,
The value of session_state is not preserved (it seems clear).

Is there a difference between the link in the sidebar menu and the link set in HTML st.markdown?

Is session_state used incorrectly?

Please give me advice.

Home.py
import streamlit as st

print('Home 1')
print(st.session_state)

st.session_state.update(st.session_state)

if "shared" not in st.session_state:
   st.session_state.shared = True
   
if 'products' not in st.session_state:
    st.session_state.products = ['None']

print('Home 2')
print(st.session_state)

st.title("Home")
st.sidebar.header('Home')

print('Home 3')
print(st.session_state)

st.markdown('<a href="http://localhost:8501/Page2" target="_self">Page2</a>', unsafe_allow_html=True)

st.markdown('<a href="http://localhost:8501/Page3" target="_self">Page3</a>', unsafe_allow_html=True)

Page1.py
import streamlit as st

print('Page1 1')
print(st.session_state)

#st.session_state.update(st.session_state)

print('Page1 2')
print(st.session_state)

if "shared" not in st.session_state:
   st.session_state.shared = True

if 'products' not in st.session_state:
    st.session_state.products = ['None']
 
print('Page1 3')
print(st.session_state)

st.title("Page1")
st.sidebar.header('Page1')

st.session_state.products = ['Apple','Grape','Lemon','Orange']

print('Page1 4')
print(st.session_state)

Page2.py
import streamlit as st

print('Page2 1')
print(st.session_state)

#st.session_state.update(st.session_state)

print('Page2 2')
print(st.session_state)

if "shared" not in st.session_state:
   st.session_state.shared = True

if 'products' not in st.session_state:
    st.session_state.products = ['None']
 
print('Page2 3')
print(st.session_state)

st.title("Page2")
st.sidebar.header('Page2')

print('Page2 4')
print(st.session_state)

Page3.py
import streamlit as st

print('Page3 1')
print(st.session_state)

#st.session_state.update(st.session_state)

print('Page3 2')
print(st.session_state)

if "shared" not in st.session_state:
   st.session_state.shared = True

if 'products' not in st.session_state:
    st.session_state.products = ['None']
 
print('Page3 3')
print(st.session_state)

st.title("Page3")
st.sidebar.header('Page3')

print('Page3 ')
print(st.session_state)

##Console output

– Home -----------
Home 1
{}

#initialize session_state

Home 2
{‘shared’: True, ‘products’: [‘None’]}
Home 3
{‘shared’: True, ‘products’: [‘None’]}

– Jump to Page1 from Sidebarmenu -----------
– Page1 -----------

#find shared in session_state
Page1 1
{‘shared’: True, ‘products’: [‘None’]}
Page1 2
{‘shared’: True, ‘products’: [‘None’]}
Page1 3
{‘shared’: True, ‘products’: [‘None’]}

#Set products to session_state

Page1 4
{‘shared’: True, ‘products’: [‘Apple’, ‘Grape’, ‘Lemon’, ‘Orange’]}

– Jump to Page2 from Sidebarmenu -----------
– Page2 -----------

#find products in session_state
Page2 1
{‘shared’: True, ‘products’: [‘Apple’, ‘Grape’, ‘Lemon’, ‘Orange’]}
Page2 2
{‘shared’: True, ‘products’: [‘Apple’, ‘Grape’, ‘Lemon’, ‘Orange’]}
Page2 3
{‘shared’: True, ‘products’: [‘Apple’, ‘Grape’, ‘Lemon’, ‘Orange’]}
Page2 4
{‘shared’: True, ‘products’: [‘Apple’, ‘Grape’, ‘Lemon’, ‘Orange’]}

– Jump to Page3 from Sidebarmenu -----------
– Page3 -----------

#find products in session_state
Page3 1
{‘shared’: True, ‘products’: [‘Apple’, ‘Grape’, ‘Lemon’, ‘Orange’]}
Page3 2
{‘shared’: True, ‘products’: [‘Apple’, ‘Grape’, ‘Lemon’, ‘Orange’]}
Page3 3
{‘shared’: True, ‘products’: [‘Apple’, ‘Grape’, ‘Lemon’, ‘Orange’]}
Page3
{‘shared’: True, ‘products’: [‘Apple’, ‘Grape’, ‘Lemon’, ‘Orange’]}

– Jump to Home from Sidebarmenu -----------
– Home -----------

#find products in session_state
Home 1
{‘products’: [‘Apple’, ‘Grape’, ‘Lemon’, ‘Orange’], ‘shared’: True}
Home 2
{‘products’: [‘Apple’, ‘Grape’, ‘Lemon’, ‘Orange’], ‘shared’: True}

– Jump to Page2 from created link -----------
– Page2 -----------

#empty session_state

Page2 1
{}
Page2 2
{}

#initialize session_state

Page2 3
{‘shared’: True, ‘products’: [‘None’]}
Page2 4
{‘shared’: True, ‘products’: [‘None’]}

2 Likes

Hello, yes I am having similar issues with session_state. Modifications to session_state don’t seem to be “seen” by other pages. This bug can be bypassed by merely going st.write(session_state) - as soon as it puts a component of session_state into the page render itself, it then realises it exists!

If you don’t want to write the session state to the page, you can just go

type(session_state)

which won’t output anything, but for some reason will refresh how Streamlit sees session_state. Not ideal, I know, but seems to be working for now.

It was solved with buttons and switch_page(), referring to your post for “Navigate Multipage App with Buttons instead of Sidebar”.

I’ll also try streamlit-extras.

Thank you.

Sorry, accidentally clicked delete :man_facepalming:

Here was my post:
@Gaku.Yokoyama If you click on a link, it unfortunately creates a new session. If you change pages either with the sidebar, or using this function from GitHub - arnaudmiribel/streamlit-extras: Discover, try, install and share Streamlit re-usable bits we call “extras”!, it should work properly.

For example, if you pip install streamlit-extras, you can do this:

from streamlit_extras.switch_page_button import switch_page

if st.button("Page2"):
    switch_page("Page2")

That switch_page post code has been added to streamlit-extras to make it more accessible. You can see it in action here https://extras.streamlitapp.com/Switch%20page%20function

@blackary How can I switch the page to new tab?

If you open it up in a new tab it will be a new session, unfortunately. So, a normal link will work fine to open a new page in a new tab, but you will lose session state.

I was able to solve this problem using using A hacky solution (not my preference) of this stackoverflow post. Just put

for k, v in st.session_state.to_dict().items():
   st.session_state[k] = v

on top of every page. This commits all keys irrespective of the widgets of this page and makes them available to all pages.

That works