Dash bootstrap component nav link relative paths dont work

Hi everyone!

I’m using dash bootstrap component to create a simple page layout with navbar and 3 containers. I have the links of the Navbar buttons going to 3 divs that I currently have (id=‘about’ and id=‘start’ and id=‘rec’).

The links work when I use absolute paths:

navbar = dbc.NavbarSimple(
children=[
    dbc.NavItem(dbc.NavLink("About", href="http://127.0.0.1:8050/#about")),
    dbc.NavItem(dbc.NavLink("Start", href="http://127.0.0.1:8050/#start")),
    dbc.NavItem(dbc.NavLink("Recommend", href="http://127.0.0.1:8050/#rec")),
   ],
brand="Home",
brand_href="#",
sticky="top",
)

but not when I use relative paths:

navbar = dbc.NavbarSimple(
children=[
    dbc.NavLink("About", href="#about"),
    dbc.NavLink("Start", href="#start"),
    dbc.NavLink("Recommend", href="#rec"),
],
brand="Home",
brand_href="#",
sticky="top",
)

With the relative paths, when I click on the “Start” button on my navbar, the link is populated in the search bar like so (“http://127.0.0.1:8050/#start”) but the page is not moved to the div element. When I press enter on the search bar, it does move.

Is there any additional thing I need to import for this to work?

1 Like

Hey @cat0tail,

dbc.NavLink can actually behave as two different kinds of link: a regular HTML hyperlink like you would get if you used html.A, or a component that behaves like dcc.Link. What dcc.Link does is update the url without refreshing the page. By combining this with dcc.Location you can monitor the url and change the layout, giving the illusion of navigating between pages without reloading the whole app. A side-effect of this is that you can’t use the # style links to jump to certain elements on the page.

dbc.NavLink tries to be smart and guess which type of link you would like, opting for dcc.Link if you supply a relative path, and a regular hyperlink if you supply an absolute path, that’s why you’re seeing the different behaviour. You can override this though using the external_link keyword argument, which will let you create a regular hyperlink with a relative path.

So TL;DR try adding external_link=True to each of your NavLinks and that should let you jump to particular components on the page. I just tested it out with this simple example and it seemed to work ok for me. Let me know if you have any problems, and also thanks for using dash-bootstrap-components!

import dash
import dash_bootstrap_components as dbc
import dash_html_components as html

app = dash.Dash()

navbar = dbc.NavbarSimple(
    children=[
        dbc.NavLink("About", href="#about", external_link=True),
        dbc.NavLink("Start", href="#start", external_link=True),
        dbc.NavLink("Recommend", href="#rec", external_link=True),
    ],
    brand="Home",
    brand_href="#",
)

app.layout = html.Div(
    [
        navbar,
        html.Div("About", id="about", style={"height": "500px"}),
        html.Div("Start", id="start", style={"height": "500px"}),
        html.Div("Rec", id="rec", style={"height": "500px"}),
    ]
)


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

@tcbegley thanks for the explanation! It works! To clarify though, when I use external link does it reload the whole app? Because I’m wondering if it’s possible to do smooth scrolling if it reloads the whole app?

I don’t think it will. Basically with external_link you’re just handing the link off to the browser to deal with, which in this case should detect that you’re staying on the same page, you just want it to scroll to a new location. When I tested it, it seemed to be scrolling to the right point on the page without reloading the app anyway.

@tcbegley I see thank you! Btw, can I shamelessly ask if you can take a look at another DBC problem I’m having?