fix(examples): mount www/ in Core-mode apps - #210
Merged
schloerke merged 1 commit intoAug 19, 2026
Conversation
page_react_html() reads index.html but does not serve the files index.html
references. Shiny Express mounts the app directory's www/ at "/"
automatically (shiny/express/_run.py); Core's App() leaves static_assets
None, so the page loaded and then 404'd on its own app.js and main.css.
Both Core examples were affected — 01-hello/app-core.py and, less visibly,
10-bookmarking/app.py, which rendered a blank page because its entire client
bundle 404'd. Both now pass static_assets={"/": <app dir>/www}.
Documents the requirement where a Core user will actually meet it: a
"Serving the client's files" section in page_react_html()'s docstring and the
Core snippet in pkg-py/README.md. R needs no counterpart — shiny::runApp()
serves www/ next to app.R automatically.
Docs-and-examples only; no package behavior change, so no new tests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #207 (base
schloerke/example1-oldfaithful-hello). Split out of that PR to keep the two ideas separate: #207 rewrites the 01-hello example, this fixes a real bug it happened to surface.The bug
page_react_html()readsindex.htmlbut does not serve the filesindex.htmlreferences. Shiny Express mounts the app directory'swww/at/automatically:Core's
App()has no equivalent —static_assetsdefaults toNone. So every Core app in this repo served/fine and then 404'd on its own scripts and stylesheets.This is not a path-resolution issue (
page_react_html()foundindex.htmlcorrectly all along), which is why it presented as "the page loads but nothing renders."What was broken
Both Core-mode examples, and only those:
examples/01-hello/app-core.py— 404 on/app.jsand/main.css.examples/10-bookmarking/app.py— same cause, worse symptom: its entire client bundle 404'd, so it rendered a completely blank page.Both now pass
static_assets={"/": Path(__file__).parent / "www"}.I swept all ten examples to confirm the blast radius. Eight are Express (
set_react_page()) and unaffected. The remaining 404s are unrelated and expected:03-columns-shadcn/04-shadcnneednpm run build(their bundles are gitignored) and09-hmrgetswww/app.jsfrom the Vite dev server. Proof those are not this bug:www/index.htmllives inside the mounted directory, andcurl /index.htmlreturns 200 on both — the mount is live, the bundles just aren't built.Docs
The trap is invisible until you run the app, so it's documented where a Core user will actually meet it:
page_react_html()'s docstring, with the working snippetpkg-py/README.md, which previously showedApp(page_react_html(...), server)— i.e. the broken formR needs no counterpart:
shiny::runApp()serveswww/next toapp.Rautomatically. That is exactly why 01-hello'sapp.Rworked all along and masked the Python-side gap.Tests
None added — this is docs-and-examples only, with no package behavior change (
page_react_html()is untouched apart from its docstring), so there is nothing new to assert.Worth considering as follow-ups, happy to file either:
examples/— boot each app, assert/and everysrc/hrefin itsindex.htmlreturns 200. This is how 10-bookmarking's blank page would have been caught instead of sitting broken.page_react_html()when the resolvedindex.html's directory isn't among the app's static mounts. That is a real behavior change and would need its own tests.Verification
app-core.py:/,/app.js,/main.cssall 200, and the full slider → histogram round trip drives correctly in a browser.10-bookmarking: renders again, and bookmark restore still hydrates —?_inputs_&txt="hi"&num=7populates the inputs and the server echoestext='hi' num=7.favicon.ico.make py-check-tests(74 passed),make py-check-typesclean,ruffclean.Stack created with GitHub Stacks CLI • Give Feedback 💬