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
@vitejs/plugin-react 'can't detect preamble' on module-shipped .tsx pages #66
@vitejs/plugin-react raises "can't detect preamble. Something is wrong." for any module-shipped .tsx page (i.e. files served from outside host/client_app/).
Module pages live either in:
modules/<m>/lacowiki_<m>/pages/Login.tsx (workspace member), or
Vite's dev server is configured with server.fs.allow to read these (the bundled vite.config.ts does this correctly). But @vitejs/plugin-react's React Fast Refresh preamble is only injected into the host's index.html. When the .tsx is served via Vite's /@fs/ mechanism from outside client_app/, the per-component preamble check fires before the entry-point preamble has executed in the same JS realm, and the plugin throws.
Reproduction
Scaffold a host with sm new --preset full.
Install any framework module that ships pages (e.g. simple_module_users ships Login.tsx from its wheel).
npm run dev.
Navigate to /login. Console:
Error: @vitejs/plugin-react can't detect preamble. Something is wrong.
at http://localhost:5050/@fs/.../site-packages/users/pages/Login.tsx:277:11
White screen.
Workarounds I've tried
Clearing .vite cache → no change.
Adding optimizeDeps.include for the user-facing entry → no change.
Hard reload → no change. Issue is consistent.
Suggested investigation
The host's main.tsx already wraps Inertia setup with createRoot(). The plugin's preamble is sourced from __vite_plugin_react_preamble_installed__ on globalThis. When the cross-origin .tsx is loaded via /@fs/, the realm matches but the load order may race. Possibly the React plugin needs include configured for the absolute paths in server.fs.allow, or the host scaffold should enable fastRefresh: false for non-host paths.
A working test would be: configure react() plugin to skip Fast Refresh entirely for files outside __dirname, or ship the host's main.tsx with a manual preamble bootstrap.
Impact
This blocks the entire dev server for any host that consumes module-shipped pages — which is every real installation, since simple_module_users ships Login.tsx and all --preset full hosts use it.
Environment
vite@6.4.2, @vitejs/plugin-react@5.x
simple_module_users page served from .venv/lib/python3.12/site-packages/users/pages/Login.tsx
Closing — addressed by commit ade3e24 (PR #98). host/client_app/vite.config.ts now sets resolve.dedupe: ['react', 'react-dom', 'react/jsx-runtime', 'react/jsx-dev-runtime'] and pre-bundles them via optimizeDeps.include. Module-shipped .tsx pages served via /@fs/ resolve to the same React copy as the host entry, so @vitejs/plugin-react's preamble check no longer fails.
Activity
fix: address framework papercuts (#66, #68, #71, #73, #75, #76, #81, #90
antosubash commentedon May 1, 2026
Closing — addressed by commit ade3e24 (PR #98).
host/client_app/vite.config.tsnow setsresolve.dedupe: ['react', 'react-dom', 'react/jsx-runtime', 'react/jsx-dev-runtime']and pre-bundles them viaoptimizeDeps.include. Module-shipped.tsxpages served via/@fs/resolve to the same React copy as the host entry, so@vitejs/plugin-react's preamble check no longer fails.Generated by Claude Code