Toasts

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| components: [viewer]
#| viewerHeight: 200

from faicons import icon_svg

from shiny import App, reactive, ui

app_ui = ui.page_fluid(
    ui.input_action_button("show", "Show toast"),
)

def server(input, output, session):
    @reactive.effect
    @reactive.event(input.show)
    def _():
        ui.show_toast(
            ui.toast(
                "You have a new message!",
                header=ui.toast_header("Inbox", status="just now"),
                icon=icon_svg("envelope"),
                type="success",
            )
        )

app = App(app_ui, server)
from faicons import icon_svg

from shiny import reactive
from shiny.express import input, ui

ui.input_action_button("show", "Show toast")

@reactive.effect
@reactive.event(input.show)
def show_message():
    ui.show_toast(  
        ui.toast(
            "You have a new message!",
            header=ui.toast_header("Inbox", status="just now"),
            icon=icon_svg("envelope"),
            type="success",
            id="message_toast",
        )
    )
from faicons import icon_svg

from shiny import App, reactive, ui

app_ui = ui.page_fluid(
    ui.input_action_button("show", "Show toast"),
)

def server(input, output, session):
    @reactive.effect
    @reactive.event(input.show)
    def _():
        ui.show_toast(  
            ui.toast(
                "You have a new message!",
                header=ui.toast_header("Inbox", status="just now"),
                icon=icon_svg("envelope"),
                type="success",
                id="message_toast",
            )
        )

app = App(app_ui, server)
No matching items

Relevant Functions

  • ui.toast
    ui.toast(*args, header=None, icon=None, id=None, type=None, duration_s=5, position='top-right', closable=True, **kwargs)

  • ui.toast_header
    ui.toast_header(title, *args, icon=None, status=None, **kwargs)

  • ui.show_toast
    ui.show_toast(toast, *, session=None)

  • ui.hide_toast
    ui.hide_toast(id, *, session=None)

No matching items

Details

A toast is a temporary, non-intrusive notification that appears on top of the app to give feedback about an action — for example, confirming that a save succeeded. Toasts auto-dismiss after a few seconds by default and can be placed in any corner, edge, or the center of the screen.

To show a toast, call ui.show_toast() from a reactive effect or event handler. For a simple message, pass a string:

@reactive.effect
@reactive.event(input.show)
def _():
    ui.show_toast("Operation complete!")

For more control, build the toast with ui.toast() and pass it to ui.show_toast(). ui.toast() lets you set:

  • type to color-code the message. The nine values are "primary", "secondary", "success", "info", "warning", "danger", "error" (an alias for "danger"), "light", and "dark".
  • position to place the toast on screen (top/middle/bottom × left/center/right; "top-right" by default). Accepts either a string ("top-left", "top left") or a sequence (["top", "left"]).
  • duration_s to control auto-hide. Toasts disappear after 5 seconds by default; set duration_s=None (or 0) to keep the toast visible until it’s dismissed. While the toast is visible, an animated progress bar shows the time remaining.
  • header to add a header above the body, either as a plain string or via ui.toast_header(), which supports a title, an icon, and muted status text (e.g. "just now").
  • icon to show an icon in the toast body, alongside the message.
  • closable to control whether the toast has a close button (True by default). Take care when combining closable=False with auto-hide disabled: the user then has no way to dismiss the toast, so your app must close it with ui.hide_toast().

To dismiss a toast from the server, call ui.hide_toast() with the toast’s id — either one you set when creating the toast, or the id returned by ui.show_toast().

Toasts or notifications?

Toasts and notifications overlap heavily — both show a transient message without interrupting the user — so prefer whichever matches the message you’re sending:

  • Reach for a toast when placement or severity carries meaning: it can appear at any of the nine screen positions, be color-coded by type, carry a header and icon, and show a countdown bar for the time remaining.
  • Reach for a notification for a plain status line. Notifications are the simpler, longer-standing API, and always stack in one corner.

Modal messages are the third option, for information the user must acknowledge before continuing.

Variations

Toast types

Color-code a toast with the type argument of ui.toast(). The available types are "primary", "secondary", "success", "info", "warning", "danger" (or its alias "error"), "light", and "dark".

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| components: [viewer]
#| viewerHeight: 250

from shiny import App, reactive, ui

app_ui = ui.page_fluid(
    ui.input_action_button("success", "Success"),
    ui.input_action_button("info", "Info"),
    ui.input_action_button("warning", "Warning"),
    ui.input_action_button("danger", "Danger"),
)

def server(input, output, session):
    @reactive.effect
    @reactive.event(input.success)
    def _():
        ui.show_toast(
            ui.toast("Operation successful!", type="success", id="toast_success")
        )

    @reactive.effect
    @reactive.event(input.info)
    def _():
        ui.show_toast(
            ui.toast("Here's some information.", type="info", id="toast_info")
        )

    @reactive.effect
    @reactive.event(input.warning)
    def _():
        ui.show_toast(
            ui.toast("Warning: check your input.", type="warning", id="toast_warning")
        )

    @reactive.effect
    @reactive.event(input.danger)
    def _():
        ui.show_toast(
            ui.toast("Error: operation failed.", type="danger", id="toast_danger")
        )

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

ui.input_action_button("success", "Success")
ui.input_action_button("info", "Info")
ui.input_action_button("warning", "Warning")
ui.input_action_button("danger", "Danger")

@reactive.effect
@reactive.event(input.success)
def show_success():
    ui.show_toast(
        ui.toast("Operation successful!", type="success", id="toast_success")  
    )

@reactive.effect
@reactive.event(input.info)
def show_info():
    ui.show_toast(ui.toast("Here's some information.", type="info", id="toast_info"))

@reactive.effect
@reactive.event(input.warning)
def show_warning():
    ui.show_toast(
        ui.toast("Warning: check your input.", type="warning", id="toast_warning")
    )

@reactive.effect
@reactive.event(input.danger)
def show_danger():
    ui.show_toast(
        ui.toast("Error: operation failed.", type="danger", id="toast_danger")
    )
from shiny import App, reactive, ui

app_ui = ui.page_fluid(
    ui.input_action_button("success", "Success"),
    ui.input_action_button("info", "Info"),
    ui.input_action_button("warning", "Warning"),
    ui.input_action_button("danger", "Danger"),
)

def server(input, output, session):
    @reactive.effect
    @reactive.event(input.success)
    def _():
        ui.show_toast(
            ui.toast("Operation successful!", type="success", id="toast_success")  
        )

    @reactive.effect
    @reactive.event(input.info)
    def _():
        ui.show_toast(
            ui.toast("Here's some information.", type="info", id="toast_info")
        )

    @reactive.effect
    @reactive.event(input.warning)
    def _():
        ui.show_toast(
            ui.toast("Warning: check your input.", type="warning", id="toast_warning")
        )

    @reactive.effect
    @reactive.event(input.danger)
    def _():
        ui.show_toast(
            ui.toast("Error: operation failed.", type="danger", id="toast_danger")
        )

app = App(app_ui, server)

Toast positions

Place a toast anywhere on screen with the position argument of ui.toast(). Valid positions combine top/middle/bottom with left/center/right, e.g. "top-left", "middle-center", or "bottom-right". The default is "top-right".

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| components: [viewer]
#| viewerHeight: 250

from shiny import App, reactive, ui

app_ui = ui.page_fluid(
    ui.input_action_button("top_left", "Top left"),
    ui.input_action_button("top_center", "Top center"),
    ui.input_action_button("middle_center", "Middle center"),
    ui.input_action_button("bottom_right", "Bottom right"),
)

def server(input, output, session):
    @reactive.effect
    @reactive.event(input.top_left)
    def _():
        ui.show_toast(
            ui.toast(
                "Top left position",
                position="top-left",
                id="toast_top_left",
            )
        )

    @reactive.effect
    @reactive.event(input.top_center)
    def _():
        ui.show_toast(
            ui.toast(
                "Top center position",
                position="top-center",
                id="toast_top_center",
            )
        )

    @reactive.effect
    @reactive.event(input.middle_center)
    def _():
        ui.show_toast(
            ui.toast(
                "Middle center position",
                position="middle-center",
                id="toast_middle_center",
            )
        )

    @reactive.effect
    @reactive.event(input.bottom_right)
    def _():
        ui.show_toast(
            ui.toast(
                "Bottom right position",
                position="bottom-right",
                id="toast_bottom_right",
            )
        )

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

ui.input_action_button("top_left", "Top left")
ui.input_action_button("top_center", "Top center")
ui.input_action_button("middle_center", "Middle center")
ui.input_action_button("bottom_right", "Bottom right")

@reactive.effect
@reactive.event(input.top_left)
def show_top_left():
    ui.show_toast(
        ui.toast(
            "Top left position",
            position="top-left",  
            id="toast_top_left",
        )
    )

@reactive.effect
@reactive.event(input.top_center)
def show_top_center():
    ui.show_toast(
        ui.toast(
            "Top center position",
            position="top-center",
            id="toast_top_center",
        )
    )

@reactive.effect
@reactive.event(input.middle_center)
def show_middle_center():
    ui.show_toast(
        ui.toast(
            "Middle center position",
            position="middle-center",
            id="toast_middle_center",
        )
    )

@reactive.effect
@reactive.event(input.bottom_right)
def show_bottom_right():
    ui.show_toast(
        ui.toast(
            "Bottom right position",
            position="bottom-right",
            id="toast_bottom_right",
        )
    )
from shiny import App, reactive, ui

app_ui = ui.page_fluid(
    ui.input_action_button("top_left", "Top left"),
    ui.input_action_button("top_center", "Top center"),
    ui.input_action_button("middle_center", "Middle center"),
    ui.input_action_button("bottom_right", "Bottom right"),
)

def server(input, output, session):
    @reactive.effect
    @reactive.event(input.top_left)
    def _():
        ui.show_toast(
            ui.toast(
                "Top left position",
                position="top-left",  
                id="toast_top_left",
            )
        )

    @reactive.effect
    @reactive.event(input.top_center)
    def _():
        ui.show_toast(
            ui.toast(
                "Top center position",
                position="top-center",
                id="toast_top_center",
            )
        )

    @reactive.effect
    @reactive.event(input.middle_center)
    def _():
        ui.show_toast(
            ui.toast(
                "Middle center position",
                position="middle-center",
                id="toast_middle_center",
            )
        )

    @reactive.effect
    @reactive.event(input.bottom_right)
    def _():
        ui.show_toast(
            ui.toast(
                "Bottom right position",
                position="bottom-right",
                id="toast_bottom_right",
            )
        )

app = App(app_ui, server)

Show and hide a toast from the server

Give a toast an id and set duration_s=None to keep it on screen, then call ui.hide_toast() with that id to dismiss it programmatically. ui.show_toast() also returns the toast’s id (auto-generated if you don’t provide one), so you can hide any toast you’ve shown. This toast also passes closable=False, so the server is the only thing that can dismiss it; only combine that with duration_s=None when your app is certain to call ui.hide_toast().

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| components: [viewer]
#| viewerHeight: 250

from shiny import App, reactive, ui

app_ui = ui.page_fluid(
    ui.input_action_button("show", "Show toast"),
    ui.input_action_button("hide", "Hide toast"),
)

def server(input, output, session):
    @reactive.effect
    @reactive.event(input.show)
    def _():
        ui.show_toast(
            ui.toast(
                "This toast stays until you hide it.",
                id="persistent_toast",
                duration_s=None,
                closable=False,
            )
        )

    @reactive.effect
    @reactive.event(input.hide)
    def _():
        ui.hide_toast("persistent_toast")

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

ui.input_action_button("show", "Show toast")
ui.input_action_button("hide", "Hide toast")

@reactive.effect
@reactive.event(input.show)
def show_persistent_toast():
    ui.show_toast(
        ui.toast(
            "This toast stays until you hide it.",
            id="persistent_toast",  
            duration_s=None,
            closable=False,
        )
    )

@reactive.effect
@reactive.event(input.hide)
def hide_persistent_toast():
    ui.hide_toast("persistent_toast")  
from shiny import App, reactive, ui

app_ui = ui.page_fluid(
    ui.input_action_button("show", "Show toast"),
    ui.input_action_button("hide", "Hide toast"),
)

def server(input, output, session):
    @reactive.effect
    @reactive.event(input.show)
    def _():
        ui.show_toast(
            ui.toast(
                "This toast stays until you hide it.",
                id="persistent_toast",  
                duration_s=None,
                closable=False,
            )
        )

    @reactive.effect
    @reactive.event(input.hide)
    def _():
        ui.hide_toast("persistent_toast")  

app = App(app_ui, server)
No matching items