Setup
vite-plus (alias vite → @voidzero-dev/vite-plus-core) 0.1.22
@cloudflare/vite-plugin ^1.37.2 (workerd SSR environment)
@tanstack/react-start ^1.168.10 + @tanstack/react-router ^1.170.7
- React 19,
@vitejs/plugin-react ^6.0.2
- bun workspaces, single app uses TanStack Start
vite.config.ts mirrors the working garden setup exactly (vanilla Vite 8 + same environments.ssr.optimizeDeps.include list + same plugin order):
```ts
export default defineConfig({
resolve: { tsconfigPaths: true, dedupe: ["react", "react-dom"] },
environments: {
ssr: {
optimizeDeps: {
include: [
"react", "react/jsx-runtime", "react/jsx-dev-runtime",
"react-dom", "react-dom/server",
"@tanstack/react-router > @tanstack/react-store",
],
},
},
},
plugins: [
cloudflare({ viteEnvironment: { name: "ssr" } }),
agents(),
tailwindcss(),
tanstackStart(),
viteReact(),
],
});
```
What happens
SSR shell render of `HeadContent` crashes with React invalid-hook-call:
```
TypeError: Cannot read properties of null (reading 'useContext')
at exports.useContext (deps_ssr/react.js?v=…:706)
at useRouter (@tanstack/react-router/src/useRouter.tsx:20)
at useTags (@tanstack/react-router/src/headContentUtils.tsx:213)
at HeadContent (@tanstack/react-router/src/HeadContent.dev.tsx:22)
```
i.e. the classic two-copies-of-React-in-workerd-SSR situation that cloudflare/workers-sdk#11825 describes. Browser ends up on the JSON 500 page (`{"status":500,"message":"HTTPError"}`).
The exact same source tree + the exact same config, run on vanilla Vite 8 in another project (https://github.com/voidzero-dev/garden parallel — its `apps/web` works fine), renders cleanly.
Comparison
|
vanilla Vite 8 (garden) |
vite-plus-core 0.1.22 (this repo) |
| Same vite.config |
works |
500 with useContext null in HeadContent |
| Same plugin order |
works |
broken |
| Same SSR optimizeDeps.include |
works |
broken |
Switching this repo's catalog alias to vanilla Vite 8 doesn't fully fix it either — first `/` render works, but on any subsequent SSR render of the route (HMR reload, client navigate, etc.) the same useContext null surfaces.
Suspicion
@voidzero-dev/vite-plus-core ships its own (rolldown-backed?) Vite that handles `environments.ssr.optimizeDeps` differently from upstream Vite's dep optimizer, so the React module the workerd runner ends up with isn't the same instance the route bundle imports. This trips every provider hook downstream (useContext in HeadContent, useEffect in QueryClientProvider, etc.).
Repro repo: I can put one up if helpful — but the diff against the existing TanStack Start cloudflare example is essentially "swap upstream Vite for the vite-plus-core alias and add @cloudflare/vite-plugin".
Related
Setup
vite-plus(aliasvite→@voidzero-dev/vite-plus-core)0.1.22@cloudflare/vite-plugin^1.37.2(workerd SSR environment)@tanstack/react-start^1.168.10+@tanstack/react-router^1.170.7@vitejs/plugin-react^6.0.2vite.config.tsmirrors the working garden setup exactly (vanilla Vite 8 + sameenvironments.ssr.optimizeDeps.includelist + same plugin order):```ts
export default defineConfig({
resolve: { tsconfigPaths: true, dedupe: ["react", "react-dom"] },
environments: {
ssr: {
optimizeDeps: {
include: [
"react", "react/jsx-runtime", "react/jsx-dev-runtime",
"react-dom", "react-dom/server",
"@tanstack/react-router > @tanstack/react-store",
],
},
},
},
plugins: [
cloudflare({ viteEnvironment: { name: "ssr" } }),
agents(),
tailwindcss(),
tanstackStart(),
viteReact(),
],
});
```
What happens
SSR shell render of `HeadContent` crashes with React invalid-hook-call:
```
TypeError: Cannot read properties of null (reading 'useContext')
at exports.useContext (deps_ssr/react.js?v=…:706)
at useRouter (@tanstack/react-router/src/useRouter.tsx:20)
at useTags (@tanstack/react-router/src/headContentUtils.tsx:213)
at HeadContent (@tanstack/react-router/src/HeadContent.dev.tsx:22)
```
i.e. the classic two-copies-of-React-in-workerd-SSR situation that cloudflare/workers-sdk#11825 describes. Browser ends up on the JSON 500 page (`{"status":500,"message":"HTTPError"}`).
The exact same source tree + the exact same config, run on vanilla Vite 8 in another project (https://github.com/voidzero-dev/garden parallel — its `apps/web` works fine), renders cleanly.
Comparison
Switching this repo's catalog alias to vanilla Vite 8 doesn't fully fix it either — first `/` render works, but on any subsequent SSR render of the route (HMR reload, client navigate, etc.) the same useContext null surfaces.
Suspicion
@voidzero-dev/vite-plus-coreships its own (rolldown-backed?) Vite that handles `environments.ssr.optimizeDeps` differently from upstream Vite's dep optimizer, so the React module the workerd runner ends up with isn't the same instance the route bundle imports. This trips every provider hook downstream (useContextinHeadContent,useEffectinQueryClientProvider, etc.).Repro repo: I can put one up if helpful — but the diff against the existing TanStack Start cloudflare example is essentially "swap upstream Vite for the vite-plus-core alias and add
@cloudflare/vite-plugin".Related