Multi-Page Dash as a page of a Flask App

Hello Dash Team!

I’m trying to make a Multi-Page Dash app as a page of a Flask App. And I am getting an error: "raise Exception("`dash.register_page()` must be called after app instantiation")"

This is the structure of my app:

dash_in_flask
│   config.py
│   index.py
│       
├───app
    │   __init__.py
    │   
    ├───my_dashapp
    │   │   assets
    │   │   __init__.py
    │   │   
    │   ├───pages
    |         |  __index.py
    |         ├─────home
    │               |  __init__.py
    │               |  layout.py
    │               |  callbacks.py
    |
    ├───main
    │   |  routes.py
    │   |  __init__.py
    │            
    ├───static
    |
    ├───templates
    |
    ├───Flask_Page1
    |
    ├───Flask_Page2

This is the code in app/__init__.py, where I register my_dashapp

def create_app(config_class):
    app = Flask(__name__)
    app.config.from_object(config_class)
    register_dataview(app, 'my_dashapp', 'my_dashapp', login_required=False)
    return app

def register_dataview(app, title, base_pathname, login_required=False):
    meta_viewport={"name":"viewport", "content":"width=device-width, initial-scale=1, shrink-to-fit=no"}

    my_dashapp = dash.Dash(
        __name__,
        use_pages=True,
        server=app,
        url_base_pathname=f'/',
        assets_folder=base_pathname+'/assets/',
        external_stylesheets=[dbc.themes.SLATE, FONT_AWESOME],
        suppress_callback_exceptions=True,
        meta_tags=[meta_viewport]
    )

    with app.app_context():
        my_dashapp.title = title
        my_dashapp.layout = dbc.Container(
            [dash.page_container],
            fluid=True
        )

    my_dashapp.clientside_callback(
    """
    function(n) {          
        const local_time_str = new Date().toLocaleString();
        const time_str = new Date().toTimeString();        
        const offset = new Date().getTimezoneOffset();             
        return offset/60
    }
    """,
    Output('time_zone_offset', 'data'),
    Input('fake_div', 'children'),
    )

This is the code in app/my_dashapp/pages/home/__init__.py, where I hope to register home as the homepage of my_dashapp

import dash

dash.register_page(__name__, path="/")

from app.DVDash.pages.home import layout
from app.DVDash.pages.home import callbacks

My app works fine when I didn’t make my_dashapp multi-page. However, it reports error after I tried to do so. I’m wondering if it’s possible to make a Multi-Page Dash app as a page of a Flask App? If so, could you please let me know how should I fix this? Thank you in advance!

Hi @whax

With this project structure, it may be better not to use the new pages feature to make multi-page apps.

The good news is that the previously recommended way to make multi-page apps still works. See the docs starting at the section multi-page apps without pages.

Hello @AnnMarieW

Thank you so much for your reply! The reason I am trying to make it multi-page is that I hope to enable query string parameters in a URL for my_dashapp. So when users visit the app with URLs that have search properties, the app can load forms and graphs according to params in URLs. If I don’t use the new pages feature to make my_dashapp multi-page, I’m wondering if the only solution will be using dcc.location and callbacks? More specifically, let the URL (dcc.location) be the input and the forms and graphs be output in callbacks. Is this the best way to do this?

Really appreciate your help!

Yes, that would be the solution. Is there a reason you need to make it a page of a Flask App? The new pages features makes things so much easier.