šŸ“£ Introducing Dash `/pages` - A Dash 2.x Feature Preview

I just tested it on Dash 2.0, and it seems to work just fine. Here is a small app that demonstrates the concept,

from dash_extensions.enrich import DashProxy, html, Output, Input, dcc
from dash_extensions.multipage import app_to_page, PageCollection, CONTENT_ID, URL_ID


def get_page(i: int):
    # Create a small app that represents the desired page.
    app = DashProxy()
    app.layout = html.Div([html.Button("Click me", id="btn"), html.Div(f"I am app {i}", id="log")])

    @app.callback(Output("log", "children"), Input("btn", "n_clicks"))
    def on_click(n_clicks):
        return f"You clicked {n_clicks} times!"

    # Convert the app to a page.
    return app_to_page(app, id=f"app{i}", label=f"App {i}"). # the id argument here is the prefix


# Create a few pages.
pc = PageCollection([get_page(i) for i in range(5)])
links = [html.A(children=page.label, href="/{}".format(page.id)) for page in pc.pages]
# Embed the pages in the main app.
app = DashProxy(suppress_callback_exceptions=True, prevent_initial_callbacks=True)
app.layout = html.Div(links + [html.Br(), html.Div(id=CONTENT_ID), dcc.Location(id=URL_ID)])
# Register callbacks.
pc.navigation(app)
pc.callbacks(app)

if __name__ == '__main__':
    app.run_server(port=8889)

It embeds five pages that all have ID clashes, but the difference in prefixes make it work.

Screenshot 2022-01-11 at 20.32.53