How to Dynamically Navigate to a Multipage App Page from Sidebar Selectbox in Streamlit?

Hi Streamlit community,

I’m building a multipage app using st.navigation where my pages are organized in a folder called “apps” (e.g., apps/app1.py, apps/app2.py). The navigation works fine with the default sidebar menu.

I have a “Favorites” feature in the sidebar: a selectbox that lists user favorites (stored in Cosmos DB). Each favorite is tied to a specific app page and includes filters (e.g., date ranges, selections) saved in a dict. When a favorite is selected, I update st.session_state with the filters and want to navigate to the corresponding app page.

I’ve tried several approaches, but none successfully switch the page while preserving the session_state updates:

  1. st.switch_page(f"apps/{app_file}") - This navigates but doesn’t apply the session_state filters reliably, and sometimes throws errors about page not found.

  2. st.page_link(f"apps/{app_file}", label=“Go to page”) - This creates a link, but I need automatic navigation on selectbox change, not a clickable link.

  3. Setting a session_state key (e.g., st.session_state.selected_page = app_name) and calling st.rerun() - This reruns the script but doesn’t change the active page in st.navigation.

  4. Using query params (e.g., st.query_params.page = app_name) - This updates the URL but doesn’t trigger page switch in multipage setup.

My goal is for the selectbox on_change (or equivalent) to:

  • Update session_state with filters.

  • Switch to the target page (e.g., app1).

  • Have the target page load with the applied filters.

Is there a recommended way to achieve dynamic navigation in multipage apps from a sidebar component? Any examples or workarounds would be appreciated!

Streamlit version: 1.50.0

Thanks!

Rich

There shouldn’t be a problem writing a callback on a selectbox to accept the item, set Session State values, then switch pages. The only complicating factor is if any of the keys in Session State are associated to widgets on the page you’re coming from. There is a widget clean up process that can have unexpected consequences when changing pages. We’re exploring changing some of this behavior, but in the meantime, the best thing to do is use different keys for carrying values between pages which are copied into widget keys after you get to the page.

Can you share a bit more concretely with a small executable example how you are having trouble setting a value in Session State and using st.switch_page in a callback on your favorites selectbox?

I devised a bit of a workaround for this issue. I switch between my apps using st.navigation and generate my favorites selection st.dropdown based on the app that is currently selected. It works well and is only one additional step. Since the filter parameters are unique for my different apps this simplified the issue and likely is a better user experience than showing all favorites on a global level in my main page. I think what is missing is the ability to initiate page switching as with st.navigation from other widgets like st.dropdown. I really like how st.page/st.navigation are implemented so wouldn’t want to deviate from that too far.

You can do this with a callback. If I understand your case correctly:

  1. Assign a key to your selectbox.
  2. Define a callback function that (within the callback) you read the value of the selectbox from Session State and execute the correct st.switch_page command.
  3. Pass the callback to the selectbox.