--- title: "Get started with aurora" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Get started with aurora} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(eval = FALSE) ``` ## What aurora is aurora builds **stateless** web apps on top of [plumber2](https://plumber2.posit.co): you author the UI with [bslib](https://rstudio.github.io/bslib/), aurora compiles it to a static `index.html` at build time, and plumber2 serves those assets plus your JSON API routes. You get Shiny-like ergonomics with an API deployment model — no WebSocket, no per-user R process, no sticky sessions. R runs only when a route is called, so an app scales horizontally behind a load balancer or Docker. ## Scaffold, run, add a route ```{r} library(aurora) aurora_create_app("meu_app", template = "minimal") aurora_run("meu_app") # http://127.0.0.1:8000 (docs at /__docs__) # add an API route (writes routers/relatorios.R with the path in the annotation) aurora_add_route("relatorios", dir = "meu_app") ``` During development, `aurora_run("meu_app", watch = TRUE)` rebuilds the static UI whenever `build_ui.R` or `ui_modules/` change — just refresh the browser. ## The app contract (convention, not a manifest) aurora assembles an app from a fixed layout. Nothing here is required to be wired by hand; aurora finds it by convention. ``` meu_app/ ├── api.R # entry point: aurora::aurora_run("."), host/port from env ├── build_ui.R # defines build_ui() -> an htmltools tag ├── helpers/ # *.R sourced BEFORE routers are parsed (db, config, stores) ├── routers/ # plumber2 annotated handlers; the URL is the annotation path ├── ui_modules/ # ui_*.R partials sourced by build_ui.R ├── www/ # static assets: js/core.js (runtime), js/app.js, style.css, images/ ├── data/config.yml # config (the config package) ├── _brand.yml # optional: visual brand consumed by bslib └── _aurora.yml # optional: overrides name / engine / auth / statics ``` ## Writing a route A handler's URL comes from its annotation. Note plumber2 only binds **path** parameters to named arguments; read the query string from the `query` argument and a parsed body from `body` (see `vignette("migrating-from-shiny")`). ```r # routers/sales.R #* @get /api/sales/data #* @serializer json function() { list(categories = c("Jan", "Fev", "Mar"), values = c(120, 200, 150)) } ``` ## Wiring UI to the API aurora ships a thin runtime (`www/js/core.js`) exposing `window.aurora`: a credentialed `fetch`/`json` wrapper plus an `onUnauthorized` hook. It ships **no** rendering code — your `app.js` renders. Use `aurora_component()` to emit an element wired to its endpoint, then read it from JS: ```r # build_ui.R aurora_component("api/sales/data", id = "chart", style = "height:360px;") ``` ```js // www/js/app.js var el = document.getElementById("chart"); aurora.json(el.dataset.endpoint).then(function (d) { echarts.init(el).setOption({ xAxis: { type: "category", data: d.categories }, yAxis: { type: "value" }, series: [{ type: "bar", data: d.values }] }); }); ``` See `inst/examples/02-dashboard-echarts` and `03-map` for full worked apps. ## Theming, data, auth, telemetry - **Theming** — edit `_brand.yml`; bslib bakes it in at build time. The `minimal` template uses `bs_theme(version = 5, brand = TRUE)`. - **Data** — `aurora_data_store()` hands handlers a hot-reloading, globals-free store: `aurora_data_get(store, "sales")` re-reads when the file changes on disk. - **Auth** — opt-in JWT-cookie scheme; scaffold it with `aurora_create_app(..., template = "auth")`. See `vignette("auth")`. - **Telemetry** — `aurora_run(otel = TRUE)`. See `vignette("telemetry")`. - **Shared assets** — serve a directory shared across apps at its own URL prefix with `_aurora.yml`'s `statics:` (e.g. `statics:` then ` /assets: /srv/shared`). See `vignette("deploy")`. ## Deploy ```{r} aurora_dockerfile("meu_app") aurora_build_image("meu_app", tag = "org/meu_app:latest", push = TRUE) ``` See `vignette("deploy")`.