Multipage 'Shiny' Apps

Build natively multi-page 'Shiny' applications, serving content on several endpoints instead of a single page. Pages are declared with their own user interface and server function and are dispatched by URL with 'routr', including parameterised routes. Redirections, request and response middleware, and helpers to read and set cookies are also provided.


brochure brochure hex logo

Lifecycle:stable R-CMD-check

Build natively multi-page {shiny} applications.

A {shiny} app is a single page: one url, one UI, one server function. {brochure} makes it several. You declare a page() with its own href, its own UI and its own server function, and the request is dispatched to it by {routr} — including parameterised routes such as /user/:id. Redirections, request and response middleware, and cookie helpers come with it.

Disclaimer: building an app with {brochure} is different from the way you usually build {shiny} apps, as you no longer operate under the single page app paradigm. vignette("design") covers what changes.

Installation

remotes::install_github("ColinFay/brochure")

{brochure} exports page(), which masks utils::page():

library(brochure)
#> 
#> Attaching package: 'brochure'
#> The following object is masked from 'package:utils':
#> 
#>     page

A minimal app

Each page has its own url, its own UI, its own server function, and its own Shiny session. The server is optional if the page is static.

library(shiny)
library(brochure)

brochureApp(
  page(
    href = "/",
    ui = fluidPage(
      h1("Home"),
      plotOutput("plot"),
      tags$a(href = "/contact", "Contact us")
    ),
    server = function(input, output, session) {
      output$plot <- renderPlot({
        plot(iris)
      })
    }
  ),
  page(
    href = "/contact",
    ui = fluidPage(
      h1("Contact"),
      tags$p("No server function in this one.")
    )
  ),
  redirect(from = "/index.html", to = "/")
)

Run it as you would any Shiny app, then navigate to / and to /contact. Moving from one page to the other is a plain link: the browser leaves the first page and opens a new session on the second one.

A parameterised href matches one segment, and the page reads what it matched with get_keys():

page(
  href = "/user/:id",
  ui = function(request) {
    fluidPage(h1(paste("User", get_keys(request)$id)))
  },
  server = function(input, output, session) {
    message("Serving user ", get_keys()$id)
  }
)

User documentation

Everything lives at https://colinfay.me/brochure/.

  • Get started — pages, routing, what every page shares, and reading url parameters
  • Handlers — the request and response middleware, logging, healthchecks, answering before Shiny
  • Cookies — setting, reading and removing cookies, and carrying a session between pages
  • Deployment — serving the app under a prefix, behind a reverse proxy or on Posit Connect
  • golem — building a brochure app as a {golem} package

Technical documentation

Previous work

Other packages implement features that are close to what {brochure} does:

As far as I can tell, they do not serve the same goal, as they both still serve Single Page Applications.

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.

install.packages("brochure")

1.0.0 by Colin Fay, 13 hours ago


https://github.com/colinfay/brochure, https://github.com/ColinFay/brochure


Report a bug at https://github.com/ColinFay/brochure/issues


Browse source code at https://github.com/cran/brochure


Authors: Colin Fay [aut, cre, cph] (ORCID:


Documentation:   PDF Manual  


MIT + file LICENSE license


Imports attempt, htmltools, purrr, rlang, routr, shiny

Suggests golem, knitr, rmarkdown, testthat, usethis, withr


See at CRAN