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()ownsheight,fill, andshow_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>_pageand settable viabslib::nav_select(). Usebslib::nav_show()andbslib::nav_hide()to reveal or hide nav controls. The reserved value"__home__"represents the main chat page.NULLor a list ofchat_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; usebslib::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'schat_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 containingbslib::input_dark_mode(); useNULLto 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 navigationtoolbar.Optional
bslib::navbar_options()that styles the page title bar. Itsbg,theme,underline, and HTML attributes are supported.positionandcollapsibleare unsupported becausepage_chat()owns the full-window layout and responsive app menu.Whether to use the default history sidebar (
TRUE), omit the default sidebar (FALSE), or use achat_sidebar()orbslib::sidebar()configuration. A bslib sidebar supplies its child content, width, initial open state, and resizability; its history defaults toFALSE. Achat_sidebar()withhistory = NULLdefaults toTRUEhere.Common arguments passed to
chat_ui().- window_title
A static browser-window title. The default,
NA, derives the window title fromtitlewhentitleis a scalar string. UseNULLto omit the window title.- lang
An optional non-empty document language string.
- theme
A
bslib::bs_theme()object. Defaults topage_chat_theme(). Supplybslib::bs_theme()directly to use another bslib preset or a completely custom Bootstrap theme.
Migration from page_fillable()
Replace:
with:
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.
Navigation, sidebars, and artifacts
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)
}