Reads a complete HTML document — the kind a Vite build emits — and injects
the shinyreact page-level dependencies into it. The document must contain
Shiny's dependency placeholder inside <head>:
Arguments
- path
Path to the HTML document. Defaults to
"www/index.html", relative to the working directory.- ...
Ignored.
- extra_deps
A list of additional htmltools::htmlDependency objects to render at the placeholder. A complete document has no tag tree to attach dependencies to, so this is the only way in — the counterpart of
page_react()'s.... They render after Shiny's and shinyreact's, so they can rely onwindow.shinyreactexisting. Mirrors Python'spage_react_html(extra_deps=).- shinyreact_js
Who supplies
shinyreact.js/shinyreact.css:"server"(the default) or"client"for an npm-tier app whose bundle imports@posit-dev/shinyreact— seepage_react().
Details
Shiny's and shinyreact's script/link tags render in its place. It is an
ordinary <meta> tag rather than template syntax, so the document stays
valid HTML that a bundler's dev server can serve unchanged. Use as the ui
argument: shinyApp(ui = page_react_html(), server = ...).
Assets the document references (your bundle's JS/CSS) should live in www/,
where Shiny serves them statically.
For apps that don't need to own the HTML document, prefer page_react() —
it requires no HTML file at all.
The whole document is a template
R places the dependencies with htmltools::htmlTemplate(), which evaluates
every {{ ... }} in the document as R code — anywhere in it, <head> or
<body>, with the global environment as parent. So a body containing
{{ 6*7 }} renders 42, and {{ nonexistent() }} is an error at page
render.
A document written for a JS templating engine that also uses {{ }}
(Handlebars, Mustache, Vue's text interpolation) is therefore not safe to
pass here as is — those braces will be evaluated as R. Escape them, or use
page_react(), which needs no HTML file at all.
Python's page_react_html() differs: it replaces the placeholder and leaves
the rest of the document untouched. Documented as a deliberate divergence
rather than a bug — see FEATURES.md and issue #223.
Path resolution
A relative path resolves against the process working directory. Under
shiny::runApp() / shiny::shinyApp() that is the app directory, so the
default "www/index.html" just works. R has no per-caller __file__, so
unlike Python — which resolves a relative path against the calling module's
directory — there is nothing to resolve against outside the working
directory. Pass an absolute path if you need to be independent of it.
The placeholder must be spelled exactly as above — the check is a
fixed-string match, so a differently-quoted or reordered <meta> tag is
rejected.