Clientside callbacks in multi-page Dash app

Hi,

I have created a multi-page Dash app whose performance I would like to optimise by implementing clientside callbacks instead of regular Dash callbacks.

My multi-page Dash app is structured with 1 page per file, as recommended in Dash’s documentation. This means that in app.py, which is where I run the Dash app from, I declare the app variable and change the pages to be displayed according to the pathnames (code from docs):

from dash import Dash, dcc, html, Input, Output, callback
from pages import page1, page2


app = Dash(__name__, suppress_callback_exceptions=True)
server = app.server

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


@callback(Output('page-content', 'children'),
              Input('url', 'pathname'))
def display_page(pathname):
    if pathname == '/page1':
        return page1.layout
    elif pathname == '/page2':
        return page2.layout
    else:
        return '404'

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

Additionally, for each page of the Dash app, I declare the layout of the page and its callbacks. Take for instance page1.py:

from dash import dcc, html, Input, Output, callback

layout = html.Div([
    html.H3('Page 1'),
    dcc.Dropdown(
        {f'Page 1 - {i}': f'{i}' for i in ['New York City', 'Montreal', 'Los Angeles']},
        id='page-1-dropdown'
    ),
    html.Div(id='page-1-display-value'),
    dcc.Link('Go to Page 2', href='/page2')
])


@callback(
    Output('page-1-display-value', 'children'),
    Input('page-1-dropdown', 'value'))
def display_value(value):
    return f'You have selected {value}'

My issue here is in creating a clientside call back for page1.py. From the clientside callbacks documentation, clientside callbacks are declared using app.clientside_callback instead of the usual @app.callback. In multipage Dash apps, callbacks are declared using @callback instead of @app.callback since the app variable is not initialised in the respective pages (such as page1.py). When declaring the clientside callback as merely clientside_callback instead of app.clientside_callback, a NameError: name 'clientside_callback' is not defined is returned. How can this issue be resolved? I appreciate any responses. Thank you!

1 Like

Hi @schua16

Try adding

from dash import clientside_callback

Then you can use it like this:

clientside_callback(
    ....
)

Or:

import dash

dash.clientside_callback(
   ...
)

This was a new feature in dash 2.0 and you can find more into in the announcement, but it looks like it hasn’t made it’s way into the docs yet.

2 Likes

That worked perfectly, thank you!