📣 Introducing Dash `/pages` - A Dash 2.x Feature Preview

Hey @ngaunguyens Glad you got it working, but that example was a special use case: How to make each page of a multi-page a different theme. (I’m not sure why somenone would want to do that, but it’s possible)

Typically, you would make the theme switch component available on all pages. Here’s how:

  • Include the theme switch component in the main layout of app.py so it’s available globally on all pages.
  • Use a callback to update the figure template in each graph when the theme changes. You can find examples of this here: Dash Bootstrap Theme Explorer
1 Like

I believe I may have found a bug with the meta tag information. I’ve been playing around with it quite a bit and I can’t seem to get my links to display as shareable cards on Twitter. I believe there are a few issues with a some of the meta tags set in the interpolate index function that generates the header information.

Based on playing around with meta tags on https://metatags.io/, I’ve found the following:

The twitter:card property tells Twitter the type of card to display, so instead of passing the description in, we should use the following.
<meta property="twitter:card" content="summary_large_image">
More information on Twitter cards can be found at the following url:

Additionally, the twitter:url is supposed to point to the link you are sharing instead of to https://metatags.io/.

For all the image tags twitter:image and og:image, I believe they need to be absolute paths to where the images are hosted online (i.e. http://www.website.com/assets/image.png instead of relative paths /assets/image.png. The current implementation will always be the image provided appended to /assets/.

1 Like

Hi @raptorbrad

Thanks for reporting! This should be fairly easy to fix. I’ve opened an issue to track it, and as soon as it’s resolved we can do another release.

Pull requests are gleefully accepted :slight_smile:

I opened a pull request, but was unable to completely test it as I don’t have a free domain/server I can test with. The idea of what needs to be done is there though! And updated documentation of course

@raptorbrad – Awesome! Thanks with glee :partying_face:


:mega: dash-labs V1.0.8 is now available

I’m pleased to announce some new features and bug fixes for the pages plug-in available in dash-labs 1.0.6.

:new: property: image_url

The pages plug-in automatically creates the meta-tags which describe a page’s content when you share a link on social media. If you would like to include an image, you can now either use an image file from the assets folder, or a link to an image using the image_url property. This is handy if you would like to host your images on a third party site or CDN.

dash.register_page(__name__, image_url="https//site.com/path/to/myimage.png")

If no image_url is provided, it will search the assets folder for an image as previously described in the documentation.

Thanks to @raptorbrad for the contribution! :medal_sports:

:new: dash_labs.print_registry()

When debugging a pages app, it’s very helpful to inspect the content of the dash.page_registry. If you simply
print(dash.page_registry) it can include a lot of data that’s hard to read.

print_registry() is a handy utility that pretty prints all or part of the dash.page_registry dict.

Examples for print_registry()

from dash import Dash, html
import dash
import dash_labs as dl

app = Dash(__name__, plugins=[dl.plugins.pages])

dash.register_page("another_home", layout=html.Div("We're home!"), path="/")


Will print to the console:

{'another_home': {'module': 'another_home',
                  'supplied_path': '/',
                  'path_template': None,
                  'path': '/',
                  'supplied_name': None,
                  'name': 'Another home',
                  'supplied_title': None,
                  'title': 'Another home',
                  'description': '',
                  'order': 0,
                  'supplied_order': None,
                  'supplied_layout': Div("We're home!"),
                  'image': None,
                  'supplied_image': None,
                  'image_url': None,
                  'redirect_from': None,
                  'layout': Div("We're home!")}}

print_registry(modules='ALL', exclude=None, include='ALL')


  • module: (string or list) Default “ALL”. Specifies which modules to print.
  • exclude: (string or list) Default None. Specifies which of the page’s parameter(s) to exclude.
  • include: (string or list) Default “ALL”. Prints only the parameters that are specified.


  • print_registry() Will print the entire content of dash.page_registry
  • print_registry("pages.home") will print only one module
  • print_registry(__name__) will print the current module. When called from app.py it will print all modules. If called from a file in the pages folder dash.page_registry may not be complete.
  • print_registry(["pages.home", "pages.archive"]) Will print 2 modules
  • print_registry(exclude="layout") will print info for all the modules, but will exclude the page[“layout”]
  • print_registry(include=["path", "name"] will print only the page[“path”] and page[“name”] for all modules
  • `print_registry(include=None) prints the keys (module names) only

:beetle: Bug fixes:

  • Fixed a UTF-8 error when opening files - thanks for reporting @adamschroeder
  • Fixed a bug in the meta tags. Now when sharing links on Twitter, the card is formatted correctly, includes an image(if any) and the link to the page works. Thanks for reporting and for the PR to fix it @raptorbrad

What’s the correct way to programmatically redirect to/display a different page? I.e. other than the user clicking on a link?
I tried setting a callback output to the pathname of a dcc.Location element. That did change the URL but did not display the relevant page. If I add another output to be the refresh of dcc.Location and set that to true then that works BUT it does a full refresh/reload of the page and so is very slow (compared to clicking on a nav link).
I feel I’m missing something obvious here?!

Hi @cokelid and welcome to the Dash community :slightly_smiling_face:

You are correct - if you update the pathname in a callback, the dcc.Location must include refresh=True

Having the ability to update the pathname in a callback without refreshing the page would be a nice feature. I’ll open an issue to track the request.

Thanks @AnnMarieW, I appreciate the speedy response!
Is this the only way to programmatically change page? Or is there a better way than setting the pathname in dcc.Location?

Updating the pathname is the only way I can think of to change the page with a callback. Of course there are other ways the user can change the page other than clicking on a link made with dcc.Link, such as clicking on an image, button or any other component wrapped in a html.A However, I believe that will also refresh the page.

Also, there might be other techniques to make a page refresh faster - for example like caching intermediate data.

Thanks again for the response! There’s definitely a lot more going on with a refresh via callback. Profiling with Chrome gives me 300ms to load a new page via clicking a link, or 1500ms via a callback refresh. The latter appears to do a “full” refresh (like a ctrl-F5)?

Just curious, what’s your use case?

I suppose you might call it context-specific search results, but specifically it’s a about displaying different dashboards (different pages) for different product types.
I have a text input for product code. If the user enters the product code for ice cream (and hits enter) they get the frozen food dashboard for that product. If they enter the product code for apples, they get the fresh fruit and veg dashboard, which is quite different to, and the data source is entirely separate from, frozen foods.
I expect to support a large number of customized dashboards for different types and sub-types, and pages seem the right way to go.
In addition, having URLs for a specific dashboard/product that users can share via email and IM is important (e.g. local.tld/frozen?prodcode=123456)

Thank you for this quick tutorial.
Please how can I add an interval that gets a fresh data from a server every period of time to this type of dashboards
And thanks in advance.

How can I add an interval that update and get fresh data from a server every period of time to this type of dashboard? and thanks in advance

Since the update my pages wont be registered in the page_registry and I do not know why.

I use this code:

print("Greife auf: bevgem zu")

import dash

from dash import dcc, html ,callback

from dash.dependencies import Output, Input, State

import dash_bootstrap_components as dbc

import plotly.graph_objects as gp

import numpy as np

import pandas as pd

import plotly.express as px

import geopandas

import os



The structure is still the same as with dash labs:

1 Like

Updating from 4.1 with dash_labs plugin to 5.1 without dash_labs plugin, the pages of my app disappeared.
I commented import dash_labs as dl and plugins=[dl.plugins.pages], in

app = dash.Dash(
    # plugins=[dl.plugins.pages],

and I changed dl.plugins.page_container to dash.page_container, but I guess that multipage apps migrating from plugin to 5.x need some more fixes.

Any clue?

Which operating system are you using? I recently found a bug on Windows and made a fix, but I’m not sure that it has been included in a release yet.

The app runs on Ubuntu 20.04 installed upon WSL2/Windows10.

Hmm, it could possibly be the same issue I ran into on Windows. Long story short, Windows handles paths slightly different than Unix based systems, like Ubuntu and MacOS. The pages feature was not accounting for this difference.

I’m not super familiar with the Windows Linux subsystem and how the paths work, but this could be the case.

A fix is coming soon for the paths problem, but I’m not 100% sure if this will fix your issue or not.