# Multipage persistence

**URL:** <https://community.plotly.com/t/multipage-persistence/10682>\
**Category:** Dash Python\
**Created:** [June 4, 2018, 6:07pm UTC](https://community.plotly.com/t/multipage-persistence/10682 "2018-06-04T18:07:21Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![makn87](https://avatars.discourse-cdn.com/v4/letter/m/f14d63/32.png) [@makn87](https://community.plotly.com/u/makn87)\
**Post date:** [June 4, 2018, 6:07pm UTC](https://community.plotly.com/t/multipage-persistence/10682/1 "2018-06-04T18:07:21Z")

</div>

Hi. I’ve looked through the user manual, and at all posts related to multi page apps. I think I’m missing the concept of making an object persist across multiple pages in html.

I would like to process some data on the initial ‘index’ page, and have it available to other tabs. In this example, I like the dataframe created on the index page to be available to page\_1\_layout and page\_2\_layout for further manipulation. Why doesn’t something like this work?

I have spent several days on this. So any help is appreciated. Thanks

import dash  
import pandas as pd  
import numpy as np  
import dash\_core\_components as dcc  
import dash\_html\_components as html

app = dash.Dash()

app.scripts.config.serve\_locally = True  
app.config.suppress\_callback\_exceptions = True

app.layout = html.Div([  
dcc.Location(id=‘url’, refresh=False),  
html.Div(id=‘page-content’,className=“container”),  
html.Div(id=‘data’,style={‘display’:‘none’})  
])

index\_page = html.Div([  
html.Div(dcc.Dropdown(id =‘df’, options=[{‘label’:str(i), ‘value’: i } for i in [‘df1’,‘df2’]])),  
dcc.Link(‘Go to Page 1’, href=’/page-1’),  
html.Br(),  
dcc.Link(‘Go to Page 2’, href=’/page-2’),  
])

page\_1\_layout = html.Div([  
html.H1(‘Page 1’),  
dcc.Dropdown(  
id=‘page-1-dropdown’,  
options=[{‘label’: i, ‘value’: i} for i in [‘LA’, ‘NYC’, ‘MTL’]],  
value=‘LA’  
),

```
html.Div(dcc.Checklist(id ='dfdrop', values=[] )),
html.Div(id='page-1-content'), 
html.Br(),
dcc.Link('Go to Page 2', href='/page-2'),
html.Br(),
dcc.Link('Go back to home', href='/'),

```

])

@app.callback(dash.dependencies.Output(‘page-1-content’, ‘children’),  
[dash.dependencies.Input(‘page-1-dropdown’, ‘value’),  
])  
def page\_1\_dropdown(value):  
return ‘You have selected “{}”’.format(value)

@app.callback(dash.dependencies.Output(‘dfdrop’,‘options’),  
[dash.dependencies.Input(‘data’,‘children’)  
])  
def option1(child):  
df = pd.read\_json(child)  
return [{‘label’:i, ‘value’:i} for i in df.columns]

page\_2\_layout = html.Div([  
html.H1(‘Page 2’),  
dcc.RadioItems(  
id=‘page-2-radios’,  
options=[{‘label’: i, ‘value’: i} for i in [‘Orange’, ‘Blue’, ‘Red’]],  
value=‘Orange’  
),  
html.Div(id=‘page-2-content’),  
html.Br(),  
dcc.Link(‘Go to Page 1’, href=’/page-1’),  
html.Br(),  
dcc.Link(‘Go back to home’, href=’/’)  
])

@app.callback(dash.dependencies.Output(‘page-2-content’, ‘children’),  
[dash.dependencies.Input(‘page-2-radios’, ‘value’)])  
def page\_2\_radios(value):  
return ‘You have selected “{}”’.format(value)

@app.callback(dash.dependencies.Output(‘data’,‘children’),  
[dash.dependencies.Input(‘df’,‘value’)])  
def create\_df(val):  
df = pd.DataFrame()  
if val == ‘df1’:  
df = pd.DataFrame(np.random.randint(0,100,size=(100,4)),columns=list(‘ABCD’))  
if val == ‘df2’:  
df = pd.DataFrame(np.random.randint(0,1000,size=(100,4)),columns=list(‘ABCD’))  
return df.to\_json()# Update the index

```
# You could also return a 404 "URL not found" page here

```

@app.callback(dash.dependencies.Output(‘page-content’, ‘children’),  
[dash.dependencies.Input(‘url’, ‘pathname’)])  
def display\_page(pathname):  
if pathname == ‘/page-1’:  
return page\_1\_layout  
elif pathname == ‘/page-2’:  
return page\_2\_layout  
else:  
return index\_page

if **name** == ‘ **main** ’:  
app.run\_server(debug=True)

---

<div class="post-metadata">

**Author:** ![charleyferrari](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/charleyferrari/32/3109_2.png) [@charleyferrari](https://community.plotly.com/u/charleyferrari)\
**Post date:** [June 4, 2018, 8:50pm UTC](https://community.plotly.com/t/multipage-persistence/10682/2 "2018-06-04T20:50:51Z")

</div>

For multi-page apps, the structure we recommend can be roughly outlined as follows:

```auto
app.layout = html.Div([
  # dash core components populating page contents,
  html.Div(id='page-content')
])

```

Our examples usually focus around `dcc.Location`, but these core components can be anything.

You’re right that there is no persistence across these different locations, because the page content is completely replaced whenever you click on another link.

The key is to take whatever dash core components you want to be persistance outside of `page-content`. This works perfectly if your core components stay at the top, but to mimic your specfic architecture (a dcc in one page being accessed in another), you can simply add a callback that hides the content depending on which page you’re on.

Checkout this toy example that shows what this could look like. The experience of this app is that there is a dropdown on page 1, which is accessed on page 3:

```auto
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

app = dash.Dash()

app.css.append_css({
    'external_url': 'https://codepen.io/chriddyp/pen/bWLwgP.css'})

app.config.suppress_callback_exceptions = True

app.layout = html.Div([
    # External dcc's for persistance
    dcc.Location(id='url'),
    dcc.Link('Page-1', href='/page1'),
    dcc.Link('Page-2', href='/page2'),
    dcc.Link('Page-3', href='/page3'),
    # We want a dropdown in Page 1 to be persistant
    html.Div([
        html.H2(['Welcome to Page 1']),
        dcc.Dropdown(
            options=[
                {'label': 'choice 1', 'value': 'choice 1'},
                {'label': 'choice 2', 'value': 'choice 2'},
                {'label': 'choice 3', 'value': 'choice 3'}
            ],
            value='choice 1',
            id='page-1-dropdown'
        )
    ], id='external-page-1'),

    # Page Content
    html.Div(id='page-content')
])

# Define pages

page_1_content = html.Div([
    html.P(['We are on page one now'])
])

page_2_content = html.Div([
    html.H2(['Welcome to Page 2']),
    html.P(['We are on page two '])
])

page_3_content = html.Div([
    html.H2(['Welcome to Page 3']),
    html.Div(id='dropdown-output'),
    html.P(['We are on page three'])
])

# Callback to populate page-content
@app.callback(
    Output('page-content', 'children'),
    [Input('url', 'pathname')]
)
def populate_content(url):
    if url == '/page1':
        return page_1_content
    elif url == '/page2':
        return page_2_content
    elif url == '/page3':
        return page_3_content

# Callback to hide Dropdown
@app.callback(
    Output('external-page-1', 'style'),
    [Input('url', 'pathname')]
)
def hide_external(url):
    if url == '/page1':
        return {'display': 'block'}
    else:
        return {'display': 'none'}

# Callback to show persistence: display dropdown contents from page 1 in page 3

@app.callback(
    Output('dropdown-output', 'children'),
    [Input('page-1-dropdown', 'value')]
)
def display_dropdown_contents(val):
    return 'you have selected {}'.format(val)

if __name__ == ' __main__':
    app.run_server(debug=True)

```

---

<div class="post-metadata">

**Author:** ![makn87](https://avatars.discourse-cdn.com/v4/letter/m/f14d63/32.png) [@makn87](https://community.plotly.com/u/makn87)\
**Post date:** [June 5, 2018, 2:27pm UTC](https://community.plotly.com/t/multipage-persistence/10682/3 "2018-06-05T14:27:08Z")

</div>

Thanks for the quick reply!  
I plugged this in and was able to see the point you were making.

My real use case is that I have a dropdown component (which you’ve created in app.layout) that allows me to select from a list of white space delimited data files. The files can range in size from several K up to 8G.

I read the data files in as dataframes, and then do some processing in app.layout.

I have about 4 different ‘app.py’ files (my multipages). Each app[1-4].py file has several callbacks that do further filtering, processing,plotting of the dataframe’s content

What I really want to do is read a file in, do the processing once, and then make the dataframe available to the the different app[1-4].py files.

I had been processing and converting the dataframe to json in app.layout, and staching it in a hidden div.

I had previously been able to get the data to persist between pages.

I couldn’t figure out how to make the data in the hidden div serve as input to the callbacks in the app[1-4].py files.

I’ll try to emulate your example. Thanks

---

<div class="post-metadata">

**Author:** ![stefancoe](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@stefancoe](https://community.plotly.com/u/stefancoe)\
**Post date:** [April 20, 2019, 3:45pm UTC](https://community.plotly.com/t/multipage-persistence/10682/4 "2019-04-20T15:45:15Z")

</div>

This is just what I was looking for! Is there any chance you can provide the same example in a multi-page app format? Thanks!

-Stefan

---

<div class="post-metadata">

**Author:** ![nedned](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/nedned/32/8795_2.png) [@nedned](https://community.plotly.com/u/nedned)\
**Post date:** [April 21, 2019, 12:24am UTC](https://community.plotly.com/t/multipage-persistence/10682/5 "2019-04-21T00:24:51Z")

</div>

Can you elaborate on what you mean?

@charleyferrari’s example is already a multi page Dash app.

---

<div class="post-metadata">

**Author:** ![stefancoe](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@stefancoe](https://community.plotly.com/u/stefancoe)\
**Post date:** [April 21, 2019, 3:59am UTC](https://community.plotly.com/t/multipage-persistence/10682/6 "2019-04-21T03:59:03Z")

</div>

Sorry- that was unclear. I meant implemented as either structure shown by the last two examples in this tutorial:

[https://dash.plot.ly/urls](https://dash.plot.ly/urls)

---

<div class="post-metadata">

**Author:** ![nedned](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/nedned/32/8795_2.png) [@nedned](https://community.plotly.com/u/nedned)\
**Post date:** [April 21, 2019, 5:20am UTC](https://community.plotly.com/t/multipage-persistence/10682/7 "2019-04-21T05:20:03Z")

</div>

It’s pretty straight forward to adapt either of them. Grab the one you want, then in `index.py`, just put all your components that you want to persist across pages before the div that is being swapped out for different pages. Which is to say before:

```python
html.Div(id='page-content')

```

---

<div class="post-metadata">

**Author:** ![stefancoe](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@stefancoe](https://community.plotly.com/u/stefancoe)\
**Post date:** [April 21, 2019, 3:07pm UTC](https://community.plotly.com/t/multipage-persistence/10682/8 "2019-04-21T15:07:43Z")

</div>

Thanks! I’ll give it a shot.

---

<div class="post-metadata">

**Author:** ![darwinhar](https://avatars.discourse-cdn.com/v4/letter/d/ecc23a/32.png) [@darwinhar](https://community.plotly.com/u/darwinhar)\
**Post date:** [November 20, 2019, 3:00am UTC](https://community.plotly.com/t/multipage-persistence/10682/9 "2019-11-20T03:00:40Z")

</div>

Sorry for reviving the thread, I tried to make based on the sample I found in [https://dash.plot.ly/urls](https://dash.plot.ly/urls).

Every time I tried to input my URL manually, it gives me !  
[31|690x242](https://community.plotly.com/uploads/short-url/umQgjd2RQSFspoGG7FCRK33JhSZ.png)

This is my app.py

```auto
import dash
import dash_bootstrap_components as dbc
from flask_caching import Cache
import os

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css', "https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap-grid.min.css", dbc.themes.CERULEAN]
app = dash.Dash( __name__ , external_stylesheets=external_stylesheets, url_base_pathname='/apps/app1/')

cache = Cache(app.server, config={
    # try 'filesystem' if you don't want to setup redis
    'CACHE_TYPE': 'filesystem',
    'CACHE_DIR': 'cache-directory'
})
server = app.server
app.config.suppress_callback_exceptions = True

timeout = 20

```

this is my index.py

```auto
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc

from app import app
from layouts import layout1, layout2, layout3, layout4, layout5, layout6, layout7, layout8, layout9, layout10, layout11, layout12, layout0, layoutProt
import callbacks

navbar = dbc.NavbarSimple(
    children=[
        dbc.NavItem(dbc.NavLink("?~C~@?~B??~C??~C??~C??~C~I", href="/apps/app1/")), #1
        dbc.NavItem(dbc.NavLink("?~I?徴", href="/apps/app2/")), # 2,3,5,7,8
        dbc.NavItem(dbc.NavLink("OS", href="/apps/app3/")), #10
        dbc.NavItem(dbc.NavLink("?~I?徴?~H~F?~C", href="/apps/app4/")), #4,6
        dbc.NavItem(dbc.NavLink("?~H??~T?", href="/apps/app5/")),#11
        dbc.NavItem(dbc.NavLink("?~V?~C??~B??~C~W?~C??~C??~C??~B?", href="/apps/app6/")), #12
    ],
    brand="test ?~B??~C~^?~C??~C?",
    brand_href="/test",
    brand_style={'font-size':'medium'},
    sticky="top",
    style={'font-size':'medium'},
)

app.layout = html.Div([
    dcc.Location(id='url', refresh=False),
    navbar,
    html.Div(id='page-content')
])

@app.callback(Output('page-content', 'children'),
              [Input('url', 'pathname')])
def display_page(pathname):
    if pathname == '/apps/app1/':
        return layout1
    elif pathname == '/apps/app2/':
        return layout2
    elif pathname == '/apps/app3/':
        return layout3
    elif pathname == '/apps/app4/':
        return layout4
    elif pathname == '/apps/app5/':
        return layout5
    elif pathname == '/apps/app6/':
        return layout6
    elif pathname == '/test/':
        return layout0
    elif pathname == '/apps/appProt/':
        return layoutProt
    else:
        return layout0

if __name__ == ' __main__':
    app.run_server(debug=True,dev_tools_ui=True,dev_tools_props_check=True, host='0.0.0.0')

```

Going to the link by typing xxxx/apps/app1/ is fine, Going to other links using hyperlink inside the page is OK.  
Problem is going to every other links by typing gives me that error.
