Multi-page app that preserves state?

Hello. I’m working with a decent-sized dash app. It currently has a handful of pages using dash’s Pages support (page_registry, page_container, NavLink, etc.). I’ve inherited that. Users have noticed that when switching pages using the NavLinks, all of the state of the page is lost. We would like it to stay in memory and be more like switching tabs rather than reloading each page every time.

I’ve seen references to using persistence flags, but that feels a bit piecemeal and maybe not supported everywhere, when I really just want the entire page to stay in memory.

I found dash-extensions’ Pages, which supposedly allows this, but I couldn’t even get callbacks to work with their small example.

Is there a solution that is easy to implement at a high level and wouldn’t require rewriting a bunch of code? Is switching to a Tab container the right way to go?

Thanks,
Reid

If I understand this (it’s possible I don’t) Navlinks shouldn’t necessarily be reloading the page every time. Is this bit of doc any help?

The NavLink component can be used like dash_core_components.Link, as a regular hyperlink, or as a button by attaching a callback to the n_clicks prop. NavLink will behave like dcc.Link by default if we assign a relative path to href, and like a hyperlink if we assign an absolute path. This can be overridden using the external_link argument.

external_link (boolean; optional): If True, the browser will treat this as an external link, forcing a page refresh at the new location. If False, this just changes the location without triggering a page refresh. Use this if you are observing dcc.Location, for instance. Defaults to True for absolute URLs and False otherwise.

Both from

https://dash-bootstrap-components.opensource.faculty.ai/docs/components/nav/

Yes, thanks, I also saw that while digging for info and forgot to mention it. I currently have external_link explicitly set to False in my NavLinks and I’m still seeing the behavior I described. I don’t understand what effect it’s having. (I didn’t mention it earlier, but maybe it’s obvious that I’m somewhat new to dash.)

Apologies, you’re right - persistence=True has to be set for the components in the pages.

An Accordion (either dmc.Accordion or dbc.Accordion) appears to preserve the values of component elements when its AccordionItems are closed and then reopened, if that’s a layout that would work for you.

Ah, I wasn’t aware of the connection to persistence, thanks.

Accordion is probably not the right control for this use case, unfortunately. I think a Tab could make sense, though. Do you happen to know if Tab suffers from these same refresh issues? I was assuming it doesn’t. Thank you.

Hi @reidr

The tabs will retain the state as long as you use “Method 2: Content as Tab Children” – as described on this page:

If you use callbacks to display the content when switching tabs (method 1), you will need to manage the state in the same way as a multi page app.

1 Like

Thank you, that’s kind of what I was suspecting would have to be the route to take. I’ll try to get Method 2 working. Appreciate both of your help!

Thanks @AnnMarieW - I couldn’t quite understand what the Persistence doc page was saying about tabs, but had ended up with the (wrong) impression that they probably didn’t persist values.