Skip to contents

page_chat() creates a fillable page containing one persistent chat_ui() home view, optional navigation pages, and a responsive app-menu sidebar.

Use page_chat() as the top-level page UI when the chat owns the full browser window. It owns the page layout, the single mounted chat, and the responsive app-menu controls. Use chat_ui() directly when the chat is embedded in an existing layout or alongside other top-level page content. For a standalone interactive chat application, use chat_app(), which composes page_chat() with chat_server().

Usage

page_chat(
  title,
  icon = NULL,
  ...,
  id = "chat",
  pages_navbar = NULL,
  toolbar = NULL,
  toolbar_global = bslib::toolbar(bslib::input_dark_mode()),
  toolbar_input = NULL,
  navbar_options = NULL,
  sidebar = TRUE,
  messages = NULL,
  greeting = NULL,
  placeholder = "Enter a message...",
  width = "min(clamp(680px, 50vw, 760px), 100%)",
  icon_assistant = NULL,
  icon_send = NULL,
  enable_cancel = NULL,
  allow_attachments = NULL,
  footer = NULL,
  drawer = TRUE,
  window_title = NA,
  lang = NULL,
  theme = page_chat_theme()
)

Arguments

title

The display title. May be text or reactive/static UI.

icon

Optional UI displayed before title.

...

Named lower-frequency chat_ui() arguments and HTML attributes. page_chat() owns height, fill, and show_history; attempts to pass those arguments are rejected.

id

A non-empty string identifying the chat. The currently selected page is readable server-side as input$<id>_page and settable via bslib::nav_select(). Use bslib::nav_show() and bslib::nav_hide() to reveal or hide nav controls. The reserved value "__home__" represents the main chat page.

pages_navbar

NULL or a list of chat_nav_panel() configurations and supported standard bslib navigation items. Standard content panels use the normal page-chat content width with no page-specific sidebar or toolbar. bslib::nav_panel_hidden() panels render their nav control hidden; use bslib::nav_show() to reveal it.

toolbar

Optional home-page-scoped UI displayed with the navigation controls. Use bslib::toolbar() to group toolbar controls. A panel's chat_nav_panel(toolbar = ) replaces this scoped segment.

toolbar_global

Optional persistent UI displayed after the page-scoped toolbar in the navigation controls. Use bslib::toolbar() to group toolbar controls. Defaults to a toolbar containing bslib::input_dark_mode(); use NULL to opt out. It remains mounted while secondary pages are selected and while controls move between desktop and mobile layouts.

toolbar_input

Optional UI displayed directly below the chat input. Use bslib::toolbar() to group toolbar controls. This is independent of the navigation toolbar.

navbar_options

Optional bslib::navbar_options() that styles the page title bar. Its bg, theme, underline, and HTML attributes are supported. position and collapsible are unsupported because page_chat() owns the full-window layout and responsive app menu.

sidebar

Whether to use the default history sidebar (TRUE), omit the default sidebar (FALSE), or use a chat_sidebar() or bslib::sidebar() configuration. A bslib sidebar supplies its child content, width, initial open state, and resizability; its history defaults to FALSE. A chat_sidebar() with history = NULL defaults to TRUE here.

Common arguments passed to chat_ui().

window_title

A static browser-window title. The default, NA, derives the window title from title when title is a scalar string. Use NULL to omit the window title.

lang

An optional non-empty document language string.

theme

A bslib::bs_theme() object. Defaults to page_chat_theme(). Supply bslib::bs_theme() directly to use another bslib preset or a completely custom Bootstrap theme.

Value

A fillable bslib page.

Migration from page_fillable()

Replace:

bslib::page_fillable(chat_ui("chat", fill = TRUE))

with:

page_chat("Assistant", id = "chat")

The page supplies the full-window sizing and keeps show_history = TRUE on the mounted chat. Do not wrap page_chat() in another page container or pass height, fill, or show_history; those arguments are page-owned.

pages_navbar accepts a list of additional navbar items. Use chat_nav_panel() when a page needs page-chat-specific sidebar, toolbar, or content-width options. It also accepts bslib::nav_panel(), bslib::nav_panel_hidden(), bslib::nav_menu(), bslib::nav_item(), and bslib::nav_spacer(). Programmatic navigation uses standard bslib helpers against the derived "<id>_page" id: bslib::nav_select() to switch pages (including hidden panels and nav_menu() children), bslib::nav_show() and bslib::nav_hide() to reveal or hide nav controls. The active page is readable as input$<id>_page ("__home__" when the main chat page is active). Sidebar navigation is not yet implemented. Each panel can use the default sidebar, no page-specific sidebar, or its own chat_sidebar() or bslib::sidebar() configuration. The sidebar argument configures the home view. Use bslib::toolbar() to group controls in toolbar; it is a home-page-scoped segment rendered with the page navigation controls and follows them into the mobile app menu. A panel's toolbar = NULL omits that scoped segment; chat_nav_panel(toolbar = bslib::toolbar(...)) supplies a page-specific replacement. Use toolbar_global = bslib::toolbar(...) for a persistent segment that remains mounted on every page after the active scoped toolbar. On narrow screens, navigation and toolbar controls move into the app menu above the active page's sidebar content without duplicating Shiny input or output IDs. By default, toolbar_global contains bslib::input_dark_mode(); use NULL to opt out.

Set drawer to a chat_drawer() configuration to provide initial content and layout options. Update the mounted drawer from the server with chat_drawer_show(), chat_drawer_update(), chat_drawer_hide(), and chat_drawer_toggle(). Artifact content is static UI passed through those server functions; use ordinary Shiny inputs and outputs inside that content when needed. You can try navigation and artifact-control examples, which do not require credentials, through shiny::runExample("page-chat-navigation", package = "shinychat") and shiny::runExample("page-chat-drawer-controls", package = "shinychat").

page_chat() owns page composition and accepts one chat root. Do not pass unrelated top-level UI or a second chat root. Existing apps that need those layouts should continue using chat_ui() with bslib::page_fillable(), bslib::page_sidebar(), or another appropriate container.

Examples

if (FALSE) { # interactive()
library(shiny)
library(shinychat)

artifact_content <- function(label) {
  tags$div(
    tags$h3("Preview"),
    tags$p(label)
  )
}

ui <- page_chat(
  "Assistant",
  messages = "Welcome! Ask a question to get started.",
  toolbar = bslib::toolbar(actionButton("show_preview", "Show preview")),
  toolbar_global = actionButton("help", "Help"),
  sidebar = chat_sidebar(
    tags$p("Home tools"),
    history = FALSE,
    open = "open"
  ),
  pages_navbar = list(
    chat_nav_panel(
      "About",
      tags$p("This is a secondary page."),
      value = "about",
    ),
    chat_nav_panel(
      "Settings",
      tags$p("Settings live here."),
      value = "settings",
      sidebar = chat_sidebar(
        tags$p("Settings menu"),
        width = 320,
        open = "closed"
      ),
      toolbar = bslib::toolbar(actionButton("save_settings", "Save settings"))
    )
  ),
  drawer = chat_drawer(
    artifact_content("Initial preview"),
    title = "Preview"
  )
)

server <- function(input, output, session) {
  observeEvent(input$chat_user_input, {
    chat_append("chat", paste0("You said: ", input$chat_user_input))
  })

  observeEvent(input$show_preview, {
    chat_drawer_show(
      "chat",
      content = artifact_content("Preview opened from the server"),
      title = "Preview"
    )
  })
}

shinyApp(ui, server)
}