from functools import partialfrom shiny.express import uifrom shiny.ui import page_navbarui.page_opts( title="App with navbar", page_fn=partial(page_navbar, id="page"), )with ui.nav_panel("A"): "Page A content"with ui.nav_panel("B"): "Page B content"with ui.nav_panel("C"): "Page C content"
from shiny import App, uiapp_ui = ui.page_navbar( ui.nav_panel("A", "Page A content"), ui.nav_panel("B", "Page B content"), ui.nav_panel("C", "Page C content"), title="App with navbar", id="page", ) def server(input, output, session):passapp = App(app_ui, server)
Follow these steps to add a navbar to the top of your app:
Define a navbar page layout with ui.page_navbar().
Pass nav items (e.g., ui.nav_panel() and ui.nav_menu()) to ui.page_navbar() to control the items displayed in the navbar.
Set the title argument of ui.page_navbar() to set the browser window title.
Optional: Pass a string to the id argument of ui.page_navbar(). This will create an input value that holds the title of the currently selected nav item. For example, id = "tab" would create a reactive value accessible as input.tab().
Navbar at bottom
#| '!! shinylive warning !!': |#| shinylive does not work in self-contained HTML documents.#| Please set `embed-resources: false` in your metadata.#| standalone: true#| components: [viewer]#| layout: horizontal#| viewerHeight: 150## file: app.pyfrom shiny import App, uiapp_ui = ui.page_navbar( ui.nav_panel("A", "Page A content"), ui.nav_panel("B", "Page B content"), ui.nav_panel("C", "Page C content"), title="App with navbar", id="page", navbar_options=ui.navbar_options(position="fixed-bottom"), ) def server(input, output, session): passapp = App(app_ui, server)
from functools import partialfrom shiny.express import uifrom shiny.ui import navbar_options, page_navbarui.page_opts( title="App with navbar", page_fn=partial( page_navbar, id="page", navbar_options=navbar_options(position="fixed-bottom"), ), )with ui.nav_panel("A"): "Page A content"with ui.nav_panel("B"): "Page B content"with ui.nav_panel("C"): "Page C content"
from shiny import App, uiapp_ui = ui.page_navbar( ui.nav_panel("A", "Page A content"), ui.nav_panel("B", "Page B content"), ui.nav_panel("C", "Page C content"), title="App with navbar", id="page", navbar_options=ui.navbar_options(position="fixed-bottom"), ) def server(input, output, session):passapp = App(app_ui, server)
Follow these steps to add a navbar to the bottom of your app:
Define a navbar page layout with ui.page_navbar().
Pass nav items (e.g., ui.nav_panel() and ui.nav_menu()) to ui.page_navbar() to control the items displayed in the navbar.
Pass navbar_options=ui.navbar_options(position="fixed-bottom") to ui.page_navbar() to pin the navbar to the bottom of the app. By default, position is "static-top", which causes the navbar to display at the top with normal scrolling behavior. You can also pin the navbar to the top (position="fixed-top").
Set the title argument of ui.page_navbar() to set the browser window title.
Optional: Pass a string to the id argument of ui.page_navbar(). This will create an input value that holds the title of the currently selected nav item. For example, id = "tab" would create a reactive value accessible as input.tab().
Navbar within a page
ui.page_navbar() makes the navbar the whole page layout. If you instead want a navbar as one element among others — with content above or below it — use ui.navset_bar() inside a regular page function such as ui.page_fluid(). It takes the same nav items and the same navbar_options.
#| '!! shinylive warning !!': |#| shinylive does not work in self-contained HTML documents.#| Please set `embed-resources: false` in your metadata.#| standalone: true#| components: [viewer]#| layout: horizontal#| viewerHeight: 300## file: app.pyfrom shiny import App, render, uiapp_ui = ui.page_fluid( ui.h4("Quarterly report"), "This heading and text are outside the navbar.", ui.navset_bar( ui.nav_panel("Summary", "Summary content"), ui.nav_panel("Details", "Details content"), ui.nav_spacer(), ui.nav_panel("About", "About content"), title="Sections", id="section", ), ui.h6("Selected section:"), ui.output_code("selected"),)def server(input, output, session): @render.code def selected(): return input.section()app = App(app_ui, server)
from shiny.express importinput, render, uiui.h4("Quarterly report")"This heading and text are outside the navbar."with ui.navset_bar(title="Sections", id="section"): with ui.nav_panel("Summary"): "Summary content"with ui.nav_panel("Details"): "Details content" ui.nav_spacer() with ui.nav_panel("About"): "About content"ui.h6("Selected section:")@render.codedef selected():returninput.section()
from shiny import App, render, uiapp_ui = ui.page_fluid( ui.h4("Quarterly report"),"This heading and text are outside the navbar.", ui.navset_bar( ui.nav_panel("Summary", "Summary content"), ui.nav_panel("Details", "Details content"), ui.nav_spacer(), ui.nav_panel("About", "About content"), title="Sections", id="section", ), ui.h6("Selected section:"), ui.output_code("selected"),)def server(input, output, session):@render.codedef selected():returninput.section()app = App(app_ui, server)
Follow these steps to add a navbar inside a page:
Add ui.navset_bar() inside any Shiny UI page method (e.g., ui.page_fluid()). Unlike ui.page_navbar(), it does not have to be the outermost element, so content can appear before and after it.
Set the title argument of ui.navset_bar(). Unlike ui.page_navbar(), this argument is required, and it sets the brand text shown in the navbar rather than the browser window title.
Pass nav items (e.g., ui.nav_panel() and ui.nav_menu()) to ui.navset_bar() to control the items displayed in the navbar.
Optional: Add ui.nav_spacer() between nav items to insert flexible space. Everything after the spacer is pushed to the far side of the navbar — the usual way to right-align an “About” or “Help” item. It works in ui.page_navbar() too.
Optional: Pass a string to the id argument of ui.navset_bar(). This will create an input value that holds the title of the currently selected nav item. For example, id = "section" would create a reactive value accessible as input.section().
Navbar appearance options
ui.navbar_options() collects the options that control how the navbar itself looks. Pass the result to the navbar_options argument of ui.page_navbar() or ui.navset_bar():
position — where the navbar sits: "static-top" (the default), "fixed-top", or "fixed-bottom".
bg — a CSS color for the navbar background.
theme — "dark" for light text on a dark background, "light" for dark text on a light background, or "auto" (the default), which picks whichever contrasts better with bg.
underline — whether nav links get an underline effect. True by default.
collapsible — whether nav items collapse into an expandable menu on narrow screens. True by default.
Any extra keyword arguments become HTML attributes on the navbar container element, so ui.navbar_options(class_="bg-primary", theme="dark") is a convenient way to pick up a Bootswatch theme’s colors.
Note
"fixed-top" and "fixed-bottom" take the navbar out of the normal document flow, so it overlays your content instead of reserving space for itself. Add matching padding to the body to compensate — for example ui.tags.style("body {padding-bottom: 70px;}") alongside a "fixed-bottom" navbar.
WarningSetting these options directly is deprecated
Before Shiny v1.3.0, these options were passed straight to ui.page_navbar() and ui.navset_bar() (for example ui.page_navbar(..., position="fixed-bottom")). That still works, but it emits a deprecation warning. Wrap them in ui.navbar_options() instead: