Skip to content

update_tooltip temporarily breaks HTML escaping in Shiny apps #1208

Open
@hedsnz

Description

@hedsnz

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:

Image

After clicking the button, the tooltip updates with unescaped HTML, i.e., the raw value of tooltip_text_updated.

Image

Switch focus from the button (click anywhere else), and the HTML escaping works as intended:

Image

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions