Skip to content

Keep query params from bind when switching pages #14350

@tenokami11

Description

@tenokami11

Checklist

  • I have searched the existing issues for similar feature requests.
  • I added a descriptive title and summary to this issue.

Summary

Currently the feature to bind query params make working with URLs much simpler, however, when added with page switching and widget value persisting, the collapse makes it hard to work with.

Essentially, when I switch page to a page I want the widgets to fill the URL when binded (which it doesn't now) so I set the query_params myself as well as the widget value via session state (to have their previous value persisted). However the persisted value is seen as the default and is collapsed and it can't be shared anymore, example is shared below.

Why?

No response

How?

perhaps a different accepted value to the bind parameter that indicates that the default shouldn't be collapsed

Additional Context

import datetime as dt

import streamlit as st

# function that saves the widget value to the persistent session state value
def persist():
    st.session_state["persist_across_page"] = st.session_state["widget"]

# mock page for switching
def other_page():
    pass

# main page
def main_page():
    # default date that is applied if no persistent session state value
    default_date = dt.date(2026, 1, 1)
    if "persist_across_page" not in st.session_state:
        st.session_state["persist_across_page"] = default_date

    # check whether coming back from a page swap (in which case, widget has never been initialized
    initial_load = "widget" not in st.session_state

    # add value to widget (either default OR what the session state orginally had
    st.session_state["widget"] = st.session_state["persist_across_page"]
    # populate query params (URL) if necessary
    if initial_load:
        st.query_params["widget"] = st.session_state["widget"]
    with st.form(key="form"):
        # create widget without bind initially as we've updated query params manually
        # then create with bind so URL updates as user updates
        st.date_input(
            key="widget",
            label="date",
            bind="query-params" if not initial_load else None,
        )
        submit = st.form_submit_button(label="Submit", on_click=persist)
    if submit:
        # mock form submit
        st.write(st.session_state["widget"])
    if initial_load:
        # re reun page if needed to regenerate bound widget
        st.rerun()


st.navigation(
    [st.Page(other_page),
    st.Page(main_page)]
).run()

Metadata

Metadata

Assignees

Labels

feature:query-paramsRelated to `st.query_params`priority:P2Medium-high priority - fix within one monthtype:bugSomething isn't working as expected

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions