Different dbc.themes within multi-page app

What’s the simplest way to use dash_bootstrap_components.themes and enable different themes for different pages within a multi-page app?

Looks like all the functionality I would need to download a stylesheet and serve it dynamically might be there in Adding CSS & JS and Overriding the Page-Load Template | Dash for Python Documentation | Plotly but I’m wondering if there’s a one-liner solution I’m missing.

Thanks

@AnnMarieW

Hi @chubukov

There is no one-liner solution that I know of (unless you create an All-in-One component to do this), but you can change the stylesheet with a clientside callback.

This one is triggered by a radio button to switch themes, but it could be modified so that it’s triggered by switching app pages. Note - this is for dash-boostrap-components >=v1.0.0

    # Use 2 style sheet in the app to reduce the flicker when the theme changes
    # example:  app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP, dbc.themes.CYBORG])
    clientside_callback(
        """
        function(url) {            
            var stylesheets = document.querySelectorAll('link[rel=stylesheet][href^="https://cdn.jsdelivr"]')                  
            stylesheets[stylesheets.length - 1].href = url           
        }
        """,
        Output(ids.dummy_div(MATCH), "children"),
        Input(ids.radio(MATCH), "value"),
    )

3 Likes

Thanks @AnnMarieW. This could be great fit for your pages functionality in Dash 2.1 – I imagine this would be a commonly desired feature, and even this seemingly simple clientside callback will take me a few tries to get right.

I agree, and that’s a great suggestion. I’ll add that to the list of feature requests. The multi page app plug-in will be published in dash-labs in the next few days so watch for the announcement :slight_smile:

Hi @chubukov

This is an example of how to specify different themes for pages in a multi-page app.

See more about multi-page apps in dash-labs https://github.com/plotly/dash-labs/blob/main/docs/08-MultiPageDashApp.md

You can specify a different theme for an app in pages/'by supplying the theme like this:

dash.register_page(__name__, theme=dbc.themes.CYBORG)

Now the theme prop can be used to update the theme in a callback. This demo uses the ThemeChangerAIO component from the dash-bootstrap-templates library to change the theme.

See the code for this example here: HelloDash/gallery/multi_page_example at main · AnnMarieW/HelloDash · GitHub

It also includes Bootstrap-themed figure templates and the dbc class to style Dash Core Components and the DataTable with a Bootstrap theme. See more info and a live demo of those features here:

Note: requires dash-labs>=1.01 dash-bootstrap-components>=1.0 dash-bootstrap-templates>=1.04

theme_change_multi_page

1 Like

Beautiful. This will be the final incentive to switch to the new pages functionality :slight_smile:

Thank you!

1 Like

I have been using the new pages functionality and ThemeSwitchAIO and I love them both, but I haven’t found a way to make an ‘app-wide’ switch whose value persists across multiple pages?
2 cases:
-if I declare the switch on the app.py main page, then its value doesn’t propagate when I switch pages: it keeps its position (left/right) but when I switch page they start on the ‘right theme’ no matter what, even if the switch is on the left.
-right now I have one switch in each page’s layout, but obviously their values are independent and when I change page it resets to the default.
Sorry if my language is not very clear.

Hi @bsauvage,

I can’t seem to recreate the problem. If I have a theme switch component only in the app.py file, then it stays persistent throughout the app.

In the example above, it showed how to over-ride the switch and set a theme for each page. Are you following that? If you don’t want t fixed theme for each page, then there is no need to set a theme like this:
dash.register_page(__name__, theme=dbc.themes.CYBORG)
`

It works! I think that was the problem. Thank you very much.

1 Like