reactRouter brings React Router, the world’s most popular React routing library, to R and Shiny.
Why reactRouter?
reactRouter works with Shiny apps and Quarto documents — and also on its own. It extends whatever you are already building with new features:
- URL-based navigation — your application behaves like a real website, with a home page and multiple sub-pages (e.g. one per report or analysis), each with its own shareable URL.
- Reactivity without a server — data loaders fetch and display data as users navigate, entirely in the browser, without requiring a running R server.
- Static hosting — the output is plain HTML/JS, deployable to GitHub Pages, Netlify, Posit Connect, or any static file host (if you don’t use it with Shiny).
Used alone, reactRouter brings the best of both worlds: the reactivity of Shiny (data that updates as users interact) and the simplicity of Quarto (multiple pages as static files, hostable anywhere, no server to maintain or pay for).
Usage
Create URL pages easily:
library(reactRouter)
library(htmltools)
ui <- RouterProvider(
router = createHashRouter(
Route(
path = "/",
element = div(
NavLink(to = "/", "Main"), " | ",
NavLink(to = "/analysis", "Analysis"), hr(),
Outlet()
),
Route(index = TRUE, element = "Main content"),
Route(path = "analysis", element = "Analysis content")
)
)
)
# htmltools::save_html(ui, "index.html")
htmltools::browsable(ui)Or use data loaders to fetch and display data client-side — no R server needed:
library(reactRouter)
library(htmltools)
# local or fetch an API
people_json <- jsonlite::toJSON(dplyr::starwars, dataframe = "rows", auto_unbox = TRUE)
ui <- RouterProvider(
router = createHashRouter(
Route(
path = "/",
element = div(
NavLink(to = "/", "Home"), " | ",
NavLink(to = "/people/1", "Luke"),
hr(), Outlet()
),
Route(index = TRUE, element = p("Try #/people/4 for Darth Vader.")),
Route(
path = "people/:id",
loader = JS(sprintf("({ params }) => (%s)[params.id - 1]", people_json)),
element = div(
useLoaderData(tags$h3(), selector = "name"),
useLoaderData(tags$p(), selector = "homeworld")
)
)
)
)
)
# htmltools::save_html(ui, "index.html")
htmltools::browsable(ui)Install
For current version 0.2.0 (coming soon on CRAN):
remotes::install_github("lgnbhl/reactRouter") # development versionFor older version 0.1.1 (older version on CRAN):
install.packages("reactRouter")Acknowledgements
reactRouter is built on top of shiny.react, the R package by Appsilon that makes it possible to use React components in Shiny and Quarto.
Data loaders work seamlessly with any R package that uses shiny.react under the hood. This includes the MUI component ecosystem for R:
- muiMaterial — Material UI components (buttons, dialogs, tabs, and more)
- muiDataGrid — interactive data grids
- muiCharts — charts and visualisations
- muiTreeView — tree view components
Learn more about how to use data loaders with these R packages here.
Contribute
Would you like to contribute to the package? Have a look at the current roadmap.
