Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion examples/01-hello/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ never tears the SVG down and re-mounts it.
```
examples/01-hello/
├── app.py # Express: set_react_page() + 2 reactive_output outputs
├── app-core.py # Core: page_react_html() + App(app_ui, server), same outputs
├── app-core.py # Core: page_react_html() + App(..., static_assets=), same outputs
├── app.R # R: page_react_html() + reactive_output, same outputs
├── faithful.py # Old Faithful waiting times + a stdlib-only binner (Python)
├── faithful.csv # base R's `faithful` dataset, exported for the Python servers
Expand All @@ -56,6 +56,11 @@ return `NULL` until the client's first `bins` message arrives (Python raises a
silent exception instead), and wrap the histogram vectors in `I()` so a
single-bin result still serializes as a JSON array rather than a scalar.

`app-core.py` passes `static_assets={"/": .../www}` to `App()`. Shiny Express
(`app.py`) and R's `runApp()` (`app.R`) both mount the app directory's `www/`
automatically; Core's `App()` does not, so without it `index.html` loads and
then 404s on `app.js` and `main.css`.

## Bridge primitives used

- `from shinyreact import reactive_output, set_react_page` (Express server, `app.py`) / `page_react_html` (Core server, `app-core.py`); `library(shinyreact)` with `page_react_html()` + `reactive_output()` in `app.R`
Expand Down
7 changes: 6 additions & 1 deletion examples/01-hello/app-core.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from pathlib import Path

from faithful import histogram, waiting
from shiny import App, Inputs, Outputs, Session
from shinyreact import page_react_html, reactive_output
Expand All @@ -16,4 +18,7 @@ def dist_caption():
return f"{len(waiting)} eruptions in {n} bin{'' if n == 1 else 's'}"


app = App(app_ui, server)
# Core apps must mount www/ themselves. Shiny Express auto-serves the app
# directory's www/ at "/", but App() does not — without this, index.html loads
# and then 404s on app.js and main.css.
app = App(app_ui, server, static_assets={"/": Path(__file__).parent / "www"})
11 changes: 10 additions & 1 deletion examples/10-bookmarking/app.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from pathlib import Path

import shinyreact
from shiny import App, Inputs, Outputs, Session, reactive

Expand All @@ -21,4 +23,11 @@ async def _on_bookmark_click() -> None:
await session.bookmark()


app = App(app_ui, server, bookmark_store="url")
# Core apps must mount www/ themselves — App() has no equivalent of Shiny
# Express's automatic www/ static mount.
app = App(
app_ui,
server,
static_assets={"/": Path(__file__).parent / "www"},
bookmark_store="url",
)
11 changes: 9 additions & 2 deletions pkg-py/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,20 @@ def greeting():

Pair with a `www/index.html` that loads your React client (no-build `app.js` or a built bundle from `src/ui.tsx`). See the [examples catalog](../examples/README.md) for file layouts and dev workflows, from no-build to Vite + HMR.

In Core mode, use `page_react_html()`:
In Core mode, use `page_react_html()`. Core apps must also mount `www/`
themselves — Shiny Express does this automatically, `App()` does not, and
without it the page loads and then 404s on its own scripts and stylesheets:

```python
from pathlib import Path
from shiny import App
import shinyreact

app = App(shinyreact.page_react_html("www/index.html"), server)
app = App(
shinyreact.page_react_html("www/index.html"),
server,
static_assets={"/": Path(__file__).parent / "www"},
)
```

### Sending messages to React components
Expand Down
21 changes: 21 additions & 0 deletions pkg-py/src/shinyreact/_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,27 @@ def page_react_html(path: str | Path = "www/index.html") -> TagList:
Unlike :func:`set_react_page`, this does not auto-discover dependencies
from traditional Shiny renderers — it only attaches the shinyreact bundle.

Serving the client's files
--------------------------
This function only reads ``index.html``; it does not serve the sibling
files that ``index.html`` references. Shiny Express mounts the app
directory's ``www/`` at ``/`` automatically, but :class:`shiny.App` does
not, so a Core app must do it explicitly — otherwise the page loads and
then 404s on its own scripts and stylesheets::

from pathlib import Path
from shiny import App
from shinyreact import page_react_html

app = App(
page_react_html(),
server,
static_assets={"/": Path(__file__).parent / "www"},
)

(R's ``shiny::runApp()`` serves ``www/`` next to ``app.R`` automatically,
so the R counterpart needs no equivalent.)

Args:
path: Path to the HTML file. Absolute paths are used verbatim;
relative paths resolve against the caller module's directory, or
Expand Down
Loading