Why my multi page app only shows the home page?

Hello Everyone,

I have written a multi page app using the format introduced here: Multipage app. similarily I have multipage that plots different charts. However, I have this problem that when I run the code, it only shows the Home page where I have placed path=‘/’ in dash.register_page(name, path=‘/’, name=‘Line Plot’), and for the rest of the pages it shows 404 - Page not found. When I change the home page to another page by moving the path=‘/’, the new page shows the written content and the old one that was working before shows 404 - Page not found.

Any help would be appreciated.

Hi @Peyman

Can you make a simple example that reproduces the issue?

1 Like

Hello @AnnMarieW

Here is an example of my problem.

  1. I have this code in app.py :
from dash import Dash, html, dcc, Input, Output, State
import dash_bootstrap_components as dbc
from dash_iconify import DashIconify

app = Dash(__name__, use_pages=True, external_stylesheets=[dbc.themes.SUPERHERO])

sidebar = dbc.Nav([
            dbc.NavLink([
                html.Div(page["name"], className="ms-2", style={}),
            ],  href=page["path"], style={},
                active="exact",
            )

            for page in dash.page_registry.values()
         ], vertical=True,
            pills=True,
            className="bg-dark",
)

download_icon = DashIconify(icon='ic:baseline-menu', width=40, style={})

app.layout = dbc.Container([

    dbc.Row([
        dbc.Col([
            dbc.Button([download_icon, ''], id="open-offcanvas", n_clicks=0),
        ], width=1,
            style={'margin-left': 0,
                   'padding': 10}
        ),

        dbc.Col(
            html.Div("Dashboard",
                style={'fontSize': 40,
                       'textAlign': 'center',
                       }
            )
        )
    ]),

    html.Hr(
        style={'margin-top': 0, 'opacity': 1}
    ),

    dbc.Row([
        dbc.Offcanvas(
            dbc.Col([sidebar], width=12),
            id="offcanvas", title="Menu", is_open=False,
            style={'width': 300, 'top': 60,
                   'background-color': '#242A33',
            },


        ),
    ],),

    dbc.Row([
        dbc.Col([dash.page_container])
    ])
], fluid=True,
)


@app.callback(
    Output("offcanvas", "is_open"),
    Input("open-offcanvas", "n_clicks"),
    [State("offcanvas", "is_open")],
)
def toggle_offcanvas(n1, is_open):
    if n1:
        return not is_open
    return is_open

if __name__ == "__main__":
    app.run(debug=True)
  1. in pages folder and in heatmap1.py:
from dash import Dash, html, dcc, Output, Input, State, MATCH, ALL, callback
import plotly.express as px
import pandas as pd
import numpy as np
import dash_bootstrap_components as dbc

dash.register_page(__name__, path='/', name='Heat Map1')

layout =    dbc.Row([
                dbc.Col([
                    dcc.Dropdown(id='test1',
                                options=['var1', 'var2'],
                                clearable=True,
                                value=['var1']
                                )
                    ], width=1,
                ),
            dbc.Row([
                dbc.Col([
                    dcc.Graph(id='graph1',
                              figure={}
                              )
                ]),
            ])
])

@callback(
    Output('graph1', 'figure'),
    Input('test1', 'value'),
    prevent_initial_call=True
)
def update_graph2(z):
    x, y = np.arange(101), np.arange(101)
    path = 'C:/Users/.../'
    df = pd.read_csv(path + z + '.csv')
    fig1 = px.imshow(df,
                    labels=dict(x="X", y="Y", color="Z"),
                    x=x, y=y
                    )
    return fig1
  1. in pages folder and in heatmap2.py:
from dash import Dash, html, dcc, Output, Input, State, MATCH, ALL, callback
import plotly.express as px
import pandas as pd
import numpy as np
import dash_bootstrap_components as dbc

dash.register_page(__name__, name='Heat Map2')

layout =    dbc.Row([
                dbc.Col([
                    dcc.Dropdown(id='test2',
                                options=['var1', 'var2'],
                                clearable=True,
                                value=['var1']
                                )
                    ], width=1,
                ),
            dbc.Row([
                dbc.Col([
                    dcc.Graph(id='graph2',
                              figure={}
                              )
                ]),
            ])
])

@callback(
    Output('graph2', 'figure'),
    Input('test2', 'value'),
    prevent_initial_call=True
)
def update_graph2(z):
    x, y = np.arange(101), np.arange(101)
    path =  'C:/Users/.../'
    df = pd.read_csv(path + z + '.csv')
    fig1 = px.imshow(df,
                    labels=dict(x="X", y="Y", color="Z"),
                    x=x, y=y
                    )
    return fig1

To run the codes it needs a csv file with 101*101 shape.

HI @Peyman

To start I ran your code without the callbacks in the heatmap1.py and heatmap2.py files. ( I didn’t want to create the data).

I had to add import dash to each file, but other than that, it worked fine. Can you see if that works for you? if so, the then problem is in your data or callback and not in the navigation.

Also, will you add this to the app.py file and say what version of dash you are running?

print(dash.__version__)
1 Like

Dear @AnnMarieW

I run the code without callbacks in heatmap1.py and heatmap2.py, and still, it is not working properly.
I think import dash was missed during copy/paste.
my dash version shows 2.6.2

Hmm - that’s odd. Still works for me. I added a label to the dropdown on each page so you could see the difference. Can you put an example in GitHub?

heatmap

1 Like

@AnnMarieW
Yes, weird. definitely, I am making a mistake somewhere. Maybe the way I created the pages Folder?

Do you mean the same example I used here?

Yes, it’s easier if it’s a minimal example.

1 Like

Dear @AnnMarieW
Thanks for your help. I don’t know how, but my problem was solved. I renamed the python files, and re-run the code and it is working now. I had renamed them before and nothing happened. very strange.

Glad you got it working :slight_smile:

1 Like

Hi y’all, not sure if older threads are monitored. I ran into a similar issue while creating my own multi-page Dash app. Renaming files for whatever reason breaks the application.

My app structure is as follows:
app.py
pages
|_ contour.py
|_ heatmap.py
|_ table.py

These pages are accessible via 127.0.0.1:8050/contour + 127.0.0.1:8050/heatmap + 127.0.0.1:8050/table, just as expected.

However, I changed the filenames to contourFPM.py, heatmapFPM.py, and tableFPM.py. I thought dash.register_page(name) would take care of this name change, and that 127.0.0.1:8050/contourFPM would return the correct page. This isn’t the case though, all new links to the re-named files returns a 404 Page not Found.

Any help would be appreciated :slight_smile: Thank you!

Hi @liuto

Are you setting the path when you register the page? If not, Pages creates a path from the file name changing _ to - and making it lower case.

When you get unexpected results like this, it can be handy to inspect the dash.page_registry dict to see what values were inferred if you didn’t set them explicitly.

You can also use this handy print_registry utility to make it easier to see the details.

1 Like

Thank you! Inspecting dash.page_registry was very helpful, and knowing that the name becomes lowercase fixed my issue as well :slight_smile:

1 Like