How do you combine Variable Paths and Multiple Pages within One File

I am using and as my references to create a Multi-Page app. I have Variable Paths working properly with all of my layouts in a /pages folder, but I would like to have everything in a single file. When I do so, I cannot figure out how get the URL argument passed to the layout function.

The documentation states: path_template: Add variables to a URL by marking sections with <variable_name>. The layout function then receives the <variable_name> as a keyword argument. e.g. path_template= “/asset/<asset_id>” then if pathname in browser is “/assets/a100” then layout will receive **{“asset_id”:“a100”}

but that doesn’t seem to be working when I define my own layout function as is necessary when using a single file. In the example below, kwargs is always null, even when a report path is set in the URL:

here is my code:

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

def layout_analytics():
    return html.Div([
        html.H1('This is our Analytics page'),
            "Select a city: ",
                options=['New York City', 'Montreal', 'San Francisco'],

def layout_archive():
    return html.Div([
        html.H1('This is our Archive page'),
        html.Div('This is our Archive page content.')

def layout_home_page():
    return html.Div([
        html.H1('This is our Home page'),
        html.Div('This is our Home page content.'),

def layout_report(**kwargs):
    return html.Div([
        html.H1('This is our Reports page'),
        html.Div(f'Requested report: ? kwargs={kwargs}'),

app = Dash(__name__, use_pages=True, pages_folder="")

dash.register_page("home", path='/', layout=layout_home_page())
dash.register_page("analytics", layout=layout_analytics())
dash.register_page("archive", layout=layout_archive())
dash.register_page("report", path_template="/report/<report_id>",

app.layout = html.Div([
            dcc.Link(f"{page['name']} - {page['path']}", href=page["relative_path"])
        ) for page in dash.page_registry.values()

    Output('analytics-output', 'children'),
    Input('analytics-input', 'value')
def update_city_selected(input_value):
    return f'You selected: {input_value}'

if __name__ == '__main__':

My layouts are quite complex and already defined within an OO structure so this is just an example to see whether I can plug everything in correctly or not. I have things working with URL parameters in a fishy way, but I really would prefer the pages working in this manner.


Thanks for the awesome minimal example :medal_sports: It makes helping with a solution so much easier.

Try changing this one line:

dash.register_page("report", path_template="/report/<report_id>",


dash.register_page("report", path_template="/report/<report_id>",

Need to provide the function to the layout – but not call the function. More info here in the dash-docs

On a side note… why do you want to put all this into a single file?

oh, total my bad, I have this right in my actual program, but just missed it in the demo. I would have expected a harder error than just having it not get the kwargs right.

The reason I prefer single page is my program is huge. I can have all my Inputs, Outputs, callbacks in the file for consistent edits. I have been using multi-page before this newer, cooler rev and my code is OO using the following structure:


  • - all the generic defs and routines
  • - all the callbacks
  • - all the layouts
  • - all the query calls needed by graph and table
  • - all the graphs
  • - all the tables
  • - all of the strings (framework if translation is ever necessary)

for much better organization. I found a way to make a global object and get it passed and working in the /pages/ files, but still prefer it all in one file instead of spread out there.

Hmm, I’d recommend taking a look here:

In my own project at work, I have multiple pages in the pages folder. Splitting out callbacks, functions and common imports into a utils folder.

Mind you, I am converting from flask templates, which have to be separated.

With all this said, I prefer having the pages separated because it makes it easier for a team to maintain. (Less merge conflicts)