NavigationRail
A material widget that is meant to be displayed at the left or right of an app to navigate between a small number of views, typically between three and five.
Example:
ft.NavigationRail(
selected_index=0,
height=200,
width=100,
destinations=[
ft.NavigationRailDestination(icon=ft.Icons.STAR, label="Star"),
ft.NavigationRailDestination(icon=ft.Icon(ft.Icons.ADD),label="Add"),
ft.NavigationRailDestination(icon=ft.Icons.DELETE, label=ft.Text("Delete")
],
)

Inherits: LayoutControl
Properties
bgcolor- Sets the color of the Container that holds all of this NavigationRail's contents.destinations- Defines the appearance of the button items that are arrayed within the navigation rail.elevation- Controls the size of the shadow below the NavigationRail.extended- Indicates that the NavigationRail should be in the extended state.group_alignment- The vertical alignment for the group of destinations within the rail.indicator_color- The color of the navigation rail's indicator.indicator_shape- The shape of the navigation rail's indicator.label_type- Defines the layout and behavior of the labels for the default, unextended navigation rail.leading- An optional leading control in the rail that is placed above the destinations.min_extended_width- The final width when the animation is complete for settingextendedtoTrue.min_width- The smallest possible width for the rail regardless of the destination's icon or label size.pin_leading_to_top- Whether to pin theleadingcontrol to the top of the rail.pin_trailing_to_bottom- Whether to pin thetrailingcontrol to the bottom of the rail.scrollable- Whether the main group ofdestinationsshould become scrollable when vertical space is insufficient.selected_index- The index intodestinationsfor the current selectedNavigationRailDestinationorNoneif no destination is selected.selected_label_text_style- TheTextStyleof a destination's label when it is selected.trailing- An optional trailing control in the rail that is placed below the destinations.unselected_label_text_style- TheTextStyleof a destination's label when it is not selected.use_indicator- Whether to add a rounded navigation indicator behind the selected destination's icon.
Events
on_change- Called when selected destination changed.
Examples
NavigationRail
play_arrowTry Online
import flet as ft
def main(page: ft.Page):
rail = ft.NavigationRail(
selected_index=0,
label_type=ft.NavigationRailLabelType.ALL,
min_width=100,
min_extended_width=400,
group_alignment=-0.9,
on_change=lambda e: print("Selected destination:", e.control.selected_index),
leading=ft.FloatingActionButton(
icon=ft.Icons.CREATE,
content="Add",
on_click=lambda e: print("FAB clicked!"),
),
destinations=[
ft.NavigationRailDestination(
icon=ft.Icons.FAVORITE_BORDER,
selected_icon=ft.Icons.FAVORITE,
label="First",
),
ft.NavigationRailDestination(
icon=ft.Icon(ft.Icons.BOOKMARK_BORDER),
selected_icon=ft.Icon(ft.Icons.BOOKMARK),
label="Second",
),
ft.NavigationRailDestination(
icon=ft.Icons.SETTINGS_OUTLINED,
selected_icon=ft.Icon(ft.Icons.SETTINGS),
label=ft.Text("Settings"),
),
],
)
page.add(
ft.SafeArea(
expand=True,
content=ft.Row(
expand=True,
controls=[
ft.SelectionArea(content=rail),
ft.VerticalDivider(width=1),
ft.Column(
alignment=ft.MainAxisAlignment.START,
expand=True,
controls=[ft.Text("Body!")],
),
],
),
)
)
if __name__ == "__main__":
ft.run(main)

Adaptive Navigation
This example switches between a NavigationBar on narrow layouts and a NavigationRail with an end NavigationDrawer on wider layouts.
play_arrowTry Online
import flet as ft
DESTINATIONS = [
("Messages", ft.Icons.WIDGETS_OUTLINED, ft.Icons.WIDGETS),
("Profile", ft.Icons.FORMAT_PAINT_OUTLINED, ft.Icons.FORMAT_PAINT),
("Settings", ft.Icons.SETTINGS_OUTLINED, ft.Icons.SETTINGS),
]
def main(page: ft.Page):
page.theme_mode = ft.ThemeMode.LIGHT
page.padding = 0
screen_index = 0
def build_page_index_text() -> ft.Text:
return ft.Text(f"Page Index = {screen_index}", size=24)
def set_screen(index: int):
nonlocal screen_index
screen_index = index
render()
def build_navigation_bar() -> ft.NavigationBar:
def handle_nav_bar_change(e: ft.Event[ft.NavigationBar]):
set_screen(e.control.selected_index)
return ft.NavigationBar(
selected_index=screen_index,
on_change=handle_nav_bar_change,
destinations=[
ft.NavigationBarDestination(
label=label,
icon=icon,
selected_icon=selected_icon,
)
for label, icon, selected_icon in DESTINATIONS
],
)
def build_navigation_rail() -> ft.NavigationRail:
def handle_nav_rail_change(e: ft.Event[ft.NavigationRail]):
if e.control.selected_index is not None:
set_screen(e.control.selected_index)
return ft.NavigationRail(
min_width=50,
selected_index=screen_index,
use_indicator=True,
on_change=handle_nav_rail_change,
destinations=[
ft.NavigationRailDestination(
label=label,
icon=icon,
selected_icon=selected_icon,
)
for label, icon, selected_icon in DESTINATIONS
],
)
def build_end_drawer() -> ft.NavigationDrawer:
async def handle_drawer_change(e: ft.Event[ft.NavigationDrawer]):
set_screen(e.control.selected_index)
await page.close_end_drawer()
return ft.NavigationDrawer(
selected_index=screen_index,
on_change=handle_drawer_change,
controls=[
ft.Container(
padding=ft.Padding.only(left=28, top=16, right=16, bottom=10),
content=ft.Text(
"Header", theme_style=ft.TextThemeStyle.TITLE_SMALL
),
),
*[
ft.NavigationDrawerDestination(
label=label,
icon=icon,
selected_icon=selected_icon,
)
for label, icon, selected_icon in DESTINATIONS
],
],
)
def build_bottom_bar_layout() -> ft.SafeArea:
return ft.SafeArea(
expand=True,
content=ft.Container(
expand=True,
alignment=ft.Alignment.CENTER,
content=build_page_index_text(),
),
)
def build_drawer_layout() -> ft.SafeArea:
async def open_drawer(e: ft.Event[ft.Button]):
await page.show_end_drawer()
return ft.SafeArea(
expand=True,
avoid_intrusions_top=False,
avoid_intrusions_bottom=False,
content=ft.Row(
expand=True,
controls=[
ft.Container(
padding=ft.Padding.symmetric(horizontal=5),
content=build_navigation_rail(),
),
ft.VerticalDivider(thickness=1, width=1),
ft.Column(
expand=True,
alignment=ft.MainAxisAlignment.SPACE_EVENLY,
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
controls=[
build_page_index_text(),
ft.Button("Open Drawer", on_click=open_drawer),
],
),
],
),
)
def render():
page.clean()
if (page.width or page.window.width) >= 450: # wide layout
page.navigation_bar = None
page.end_drawer = build_end_drawer()
page.add(build_drawer_layout())
else: # narrow layout
page.end_drawer = None
page.navigation_bar = build_navigation_bar()
page.add(build_bottom_bar_layout())
page.update()
page.on_resize = lambda e: render()
render()
if __name__ == "__main__":
ft.run(main)

Properties
bgcolorclass-attributeinstance-attribute
bgcolor: ColorValue | None = NoneSets the color of the Container that holds all of this NavigationRail's contents.
destinationsclass-attributeinstance-attribute
destinations: list[NavigationRailDestination] = field(
default_factory=list
)Defines the appearance of the button items that are arrayed within the navigation rail.
The value must be a list of two or more NavigationRailDestination instances.