Multipage app - preserving selections

I am using multi-selects in a multi-page app. I would like the session state for the components to be preserved across the multipage app, similar to the “regular” session states.

Looks like the regular session states are being preserved but not the session state for the component based on the key.

The session state for the components is lost across pages while the session state for the components is lost.

You will see that the “Went ” is preserved, but when you go back and forth between the pages the session state for the multiselect is reset. I tried using a separate session variable and storing the selected value in the regular session state ss_ but the behavior is wonky when I select a new value (See the code for Page 1). I might be able to fix it with an “onChange” code, but its too much effort …It should work right out of the box.

Home.py

import streamlit as st
import sys

st.session_state["Home"]="Went Home"

st.write(f"Home: {st.session_state.Home}")
if "Page1" in st.session_state: 
	st.write(f"Page1: {st.session_state.Page1}") 

if "Page2" in st.session_state:
	st.write(f"Page2: {st.session_state.Page2}") 

if "Page3" in st.session_state:
	st.write(f"Page3: {st.session_state.Page3}") 

Page1.py

import streamlit as st
import sys

st.session_state["Page1"]="Went Page1"

if "ss_regions" not in st.session_state:
	st.session_state.ss_regions=[]

selected_regions = st.multiselect("Region",["Region1","Region2","Region3"],key="regions",default=st.session_state.ss_regions)

st.session_state.ss_regions=selected_regions

print(f"Regions: selected: {selected_regions} key:{st.session_state.regions} ss_key:{st.session_state.ss_regions}")


st.write(f"Home: {st.session_state.Home}")
if "Page1" in st.session_state: 
	st.write(f"Page1: {st.session_state.Page1}") 

if "Page2" in st.session_state:
	st.write(f"Page2: {st.session_state.Page2}") 

if "Page3" in st.session_state: 
	st.write(f"Page3: {st.session_state.Page3}") 

st.write(f"Regions: selected: {selected_regions} key:{st.session_state.regions} ss_key:{st.session_state.ss_regions}")

Page2.py

import streamlit as st
import sys

st.session_state["Page2"]="Went Page2"

if "ss_subregions" not in st.session_state:
	st.session_state.ss_subregions=[]

selected_subregions = st.multiselect("SubRegion",["SubRegion1","SubRegion2","SubRegion3"],key="subregions")

st.session_state.ss_subregions=selected_subregions

print(f"SubRegions: selected: {selected_subregions} key:{st.session_state.subregions} ss_key:{st.session_state.ss_subregions}")

st.write(f"Home: {st.session_state.Home}")
if "Page1" in st.session_state: 
	st.write(f"Page1: {st.session_state.Page1}") 

if "Page2" in st.session_state:
	st.write(f"Page2: {st.session_state.Page2}") 

if "Page3" in st.session_state: 
	st.write(f"Page3: {st.session_state.Page3}") 

st.write(f"SubRegions: selected: {selected_subregions} key:{st.session_state.subregions} ss_key:{st.session_state.ss_subregions}")

Page3.py

import streamlit as st
import sys

st.session_state["Page3"]="Went Page3"

selected_countries = st.multiselect("Country",["Country2","Country2","Country3"],key="countries")

st.session_state.ss_countries=selected_countries

print(f"Countries: selected: {selected_countries} key:{st.session_state.countries} ss_key:{st.session_state.ss_countries}")


st.write(f"Home: {st.session_state.Home}")
if "Page1" in st.session_state: 
	st.write(f"Page1: {st.session_state.Page1}") 

if "Page2" in st.session_state:
	st.write(f"Page2: {st.session_state.Page2}") 

if "Page3" in st.session_state: 
	st.write(f"Page3: {st.session_state.Page3}") 

st.write(f"Countries: selected: {selected_countries} key:{st.session_state.countries} ss_key:{st.session_state.ss_countries}")

I think this is the relevant open issue in bug tracker: An option to keep component values in the session state · Issue #4458 · streamlit/streamlit · GitHub

Personally, I do write the on_change callbacks to manually assign widget states to st.session_state if I know I am going to need to preserve the state of ‘disappearing’ widgets.

edit: I have not done it this way but I believe you could also try to get around it by putting st.session_state.update(st.session_state) at the beginning of each page.