Skip to content

Conversation

@cpsievert
Copy link
Contributor

@cpsievert cpsievert commented Dec 16, 2025

Closes #169

This PR introduces proper support for using QueryChat within Shiny (for R) modules by allowing explicit id parameter overrides in $ui(), $sidebar(), and $server() methods.

Key Changes

1. Added id parameter to $ui(), $sidebar(), and $server() methods:

  • Users can now explicitly pass an id when calling these methods
  • When not provided, falls back to the ID specified at initialization
  • In Shiny modules, users pass namespaced IDs using standard Shiny module patterns: id = ns("your_id")

2. Follows idiomatic Shiny module patterns:

  • Uses the standard Shiny approach where module IDs are wrapped in ns() in the UI function
  • The corresponding server function receives the unwrapped ID
  • This is the established pattern that Shiny developers are familiar with

3. Enables multiple instances from the same QueryChat object:

  • By allowing explicit id override, users can create multiple chat interfaces from a single QueryChat instance
  • Useful for both module and non-module scenarios where multiple chats are needed

Implementation Details

  • Modified $ui() and $sidebar() to accept an optional id parameter instead of ns function
  • Modified $server() to accept an optional id parameter
  • When id is not provided, falls back to self$id with automatic namespace detection (via namespaced_id()) for UI methods
  • Updated documentation to clarify the new module usage pattern
  • Removed the error check that prevented setting id directly

Usage

In a Shiny module UI function:

module_ui <- function(id, qc) {
  ns <- NS(id)
  card(qc$ui(id = ns("qc-ui")))  # Standard Shiny module pattern
}

In a Shiny module server function:

module_server <- function(id, qc) {
  moduleServer(id, function(input, output, session) {
    qc$server(id = "qc-ui")  # Matches the unwrapped ID from UI
  })
}

In a regular Shiny app (no module):

ui <- page_fluid(
  qc$ui()  # Uses default ID from initialization
)

server <- function(input, output, session) {
  qc$server()  # Uses default ID from initialization
}

This comment was marked as resolved.

Copy link
Contributor

@gadenbuie gadenbuie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I liked considering the idea of passing in ns() (it's a creative solution!), but it feels little off compared to the established patterns we use with Shiny modules.

In #173 I'm proposing that we expose id directly, while still allowing for the server-side rendered case to "just work". More than just solving the Shiny modules use case, that opens up re-using a qc object for more than chat instance.

…173)

* refactor: Allow directly providing `id`

* chore: Also `$sidebar()` and update docstrings
@cpsievert
Copy link
Contributor Author

@gadenbuie mind updating the description and taking this over the finish line?

@gadenbuie
Copy link
Contributor

@cpsievert I updated the PR description, made the "querychat_" + table_name for default ID, and added an example app in the R package as 03-module-app. I also made similar changes on the Python side (except for adding an example app).

@gadenbuie gadenbuie changed the title fix(pkg-r): better support for modules. fix: Expose id in ui/server methods to support Shiny for R modules and multiple instances Dec 18, 2025
@cpsievert
Copy link
Contributor Author

Thanks! LGTM other than the one suggestion.

Co-authored-by: Carson Sievert <[email protected]>
@gadenbuie gadenbuie merged commit c5e63ed into main Dec 18, 2025
18 checks passed
@gadenbuie gadenbuie deleted the fix/module-ui-id branch December 18, 2025 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unable to run QueryChat inside shinyModule

3 participants