No initial callback with store across multiple pages

In my multi-page app I would like to share storage, or at least, I want to click a button and have that effect on the layout of the next page. That’s what I would like to accomplish, so if I go to a settings page and click I want a pink background on all pages, I want that to happen. I don’t per se use just ONE store, but I would like to be able to share some state by sharing some stores.

The thing is that the initial callbacks seem to be fired only the first time, but I guess I already found the solution. Still there are some questions which need to be answered. This is my code for two pages, which share the same store and state id’s:

products_bp = DashBlueprint()

products_bp .layout = html.Div([
    Store(id="my_storage", storage_type="session"),
    html.Button("Click me!", id="my_id"),

# Update the store
@products_bp .callback(
    Output("my_storage", 'data'),
    Input("my_id", "n_clicks"),
    State("my_storage", 'data'))
def on_click(n_clicks, data):
    if n_clicks is None:
        raise PreventUpdate

    # Give a default data dict with 0 clicks if there's no data.
    data = data or {'clicks': 0}

    data['clicks'] = data['clicks'] + 1
    return data

# Update the HTML
@products_bp .callback(
    Output("log", "children"), 
    State("my_storage", 'data'))
def on_data(ts, data):
    if ts is None:
        raise PreventUpdate

    data = data or {}

    return f"Amount of clicks: {data.get('clicks', 0)}"

On page load, initial callbacks are fired, but as soon as I navigate to another page (there is no refresh by the way, just like any other single page app), the Amount of clicks: {data.get('clicks', 0)} disappear.

I figured I had two options:

  • use a different storage for each page, but that’s what I don’t want as described above
  • remove the ts is None: raise PreventUpdate from the last callback.

But with the last option, I’m not sure if that can cause any strange behavior? I believe it is kinda odd that the timestamp is set on page load, but not after a page switch…

And perhaps one extra question: it seems to take like a half of a second for “Amount of clicks: {data.get(‘clicks’, 0)}” to show up, not sure if I can add a pageloader to have the experience the message is just there, instantly, or there are ways to speed things up?

Could you post a complete code example that demonstrates the issue? That would make it easier for people to help you debug the issue :slight_smile: