Tabs

Tabs and navigation allow you to create Shiny apps with multiple pages.

Tabs and navigation allow you to create apps that have multiple pages.

Relevant Functions

  • ui.accordion
    ui.accordion(*args, id=None, open=None, multiple=True, class_=None, width=None, height=None, **kwargs)

  • ui.accordion_panel
    ui.accordion_panel(title, *args, value=MISSING, icon=None, **kwargs)

  • ui.navset_card_tab
    ui.navset_card_tab(*args, id=None, selected=None, title=None, sidebar=None, full_screen=False, header=None, footer=None)

  • ui.navset_card_pill
    ui.navset_card_pill(*args, id=None, selected=None, title=None, sidebar=None, full_screen=False, header=None, footer=None, placement='above')

  • ui.navset_card_underline
    ui.navset_card_underline(*args, id=None, selected=None, title=None, sidebar=None, full_screen=False, header=None, footer=None, placement='above')

  • ui.navset_hidden
    ui.navset_hidden(*args, id=None, selected=None, header=None, footer=None)

  • ui.navset_pill
    ui.navset_pill(*args, id=None, selected=None, header=None, footer=None)

  • ui.navset_pill_list
    ui.navset_pill_list(*args, id=None, selected=None, header=None, footer=None, well=True, widths=(4, 8))

  • ui.navset_tab
    ui.navset_tab(*args, id=None, selected=None, header=None, footer=None)

  • ui.navset_underline
    ui.navset_underline(*args, id=None, selected=None, header=None, footer=None)

  • ui.update_navset
    ui.update_navset(id, selected=None, session=None)

  • ui.nav_control
    ui.nav_control(*args)

  • ui.nav_menu
    ui.nav_menu(title, *args, value=None, icon=None, align='left')

  • ui.nav_panel
    ui.nav_panel(title, *args, value=None, icon=None)

No matching items

Tabset with pill navigation

#| '!! 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: 190

## file: app.py
from shiny import App, ui

app_ui = ui.page_fluid(
    ui.navset_pill(  
        ui.nav_panel("A", "Panel A content"),
        ui.nav_panel("B", "Panel B content"),
        ui.nav_panel("C", "Panel C content"),
        ui.nav_menu(
            "Other links",
            ui.nav_panel("D", "Panel D content"),
            "----",
            "Description:",
            ui.nav_control(
                ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
            ),
        ),
        id="tab",  
    )  
)


def server(input, output, session):
    pass


app = App(app_ui, server)
from shiny.express import ui

with ui.navset_pill(id="tab"):  
    with ui.nav_panel("A"):
        "Panel A content"

    with ui.nav_panel("B"):
        "Panel B content"

    with ui.nav_panel("C"):
        "Panel C content"

    with ui.nav_menu("Other links"):
        with ui.nav_panel("D"):
            "Page D content"

        "----"
        "Description:"
        with ui.nav_control():
            ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
from shiny import App, ui

app_ui = ui.page_fluid(
    ui.navset_pill(  
        ui.nav_panel("A", "Panel A content"),
        ui.nav_panel("B", "Panel B content"),
        ui.nav_panel("C", "Panel C content"),
        ui.nav_menu(
            "Other links",
            ui.nav_panel("D", "Panel D content"),
            "----",
            "Description:",
            ui.nav_control(
                ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
            ),
        ),
        id="tab",  
    )  
)


def server(input, output, session):
    pass


app = App(app_ui, server)

Follow these steps to create an app with a tabset with pill navigation layout:

  1. Add ui.navset_pill() inside any Shiny UI page method (e.g., ui.page_fluid()). ui.navset_pill() creates a pillset.

  2. Pass nav items (e.g., ui.nav_panel() and ui.nav_menu()) to ui.navset_pill() to set the items displayed in the navset.

  3. Pass arguments to the nav items to control each item’s title, appearance, and associated content. For example, set the title argument of ui.nav_panel() to control the displayed title of the nav item. Pass UI elements as additional arguments to ui.nav_panel(). These elements will be displayed when the tab is active.

  4. Optional: Pass a string to the id argument of ui.navset_pill(). 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().

Tabset with underline navigation

#| '!! 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: 190

## file: app.py
from shiny import App, ui

app_ui = ui.page_fluid(
    ui.navset_underline(  
        ui.nav_panel("A", "Panel A content"),
        ui.nav_panel("B", "Panel B content"),
        ui.nav_panel("C", "Panel C content"),
        ui.nav_menu(
            "Other links",
            ui.nav_panel("D", "Panel D content"),
            "----",
            "Description:",
            ui.nav_control(
                ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
            ),
        ),
        id="tab",  
    )  
)


def server(input, output, session):
    pass


app = App(app_ui, server)
from shiny.express import ui

with ui.navset_underline(id="tab"):  
    with ui.nav_panel("A"):
        "Panel A content"

    with ui.nav_panel("B"):
        "Panel B content"

    with ui.nav_panel("C"):
        "Panel C content"

    with ui.nav_menu("Other links"):
        with ui.nav_panel("D"):
            "Page D content"

        "----"
        "Description:"
        with ui.nav_control():
            ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
from shiny import App, ui

app_ui = ui.page_fluid(
    ui.navset_underline(  
        ui.nav_panel("A", "Panel A content"),
        ui.nav_panel("B", "Panel B content"),
        ui.nav_panel("C", "Panel C content"),
        ui.nav_menu(
            "Other links",
            ui.nav_panel("D", "Panel D content"),
            "----",
            "Description:",
            ui.nav_control(
                ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
            ),
        ),
        id="tab",  
    )  
)


def server(input, output, session):
    pass


app = App(app_ui, server)

Follow these steps to create an app with an underline navigation layout:

  1. Add ui.navset_underline() inside any Shiny UI page method (e.g., ui.page_fluid()). ui.navset_underline() creates a tabset where the selected nav item is underlined.

  2. Pass nav items (e.g., ui.nav_panel() and ui.nav_menu()) to ui.navset_underline() to set the items displayed in the navset.

  3. Pass arguments to the nav items to control each item’s title, appearance, and associated content. For example, set the title argument of ui.nav_panel() to control the displayed title of the nav item. Pass UI elements as additional arguments to ui.nav_panel(). These elements will be displayed when the tab is active.

  4. Optional: Pass a string to the id argument of ui.navset_underline(). 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().

To place an underlined tabset inside a card, use ui.navset_card_underline() instead — see Card with an underline tabset below.

Tabset with pill list navigation

#| '!! 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: 320

## file: app.py
from shiny import App, ui

app_ui = ui.page_fluid(
    ui.navset_pill_list(  
        ui.nav_panel("A", "Panel A content"),
        ui.nav_panel("B", "Panel B content"),
        ui.nav_panel("C", "Panel C content"),
        ui.nav_menu(
            "Other links",
            ui.nav_panel("D", "Panel D content"),
            "----",
            "Description:",
            ui.nav_control(
                ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
            ),
        ),
        id="tab",
    )  
)


def server(input, output, session):
    pass


app = App(app_ui, server)
from shiny.express import ui

with ui.navset_pill_list(id="tab"):  
    with ui.nav_panel("A"):
        "Panel A content"

    with ui.nav_panel("B"):
        "Panel B content"

    with ui.nav_panel("C"):
        "Panel C content"

    with ui.nav_menu("Other links"):
        with ui.nav_panel("D"):
            "Page D content"

        "----"
        "Description:"
        with ui.nav_control():
            ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
from shiny import App, ui

app_ui = ui.page_fluid(
    ui.navset_pill_list(  
        ui.nav_panel("A", "Panel A content"),
        ui.nav_panel("B", "Panel B content"),
        ui.nav_panel("C", "Panel C content"),
        ui.nav_menu(
            "Other links",
            ui.nav_panel("D", "Panel D content"),
            "----",
            "Description:",
            ui.nav_control(
                ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
            ),
        ),
        id="tab",
    )  
)


def server(input, output, session):
    pass


app = App(app_ui, server)

Follow these steps to create an app with a pill list navigation layout. A pill list is a vertical pillset navigation.

  1. Add ui.navset_pill_list() inside any Shiny UI page method (e.g., ui.page_fluid()). ui.navset_pill_list() creates a pill list.

  2. Pass nav items (e.g., ui.nav_panel() and ui.nav_menu()) to ui.navset_pill_list() to set the items displayed in the pillset.

  3. Pass arguments to the nav items to control each item’s title, appearance, and associated content. For example, set the title argument of ui.nav_panel() to control the displayed title of the nav item. Pass UI elements as additional arguments to ui.nav_panel(). These elements will be displayed when the tab is active.

  4. Optional: Pass a string to the id argument of ui.navset_pill_list(). 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().

Tabset with tab navigation

#| '!! 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: 200

## file: app.py
from shiny import App, ui

app_ui = ui.page_fluid(
    ui.navset_tab(  
        ui.nav_panel("A", "Panel A content"),
        ui.nav_panel("B", "Panel B content"),
        ui.nav_panel("C", "Panel C content"),
        ui.nav_menu(
            "Other links",
            ui.nav_panel("D", "Panel D content"),
            "----",
            "Description:",
            ui.nav_control(
                ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
            ),
        ),
        id="tab",  
    )  
)


def server(input, output, session):
    pass


app = App(app_ui, server)
from shiny.express import ui

with ui.navset_pill(id="tab"):  
    with ui.nav_panel("A"):
        "Panel A content"

    with ui.nav_panel("B"):
        "Panel B content"

    with ui.nav_panel("C"):
        "Panel C content"

    with ui.nav_menu("Other links"):
        with ui.nav_panel("D"):
            "Page D content"

        "----"
        "Description:"
        with ui.nav_control():
            ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
from shiny import App, ui

app_ui = ui.page_fluid(
    ui.navset_tab(  
        ui.nav_panel("A", "Panel A content"),
        ui.nav_panel("B", "Panel B content"),
        ui.nav_panel("C", "Panel C content"),
        ui.nav_menu(
            "Other links",
            ui.nav_panel("D", "Panel D content"),
            "----",
            "Description:",
            ui.nav_control(
                ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
            ),
        ),
        id="tab",  
    )  
)


def server(input, output, session):
    pass


app = App(app_ui, server)

Follow these steps to create an app with a tab navigation layout:

  1. Add ui.navset_tab() inside any Shiny UI page method (e.g., ui.page_fluid()). ui.navset_tab() creates a tabset.

  2. Pass nav items (e.g., ui.nav_panel() and ui.nav_menu()) to ui.navset_tab() to set the items displayed in the tabset.

  3. Pass arguments to the nav items to control each item’s title, appearance, and associated content. For example, set the title argument of ui.nav_panel() to control the displayed title of the nav item. Pass UI elements as additional arguments to ui.nav_panel(). These elements will be displayed when the tab is active.

  4. Optional: Pass a string to the id argument of ui.navset_tab(). 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().

Card with a tabbed tabset

#| '!! 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: 250

## file: app.py
from shiny import App, ui

app_ui = ui.page_fillable(
    ui.navset_card_tab(  
        ui.nav_panel("A", "Panel A content"),
        ui.nav_panel("B", "Panel B content"),
        ui.nav_panel("C", "Panel C content"),
        ui.nav_menu(
            "Other links",
            ui.nav_panel("D", "Panel D content"),
            "----",
            "Description:",
            ui.nav_control(
                ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
            ),
        ),
        id="tab",  
    )  
)


def server(input, output, session):
    pass


app = App(app_ui, server)
from shiny.express import ui

ui.page_opts(fillable=True)

with ui.navset_card_tab(id="tab"):  
    with ui.nav_panel("A"):
        "Panel A content"

    with ui.nav_panel("B"):
        "Panel B content"

    with ui.nav_panel("C"):
        "Panel C content"

    with ui.nav_menu("Other links"):
        with ui.nav_panel("D"):
            "Page D content"

        "----"
        "Description:"
        with ui.nav_control():
            ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
from shiny import App, ui

app_ui = ui.page_fillable(
    ui.navset_card_tab(  
        ui.nav_panel("A", "Panel A content"),
        ui.nav_panel("B", "Panel B content"),
        ui.nav_panel("C", "Panel C content"),
        ui.nav_menu(
            "Other links",
            ui.nav_panel("D", "Panel D content"),
            "----",
            "Description:",
            ui.nav_control(
                ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
            ),
        ),
        id="tab",  
    )  
)


def server(input, output, session):
    pass


app = App(app_ui, server)

Follow these steps to add a card with a tabbed tabset to your app:

  1. Add ui.navset_card_tab() inside any Shiny UI page method (e.g., ui.page_fluid()). ui.navset_card_tab() creates a tabset inside a card.

  2. Pass nav items (e.g., ui.nav_panel() and ui.nav_menu()) to ui.navset_card_tab() to set the items displayed in the tabset inside the card.

  3. Pass arguments to the nav items to control each item’s title, appearance, and associated content. For example, set the title argument of ui.nav_panel() to control the displayed title of the nav item. Pass UI elements as additional arguments to ui.nav_panel(). These elements will be displayed when the tab is active.

  4. Optional: Pass a string to the id argument of ui.navset_card_tab(). 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().

Card with a pill tabset

#| '!! 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: 250

## file: app.py
from shiny import App, ui

app_ui = ui.page_fillable(
    ui.navset_card_pill(  
        ui.nav_panel("A", "Panel A content"),
        ui.nav_panel("B", "Panel B content"),
        ui.nav_panel("C", "Panel C content"),
        ui.nav_menu(
            "Other links",
            ui.nav_panel("D", "Panel D content"),
            "----",
            "Description:",
            ui.nav_control(
                ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
            ),
        ),
        id="tab",
    )  
)


def server(input, output, session):
    pass


app = App(app_ui, server)
from shiny.express import ui

ui.page_opts(fillable=True)

with ui.navset_card_pill(id="tab"):  
    with ui.nav_panel("A"):
        "Panel A content"

    with ui.nav_panel("B"):
        "Panel B content"

    with ui.nav_panel("C"):
        "Panel C content"

    with ui.nav_menu("Other links"):
        with ui.nav_panel("D"):
            "Page D content"

        "----"
        "Description:"
        with ui.nav_control():
            ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
from shiny import App, ui

app_ui = ui.page_fillable(
    ui.navset_card_pill(  
        ui.nav_panel("A", "Panel A content"),
        ui.nav_panel("B", "Panel B content"),
        ui.nav_panel("C", "Panel C content"),
        ui.nav_menu(
            "Other links",
            ui.nav_panel("D", "Panel D content"),
            "----",
            "Description:",
            ui.nav_control(
                ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
            ),
        ),
        id="tab",
    )  
)


def server(input, output, session):
    pass


app = App(app_ui, server)

Follow these steps to add a card with a pill tabset to your app:

  1. Add ui.navset_card_pill() inside any Shiny UI page method (e.g., ui.page_fluid()). ui.navset_card_pill() creates a pillset inside a card.

  2. Pass nav items (e.g., ui.nav_panel() and ui.nav_menu()) to ui.navset_card_pill() to set the items displayed in the pillset inside the card.

  3. Pass arguments to the nav items to control each item’s title, appearance, and associated content. For example, set the title argument of ui.nav_panel() to control the displayed title of the nav item. Pass UI elements as additional arguments to ui.nav_panel(). These elements will be displayed when the tab is active.

  4. Optional: Pass a string to the id argument of ui.navset_card_pill(). 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().

Card with an underline tabset

#| '!! 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: 250

## file: app.py
from shiny import App, ui

app_ui = ui.page_fillable(
    ui.navset_card_underline(  
        ui.nav_panel("A", "Panel A content"),
        ui.nav_panel("B", "Panel B content"),
        ui.nav_panel("C", "Panel C content"),
        ui.nav_menu(
            "Other links",
            ui.nav_panel("D", "Panel D content"),
            "----",
            "Description:",
            ui.nav_control(
                ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
            ),
        ),
        id="tab",
    )  
)


def server(input, output, session):
    pass


app = App(app_ui, server)
from shiny.express import ui

ui.page_opts(fillable=True)

with ui.navset_card_underline(id="tab"):  
    with ui.nav_panel("A"):
        "Panel A content"

    with ui.nav_panel("B"):
        "Panel B content"

    with ui.nav_panel("C"):
        "Panel C content"

    with ui.nav_menu("Other links"):
        with ui.nav_panel("D"):
            "Page D content"

        "----"
        "Description:"
        with ui.nav_control():
            ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
from shiny import App, ui

app_ui = ui.page_fillable(
    ui.navset_card_underline(  
        ui.nav_panel("A", "Panel A content"),
        ui.nav_panel("B", "Panel B content"),
        ui.nav_panel("C", "Panel C content"),
        ui.nav_menu(
            "Other links",
            ui.nav_panel("D", "Panel D content"),
            "----",
            "Description:",
            ui.nav_control(
                ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
            ),
        ),
        id="tab",
    )  
)


def server(input, output, session):
    pass


app = App(app_ui, server)

Follow these steps to add a card with an underline tabset to your app:

  1. Add ui.navset_card_underline() inside any Shiny UI page method (e.g., ui.page_fluid()). ui.navset_card_underline() creates an underlined tabset inside a card.

  2. Pass nav items (e.g., ui.nav_panel() and ui.nav_menu()) to ui.navset_card_underline() to set the items displayed in the tabset inside the card.

  3. Pass arguments to the nav items to control each item’s title, appearance, and associated content. For example, set the title argument of ui.nav_panel() to control the displayed title of the nav item. Pass UI elements as additional arguments to ui.nav_panel(). These elements will be displayed when the tab is active.

  4. Optional: Pass a string to the id argument of ui.navset_card_underline(). 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().

Tabset with no visible navigation

Sometimes you want the panel-switching behavior of a tabset, but you want to drive it from your own controls rather than from a row of tabs — for example a multi-step wizard driven by “Next” and “Back” buttons. ui.navset_hidden() renders the panels with the navigation hidden, and you change the visible panel from the server with ui.update_navset().

#| '!! 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: 200

## file: app.py
from shiny import App, reactive, ui

app_ui = ui.page_fluid(
    ui.input_radio_buttons(
        "controller", "Show panel", ["1", "2", "3"], selected="1", inline=True
    ),
    ui.navset_hidden(  
        ui.nav_panel(None, "Panel 1 content", value="panel1"),  
        ui.nav_panel(None, "Panel 2 content", value="panel2"),  
        ui.nav_panel(None, "Panel 3 content", value="panel3"),  
        id="hidden_tabs",  
    ),  
)


def server(input, output, session):
    @reactive.effect
    @reactive.event(input.controller)
    def _():
        ui.update_navset("hidden_tabs", selected="panel" + input.controller())  


app = App(app_ui, server)
from shiny import reactive
from shiny.express import input, ui

ui.input_radio_buttons(
    "controller", "Show panel", ["1", "2", "3"], selected="1", inline=True
)

with ui.navset_hidden(id="hidden_tabs"):  
    with ui.nav_panel(None, value="panel1"):  
        "Panel 1 content"

    with ui.nav_panel(None, value="panel2"):  
        "Panel 2 content"

    with ui.nav_panel(None, value="panel3"):  
        "Panel 3 content"


@reactive.effect
@reactive.event(input.controller)
def _():
    ui.update_navset("hidden_tabs", selected="panel" + input.controller())  
from shiny import App, reactive, ui

app_ui = ui.page_fluid(
    ui.input_radio_buttons(
        "controller", "Show panel", ["1", "2", "3"], selected="1", inline=True
    ),
    ui.navset_hidden(  
        ui.nav_panel(None, "Panel 1 content", value="panel1"),  
        ui.nav_panel(None, "Panel 2 content", value="panel2"),  
        ui.nav_panel(None, "Panel 3 content", value="panel3"),  
        id="hidden_tabs",  
    ),  
)


def server(input, output, session):
    @reactive.effect
    @reactive.event(input.controller)
    def _():
        ui.update_navset("hidden_tabs", selected="panel" + input.controller())  


app = App(app_ui, server)

Follow these steps to create a tabset with no visible navigation:

  1. Add ui.navset_hidden() inside any Shiny UI page method (e.g., ui.page_fluid()), and pass a string to its id argument. The id is optional on the other navsets, but here you always want it: it is what ui.update_navset() targets, and without it there is no way to change the visible panel.

  2. Pass nav items to ui.navset_hidden(). Give each ui.nav_panel() a value — that is the name you will switch to later. Because the navigation is not displayed, pass None as the panel’s title.

  3. Add whatever controls you want to drive the tabset with, such as ui.input_radio_buttons() above or a pair of buttons.

  4. In the server function, call ui.update_navset("<id>", selected="<value>") to show a different panel — typically from a @reactive.effect that responds to your controls.

Note

The nav links are still present in the HTML, just hidden with CSS, so this is a layout convenience rather than a way to keep panel content secret. Content in an unselected panel is still sent to the browser.

Vertically collapsing accordion panels

#| '!! 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: 350

## file: app.py
from shiny import App, ui

app_ui = ui.page_fluid(
    ui.accordion(  
        ui.accordion_panel("Section A", "Section A content"),  
        ui.accordion_panel("Section B", "Section B content"),  
        ui.accordion_panel("Section C", "Section C content"),  
        ui.accordion_panel("Section D", "Section D content"),  
        ui.accordion_panel("Section E", "Section E content"),  
        id="acc",  
        open="Section A",  
    ),  
)


def server(input, output, session):
    pass


app = App(app_ui, server)
from shiny.express import ui

with ui.accordion(id="acc", open="Section A"):  
    with ui.accordion_panel("Section A"):  
        "Section A content"

    with ui.accordion_panel("Section B"):  
        "Section B content"

    with ui.accordion_panel("Section C"):  
        "Section C content"

    with ui.accordion_panel("Section D"):  
        "Section D content"

    with ui.accordion_panel("Section E"):  
        "Section E content"
from shiny import App, ui

app_ui = ui.page_fluid(
    ui.accordion(  
        ui.accordion_panel("Section A", "Section A content"),  
        ui.accordion_panel("Section B", "Section B content"),  
        ui.accordion_panel("Section C", "Section C content"),  
        ui.accordion_panel("Section D", "Section D content"),  
        ui.accordion_panel("Section E", "Section E content"),  
        id="acc",  
        open="Section A",  
    ),  
)


def server(input, output, session):
    pass


app = App(app_ui, server)

Follow these steps to add vertically collapsing accordion panels to your app:

  1. Add ui.accordion() inside any Shiny UI page method (e.g., ui.page_fluid()). ui.accordion() creates a vertically collapsing accordion.

  2. Pass accordion panel items to ui.accordion() using calls to ui.accordion_panel(). Each call to ui.accordion_panel() creates one accordion panel.

  3. Pass arguments to the accordion panels to control each panel’s title, appearance, and associated content. The *args argument of ui.accordion_panel() controls the contents of the accordion panel.

  4. Optional: Pass a string to the id argument of ui.accordian(). This will create an input value that represents the currently active accordion panels. For example, id = "panel" would create a reactive value accessible as input.panel().