You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
2.0.0-rc.3 | Updates in Document.jsx won't HRM update #3151
Might seem as a silly issue, but any updates on Document.jsx won't hot reload the module. I've added some Tailwind classes on and they only show up in my running app when I manually refresh. The same goes for adding/removing DOM elements, such as an
inside the .
Your Example Website or App
solid 2.0 rc-3
Steps to Reproduce the Bug or Issue
Install solid 2.0 rc-3 (or 4) and try and edit Document.jsx:
Thanks for the report. This is very likely @solidjs/vite-plugin territory rather than core: the document shell (<html>/<head>, HydrationScript) is server-rendered and can't hot-swap like a component, so the expected behavior on a Document edit is a triggered full reload — and it sounds like not even that is happening. To pin it down, could you share which template you started from, your @solidjs/vite-plugin version, and whether editing a regular route component does HMR correctly in the same app? We're tracking it for the plugin either way.
Triage: not silly at all, and reproducible by inspection. A module rendering the document shell (<html>/<head>/<body>) can never hot-swap — the markup it produces is the server-rendered scaffolding the client already claimed at hydration, and there is no boundary to re-render under (replacing document.documentElement live would tear down the whole app anyway). Today solid-refresh wraps or accepts the module like any other component, so the update is absorbed silently and nothing visibly changes — the worst of both worlds.
The correct behavior is for the transform to recognize document-shell modules and decline HMR for them (import.meta.hot.decline()), which makes Vite fall back to a full page reload on save — your Tailwind classes on <html> would then show up immediately, at the cost of a reload, which is the honest cost. The fix belongs in @solidjs/vite-plugin / solid-refresh rather than the core runtime, so it ships on the plugin's release cadence rather than with core rc.5. Leaving this open until it lands there.
Fixed in solidjs/solid-vite-plugin#336. The mechanism turned out to be two-sided, both in the vite plugin's dev serving:
In SSR start mode the client entry hydrates the whole document, so your Document.jsx is a real client module — the HMR transform wrapped it like any component and the update was accepted and silently absorbed (no swap can re-claim document.documentElement). The plugin now declines HMR for the resolved document module specifically, so saving it triggers a full page reload — your Tailwind classes on <html> show up immediately at the honest cost of a reload.
In client (SPA) mode the document is server-graph-only, and server-side updates were suppressed entirely; those now also full-reload the browser.
Ships with the next @solidjs/vite-plugin release; no core change needed.
The plugin now declines HMR for the resolved document module specifically, so saving it triggers a full page reload — your Tailwind classes on show up immediately at the honest cost of a reload.
Fixed in 4da3fb4 on next — the compiler's refresh pass now detects document-shell modules (intrinsic html/head/body) and takes the @refresh reload path (a decline block), so editing Document.jsx triggers a full reload that fetches a fresh server render. A document shell can't hot-swap: its elements compile with no client template (only recoverable from the hydration walk) and its static markup exists only in the server HTML. Ships in the next RC.
Activity
ryansolid commentedon Aug 31, 2026
Thanks for the report. This is very likely @solidjs/vite-plugin territory rather than core: the document shell (
<html>/<head>, HydrationScript) is server-rendered and can't hot-swap like a component, so the expected behavior on a Document edit is a triggered full reload — and it sounds like not even that is happening. To pin it down, could you share which template you started from, your@solidjs/vite-pluginversion, and whether editing a regular route component does HMR correctly in the same app? We're tracking it for the plugin either way.ryansolid commentedon Aug 31, 2026
Triage: not silly at all, and reproducible by inspection. A module rendering the document shell (
<html>/<head>/<body>) can never hot-swap — the markup it produces is the server-rendered scaffolding the client already claimed at hydration, and there is no boundary to re-render under (replacingdocument.documentElementlive would tear down the whole app anyway). Today solid-refresh wraps or accepts the module like any other component, so the update is absorbed silently and nothing visibly changes — the worst of both worlds.The correct behavior is for the transform to recognize document-shell modules and decline HMR for them (
import.meta.hot.decline()), which makes Vite fall back to a full page reload on save — your Tailwind classes on<html>would then show up immediately, at the cost of a reload, which is the honest cost. The fix belongs in@solidjs/vite-plugin/ solid-refresh rather than the core runtime, so it ships on the plugin's release cadence rather than with core rc.5. Leaving this open until it lands there.ryansolid commentedon Aug 31, 2026
Fixed in solidjs/solid-vite-plugin#336. The mechanism turned out to be two-sided, both in the vite plugin's dev serving:
document, so yourDocument.jsxis a real client module — the HMR transform wrapped it like any component and the update was accepted and silently absorbed (no swap can re-claimdocument.documentElement). The plugin now declines HMR for the resolved document module specifically, so saving it triggers a full page reload — your Tailwind classes on<html>show up immediately at the honest cost of a reload.Ships with the next
@solidjs/vite-pluginrelease; no core change needed.karimmaassen commentedon Sep 1, 2026
That's a swift update indeed!
Makes sense.
fix(compiler): decline document-shell modules in refresh pass so edit…
ryansolid commentedon Sep 1, 2026
Fixed in 4da3fb4 on next — the compiler's refresh pass now detects document-shell modules (intrinsic html/head/body) and takes the @refresh reload path (a decline block), so editing Document.jsx triggers a full reload that fetches a fresh server render. A document shell can't hot-swap: its elements compile with no client template (only recoverable from the hydration walk) and its static markup exists only in the server HTML. Ships in the next RC.