| Title: | Build Modern Web Applications with 'htmx' and 'plumber2' |
| Version: | 0.2.0 |
| Description: | A lightweight framework for building server-driven web applications in 'R'. 'htmxr' combines the simplicity of 'htmx' for partial page updates with the power of 'plumber2' for non-blocking HTTP endpoints. Build interactive dashboards and data applications without writing 'JavaScript', using familiar 'R' patterns inspired by 'Shiny'. For more information on 'htmx', see https://htmx.org. |
| License: | MIT + file LICENSE |
| URL: | https://hyperverse-r.github.io/htmxr/, https://github.com/hyperverse-r/htmxr |
| BugReports: | https://github.com/hyperverse-r/htmxr/issues |
| Depends: | R (≥ 4.1.0) |
| Imports: | htmltools, plumber2 |
| Suggests: | dplyr, ggplot2, purrr, svglite, testthat (≥ 3.0.0) |
| Config/testthat/edition: | 3 |
| Encoding: | UTF-8 |
| RoxygenNote: | 7.3.3 |
| NeedsCompilation: | no |
| Packaged: | 2026-03-06 00:12:34 UTC; arthur |
| Author: | Arthur Bréant [aut, cre] |
| Maintainer: | Arthur Bréant <arthur@thinkr.fr> |
| Repository: | CRAN |
| Date/Publication: | 2026-03-06 08:10:19 UTC |
Button element
Description
Creates a <button> element with optional htmx attributes.
Usage
hx_button(
id,
label = NULL,
class = NULL,
get = NULL,
post = NULL,
target = NULL,
swap = NULL,
trigger = NULL,
indicator = NULL,
swap_oob = NULL,
confirm = NULL,
...
)
Arguments
id |
Element id. |
label |
Button label (text or HTML content). Pass |
class |
Optional CSS class(es). |
get |
URL for |
post |
URL for |
target |
CSS selector for |
swap |
Swap strategy for |
trigger |
Trigger specification for |
indicator |
CSS selector for |
swap_oob |
Out-of-band swap targets for |
confirm |
Confirmation message for |
... |
Additional HTML attributes passed to the |
Value
An htmltools::tags object.
Examples
# Simple button
hx_button("btn1", "Click me")
# Button with htmx GET request
hx_button("load-btn", "Load data", get = "/api/data", target = "#result")
# Button with confirmation
hx_button("del-btn", "Delete", post = "/api/delete", confirm = "Are you sure?")
Specify additional head elements for an htmxr page
Description
Wraps tags to be included in the page head when passed to hx_page().
Usage
hx_head(..., title = "htmxr page")
Arguments
... |
tags to include in the head (stylesheets, scripts, meta, etc.) |
title |
page title |
Value
A list with class hx_head, to be passed to hx_page().
Examples
hx_head(title = "My app")
hx_head(
title = "My app",
tags$link(rel = "stylesheet", href = "/style.css")
)
Detect if a request comes from htmx
Description
Checks whether the incoming HTTP request was made by htmx by inspecting
the HX-Request header. htmx sends this header with every AJAX request.
Usage
hx_is_htmx(request)
Arguments
request |
A request object (e.g. from a plumber2 handler). Must have
a |
Value
TRUE if the request was made by htmx, FALSE otherwise.
Examples
# Simulated htmx request
req <- list(headers = list(`hx-request` = "true"))
hx_is_htmx(req)
# Regular request
req <- list(headers = list())
hx_is_htmx(req)
Generate a complete HTML page with htmx
Description
Generate a complete HTML page with htmx
Usage
hx_page(..., lang = "en", html_attrs = list())
Arguments
... |
page content. Use |
lang |
language code for the |
html_attrs |
a named list of additional attributes to set on the
|
Value
A length-one character string containing the full HTML document
(including <!DOCTYPE html>), ready to be served as an HTTP response.
Examples
hx_page(tags$h1("Hello, htmxr!"))
hx_page(
hx_head(title = "My app"),
tags$p("Hello, world!")
)
Run an htmxr example
Description
Launches an example API that demonstrates htmxr features.
Call hx_run_example() without arguments to list available examples.
Usage
hx_run_example(example = NULL, port = 8080)
Arguments
example |
name of the example to run. If |
port |
port to run the API on. |
Value
Called for side effects. When example is NULL, returns the
available example names invisibly. Otherwise does not return (the server
blocks).
Examples
hx_run_example() # list available examples
if (interactive()) {
hx_run_example("hello") # run the hello example
}
Select input
Description
Creates a <select> element with optional htmx attributes.
When label is provided, the input is wrapped in a <div> containing a
<label> element linked via the for attribute.
Usage
hx_select_input(
id,
label = NULL,
choices,
selected = NULL,
multiple = FALSE,
name = id,
class = NULL,
get = NULL,
post = NULL,
target = NULL,
swap = NULL,
trigger = NULL,
indicator = NULL,
swap_oob = NULL,
confirm = NULL,
...
)
Arguments
id |
Element id. Also used as |
label |
Optional label text. When provided, the input is wrapped in a
|
choices |
Named or unnamed character vector of choices. If unnamed, values are used as labels. If named, names are used as labels and values as option values (same convention as Shiny). |
selected |
Optional value(s) to pre-select. |
multiple |
Logical. If |
name |
Form field name. Defaults to |
class |
Optional CSS class(es) for the |
get |
URL for |
post |
URL for |
target |
CSS selector for |
swap |
Swap strategy for |
trigger |
Trigger specification for |
indicator |
CSS selector for |
swap_oob |
Out-of-band swap targets for |
confirm |
Confirmation message for |
... |
Additional HTML attributes passed to the |
Value
An htmltools::tags object.
Examples
# Simple select without label
hx_select_input("cut", choices = c("Fair", "Good", "Ideal"))
# Select with label and named choices
hx_select_input(
"cut",
label = "Filter by cut:",
choices = c("All" = "all", "Fair", "Good", "Ideal"),
selected = "all"
)
# Select with htmx attributes
hx_select_input(
"cut",
label = "Filter by cut:",
choices = c("All" = "all", "Fair", "Good"),
get = "/rows",
trigger = "change",
target = "#tbody"
)
Serve htmxr static assets
Description
Configures a plumber2 API to serve htmxr's static assets
(htmx JavaScript library) at /htmxr/assets/.
Usage
hx_serve_assets(api)
Arguments
api |
a plumber2 API object |
Value
the API object (modified, for piping)
Examples
plumber2::api() |>
hx_serve_assets()
Add htmx attributes to any HTML tag
Description
A generic modifier that appends htmx attributes to an existing htmltools::tags object. Works with any HTML element.
Usage
hx_set(
tag,
get = NULL,
post = NULL,
target = NULL,
swap = NULL,
trigger = NULL,
indicator = NULL,
swap_oob = NULL,
confirm = NULL
)
Arguments
tag |
An htmltools::tags object to modify. |
get |
URL for |
post |
URL for |
target |
CSS selector for |
swap |
Swap strategy for |
trigger |
Trigger specification for |
indicator |
CSS selector for |
swap_oob |
Out-of-band swap targets for |
confirm |
Confirmation message for |
Value
The input tag with htmx attributes appended.
Examples
tags$div(id = "plot") |>
hx_set(get = "/plot", trigger = "load", target = "#plot", swap = "innerHTML")
hx_set(
tags$div(id = "result", class = "container"),
get = "/data",
trigger = "load"
)
Slider input
Description
Creates an <input type="range"> element with optional htmx attributes.
When label is provided, the input is wrapped in a <div> containing a
<label> element linked via the for attribute.
Usage
hx_slider_input(
id,
label = NULL,
value = 50,
min = 0,
max = 100,
step = 1,
name = id,
class = NULL,
get = NULL,
post = NULL,
target = NULL,
swap = NULL,
trigger = NULL,
indicator = NULL,
swap_oob = NULL,
confirm = NULL,
...
)
Arguments
id |
Element id. Also used as |
label |
Optional label text. When provided, the input is wrapped in a
|
value |
Initial value (default |
min |
Minimum value (default |
max |
Maximum value (default |
step |
Step increment (default |
name |
Form field name. Defaults to |
class |
Optional CSS class(es) for the |
get |
URL for |
post |
URL for |
target |
CSS selector for |
swap |
Swap strategy for |
trigger |
Trigger specification for |
indicator |
CSS selector for |
swap_oob |
Out-of-band swap targets for |
confirm |
Confirmation message for |
... |
Additional HTML attributes passed to the |
Value
An htmltools::tags object.
Examples
# Simple slider
hx_slider_input("bins", label = "Number of bins:", min = 1, max = 50)
# Slider with htmx attributes
hx_slider_input(
"bins",
label = "Number of bins:",
value = 30, min = 1, max = 50,
get = "/plot",
trigger = "input changed delay:300ms",
target = "#plot"
)
Table with htmx-powered tbody
Description
Builds a complete <table> element with a <thead> and a <tbody>.
htmx attributes are applied to the <tbody>, making it the swap target.
When data is NULL (the default), the <tbody> is empty and its content
is loaded lazily via htmx (e.g. trigger = "load").
Usage
hx_table(
columns,
data = NULL,
tbody_id = NULL,
col_labels = NULL,
col_classes = NULL,
class = NULL,
thead_class = NULL,
get = NULL,
post = NULL,
target = NULL,
swap = NULL,
trigger = NULL,
indicator = NULL,
swap_oob = NULL,
confirm = NULL,
...
)
Arguments
columns |
Character vector of column names to display. Defines the
|
data |
Optional data frame. If provided, rows are rendered in the
|
tbody_id |
|
col_labels |
Labels for the |
col_classes |
Named list of CSS classes for |
class |
CSS class(es) for the |
thead_class |
CSS class(es) for the |
get |
URL for |
post |
URL for |
target |
CSS selector for |
swap |
Swap strategy for |
trigger |
Trigger specification for |
indicator |
CSS selector for |
swap_oob |
Out-of-band swap targets for |
confirm |
Confirmation message for |
... |
Additional HTML attributes passed to the |
Value
An htmltools::tags object (<table>).
Examples
# Lazy-load table (empty tbody, content loaded on trigger)
hx_table(
columns = c("cut", "color", "price"),
col_labels = c("Cut", "Color", "Price"),
tbody_id = "tbody",
get = "/rows",
trigger = "load",
swap = "innerHTML"
)
# Table with data pre-rendered
df <- data.frame(cut = c("Fair", "Good"), price = c(326L, 400L))
hx_table(columns = c("cut", "price"), data = df)
Table rows fragment
Description
Converts a data frame into a tagList of <tr> elements, one per row.
Designed to be used as a fragment endpoint response — the output replaces
a <tbody> via htmx swap.
Usage
hx_table_rows(data, columns = NULL, col_classes = NULL)
Arguments
data |
A data frame. |
columns |
Character vector of column names to include (and their order).
If |
col_classes |
Named list of CSS classes to add to |
Value
A htmltools::tagList of <tr> tags.
Examples
df <- data.frame(cut = c("Fair", "Good"), price = c(326L, 400L))
hx_table_rows(df, columns = c("cut", "price"))
# With CSS classes on specific columns
hx_table_rows(df, col_classes = list(price = "text-end fw-bold"))
Trigger client-side htmx events via response headers
Description
Adds an HX-Trigger, HX-Trigger-After-Swap, or HX-Trigger-After-Settle
header to a plumber2 response, causing htmx to fire one or more client-side
events after the response is received.
Usage
hx_trigger(response, event)
hx_trigger_after_swap(response, event)
hx_trigger_after_settle(response, event)
Arguments
response |
A plumber2 response object. The parameter must be named
|
event |
One of:
|
Details
Timing variants
-
hx_trigger()— fires immediately when the response is received (HX-Trigger). -
hx_trigger_after_swap()— fires after htmx swaps the new content into the DOM (HX-Trigger-After-Swap). Use this when the event handler needs to interact with the freshly-swapped elements. -
hx_trigger_after_settle()— fires after htmx settles (CSS transitions complete) (HX-Trigger-After-Settle).
Detail serialisation
When event is a named list, values are serialised to JSON using a minimal
built-in serialiser that supports NULL, logicals, numbers, strings, and
named lists of the above. No external dependency required.
Value
The response object response, invisibly.
Examples
## Not run:
#* @post /submit
function(response) {
# Simple event
hx_trigger(response, "formSubmitted")
# Multiple events
hx_trigger(response, c("formSubmitted", "refresh"))
# Event with detail payload
hx_trigger(response, list(showMessage = list(level = "info", text = "Saved!")))
list(status = "ok")
}
## End(Not run)
Objects exported from other packages
Description
These objects are imported from other packages. Follow the links below to see their documentation.