update_tooltip temporarily breaks HTML escaping in Shiny apps
Nobody has claimed this yet.
- Dominant language
- SCSS
- Stars
- 569
- Forks
- 72
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 5
Description
Describe the problem
Using update_tooltip to update a tooltip temporarily causes HTML escaping to fail, i.e., the raw HTML string is displayed. This occurs both in R and Python Shiny. If you switch mouse focus elsewhere and then return to the tooltip, it displays HTML content as expected.
Here is a reprex in R:
library(bslib)
library(htmltools)
library(shiny)
tooltip_text_initial <- "<strong>Initial tooltip text</strong>"
tooltip_text_updated <- "<strong>Updated tooltip text</strong>"
ui <- bslib::page_fluid(
bslib::tooltip(
shiny::actionButton("btn", "A button"),
htmltools::HTML(tooltip_text_initial),
id = "tooltip"
)
)
server <- function(input, output, session) {
observe({
message("This code is triggered on a button click.")
bslib::update_tooltip(
id = "tooltip",
htmltools::HTML(tooltip_text_updated)
)
}) |>
shiny::bindEvent(input$btn)
}
shinyApp(ui, server)
App startup, hover mouse over button, showing initial text:
After clicking the button, the tooltip updates with unescaped HTML, i.e., the raw value of tooltip_text_updated.
Switch focus from the button (click anywhere else), and the HTML escaping works as intended:
Session Info
I've tested this in Firefox, Chrome, and the built-in RStudio Viewer (RStudio versions 2024.09.0 and 2024.12.1), under R 4.4.0 and 4.4.3, and the latest stable releases of bslib and shiny. (I haven't tested the development versions because I can't see any reference to update_tooltip in any recent dev changes.)
> devtools::session_info() ─ Session info ───────────────────────────────────────────────────────────────────────────── setting value version R version 4.4.0 (2024-04-24 ucrt) os Windows 11 x64 (build 26100) system x86_64, mingw32 ui RStudio language (EN) collate English_New Zealand.utf8 ctype English_New Zealand.utf8 tz Pacific/Auckland date 2025-05-05 rstudio 2024.09.0+375 Cranberry Hibiscus (desktop) pandoc NA
─ Packages ─────────────────────────────────────────────────────────────────────────────────
package * version date (UTC) lib source
bslib * 0.9.0 2025-01-30 [1] CRAN (R 4.4.3)
cachem 1.1.0 2024-05-16 [1] CRAN (R 4.4.3)
cli 3.6.2 2023-12-11 [1] CRAN (R 4.4.0)
devtools 2.4.5 2022-10-11 [1] CRAN (R 4.4.1)
digest 0.6.35 2024-03-11 [1] CRAN (R 4.4.0)
ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.4.1)
fansi 1.0.6 2023-12-08 [1] CRAN (R 4.4.0)
fastmap 1.2.0 2024-05-15 [1] CRAN (R 4.4.3)
fs 1.6.4 2024-04-25 [1] CRAN (R 4.4.0)
glue 1.7.0 2024-01-09 [1] CRAN (R 4.4.0)
htmltools 0.5.8.1 2024-04-04 [1] CRAN (R 4.4.0)
htmlwidgets 1.6.4 2023-12-06 [1] CRAN (R 4.4.1)
httpuv 1.6.15 2024-03-26 [1] CRAN (R 4.4.1)
jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.4.0)
jsonlite 1.8.8 2023-12-04 [1] CRAN (R 4.4.0)
later 1.3.2 2023-12-06 [1] CRAN (R 4.4.1)
lifecycle 1.0.4 2023-11-07 [1] CRAN (R 4.4.0)
magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.4.0)
memoise 2.0.1 2021-11-26 [1] CRAN (R 4.4.0)
mime 0.12 2021-09-28 [1] CRAN (R 4.4.0)
miniUI 0.1.1.1 2018-05-18 [1] CRAN (R 4.4.1)
pillar 1.9.0 2023-03-22 [1] CRAN (R 4.4.0)
pkgbuild 1.4.4 2024-03-17 [1] CRAN (R 4.4.1)
pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.4.0)
pkgload 1.4.0 2024-06-28 [1] CRAN (R 4.4.1)
profvis 0.3.8 2023-05-02 [1] CRAN (R 4.4.1)
promises 1.3.2 2024-11-28 [1] CRAN (R 4.4.3)
purrr 1.0.2 2023-08-10 [1] CRAN (R 4.4.0)
R6 2.5.1 2021-08-19 [1] CRAN (R 4.4.0)
Rcpp 1.0.12 2024-01-09 [1] CRAN (R 4.4.1)
remotes 2.5.0 2024-03-17 [1] CRAN (R 4.4.1)
rlang 1.1.3 2024-01-10 [1] CRAN (R 4.4.0)
rstudioapi 0.16.0 2024-03-24 [1] CRAN (R 4.4.1)
sass 0.4.9 2024-03-15 [1] CRAN (R 4.4.0)
sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.4.1)
shiny * 1.10.0 2024-12-14 [1] CRAN (R 4.4.3)
stringi 1.8.3 2023-12-11 [1] CRAN (R 4.4.0)
stringr 1.5.1 2023-11-14 [1] CRAN (R 4.4.0)
tibble 3.2.1 2023-03-20 [1] CRAN (R 4.4.0)
urlchecker 1.0.1 2021-11-30 [1] CRAN (R 4.4.1)
usethis 2.2.3 2024-02-19 [1] CRAN (R 4.4.1)
utf8 1.2.4 2023-10-22 [1] CRAN (R 4.4.0)
vctrs 0.6.5 2023-12-01 [1] CRAN (R 4.4.0)
withr 3.0.0 2024-01-16 [1] CRAN (R 4.4.0)
xtable 1.8-4 2019-04-21 [1] CRAN (R 4.4.1)
The same behaviour occurs in Python Shiny; so I'm not sure whether this is a Shiny or bslib issue:
from shiny import App, reactive, ui
tooltip_text_initial = "Initial tooltip text"
tooltip_text_updated = "<strong>Updated tooltip text</strong>"
app_ui = ui.page_fluid(
ui.tooltip(
ui.input_action_button(
id="btn",
label="A button"
),
tooltip_text_initial,
id="tooltip"
)
)
def server(input, output, session):
@reactive.effect
@reactive.event(input.btn)
def update_tooltip_message():
ui.update_tooltip(
"tooltip",
ui.HTML(tooltip_text_updated)
)
app = App(app_ui, server)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the R and Python Shiny examples and trace the update_tooltip entry point in both cases. The fix is complete when updated tooltip content preserves the intended HTML escaping immediately after the update, without requiring focus to move away and return.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, r
- Domain
- frontend, web-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100