Using plotly dash + pages + dcc.Tab - page referencing not working

Oh i see. For that you need to change url. Try this:

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

app = dash.Dash(__name__, use_pages=True)

app.layout = html.Div([
    html.H1('Dashboard'),
    
    dcc.Tabs(id="tabs", value='page1', children=[
        dcc.Tab(label='Tab 1', value='page1'),
        dcc.Tab(label='Tab 2', value='page2'),
        dcc.Tab(label='Tab 3', value='page3'),
    ]),

    dash.page_container,
    dcc.Location(id="url"),
])

@callback(
    Output("url", "pathname"),
    Input("tabs", "value"),
)
def render_content(tab):
    return f"/{tab}"

if __name__ == '__main__':
    app.run_server(debug=True)

I haven’t tried this exactly but the callback works for me.

EDIT:
I revised your posted code and caught an error in both your pages. You have to define proper paths for them. Lets say you are at url http://127.0.0.1:8050/. This means the page you are displaying has path “/”. In your case page1 which is fine, but you can’t pass value of tab1 as page1 but as /. The second page doesn’t have a path defined.

This code works fine, but the catch is after you pass a new url a new page is loaded which means it will reset tabs to original state.

app.py

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

app = dash.Dash(
    __name__,
    use_pages=True,
    suppress_callback_exceptions=True,
)

app.layout = html.Div(
    [
        html.H1("Dashboard"),
        dcc.Tabs(
            id="tabs",
            children=[
                dcc.Tab(label="Tab1", value="page1"),
                dcc.Tab(label="Tab2", value="page2"),
                dcc.Tab(label="Tab3", value="page3"),
            ],
        ),
        dash.page_container,
        dcc.Location(id="url"),
    ]
)


@callback(
    Output("url", "pathname"),
    Output("tabs", "value"),
    Input("tabs", "value"),
)
def render_content(tab):
    if tab.startswith("page"):
        print(tab)
        return f"/{tab}", tab

    else:
        return dash.no_update


if __name__ == "__main__":
    app.run_server(debug=True)

pages/home.py

import dash
from dash import html, dcc

dash.register_page(__name__, path="/", name="Home")

layout = html.Div(
    [
        html.H1("Home"),
        html.Div("This is the content of home page. Pick a tab!"),
    ]
)

pages/page1.py

import dash
from dash import html, dcc

dash.register_page(__name__, path="/page1", name="Page 1")

layout = html.Div(
    [
        html.H1("Page 1"),
        html.Div("This is the content of page 1"),
        dcc.Input(id="input-box"),
        html.Div(id="output-text"),
    ]
)

pages/page2.py

import dash
from dash import html, dcc

dash.register_page(__name__, path="/page2", name="Page 2")
layout = html.Div(
    [
        html.H1("Page 2"),
        html.Div("This is the content of page 2"),
        dcc.Input(id="input-box"),
        html.Div(id="output-text"),
    ]
)

Maybe replace tabs with links as it is displayed in docs or check out my approach from the original response. If you are really set on tabs and page_container check out this debate:
https://community.plotly.com/t/combining-dcc-tabs-and-dcc-location/27831

Personally i think it’s just too much hastle. Just define layouts inside each Tab and be happy :smiley:

1 Like