#Problems with hosting on Vercel | Nitro V3 & Vite v8

54 messages · Page 1 of 1 (latest)

thin pasture
#

After upgrading my project to Vite v8 - the Vercel builds still succes’s but visiting the app just says http status 500.

If i downgrade to vite 7.3.1 it works.

Have anyone faced this issue?

Tanstack start, Tanstack query, vite v8 and nitro v3 - monorepo.

young plume
#

i think ts start doesnt support vite 8 yet

thin pasture
sacred inlet
#

Start should work fine with Vite 8

#

what nitro version are you on? beta/alpha/nightly? and have you upgraded other plugins?

thin pasture
#

Oh just saw that you are the creator of the starter pack I am following 🙂 Well done dude! But yeah it does not work for me

sacred inlet
#

there are also logs on Vercel (the Logs tab) whenever you get status 500 which will make it easier to pinpoint the issue

#

also any chance you're using the Tooltip (specifically TooltipProvider) component from shadcn/base-ui? i remember having an issue with it in the monorepo version, where it breaks ssr due to bundling issues with this error below. i never really had the time to investigate it though, I just removed TooltipProvider from root and moved it to the dashboard layout

Error: Cannot find module 'react'
Require stack:
- /var/task/_ssr/chunk-bm1JCPTs.mjs
thin pasture
# sacred inlet anything else you can share about your dependencies/plugins? and vite config?

My config looks like 99% if not 100% like the one on the repo itself. However the weird thing is that everything works fine locally, build succeeds, app works etc. But when deployed to vercel it succeeds but app is 500 HTTPS error - and server logs says errors like this:

TypeError: Cannot destructure property '__extends' of '__toESM$1(...).default' as it is undefined.
at file:///var/task/_ssr/command-jUpCaa45.mjs:827:7
... 5 lines matching cause stack trace ...
at async Object.fetch (file:///var/task/_ssr/ssr.mjs:5476:10) {
cause: TypeError: Cannot destructure property '__extends' of '__toESM$1(...).default' as it is undefined.
at file:///var/task/_ssr/command-jUpCaa45.mjs:827:7
at ModuleJob.run (node:internal/modules/esm/module_job:413:25)
at process.processTicksAndRejections (node:internal/process/task_queues:103:5)
at async onImport.tracePromise.proto (node:internal/modules/esm/loader:660:26)
at async loadEntries (file:///var/task/_ssr/ssr.mjs:5121:22)
at async startRequestResolver (file:///var/task/_ssr/ssr.mjs:5306:20)
at async Object.fetch (file:///var/task/_ssr/ssr.mjs:5476:10),
status: 500,
statusText: undefined,
headers: undefined,
data: undefined,
body: undefined,
unhandled: true
}

#

This points to the command component from Shadcn having some underlying dependencies under the hood that vite v8 does not support - so it seems. I tried every work around ever, and nothing helped. So now i just reverted back to vite v 7.3.1 instead.

#

@sacred inlet If you try on your project to install the command component from shadcn, use it in your project and deploy to vercel - will the production app still work? or do you get 500 https error

sacred inlet
#

how is your monorepo structured? are you using turborepo or vite+? and ui is in a different package/workspace outside the web app?

thin pasture
#

I am using turborepo, and ui is in a different package yes. Outside the web app

thin pasture
sacred inlet
sacred inlet
#

there is definitely an issue here though with Vite 8 in a monorepo setup. I'm not seeing this issue in non-monorepo setups

I'm also getting SSR/hydration errors, even when starting from the official shadcn/ui monorepo template (e.g. pnpm dlx shadcn@latest init --preset b2D2iPH7I --base base --template start --monorepo) and manually upgrading it to Vite 8 with components like Tooltip, DropdownMenu, Command

#

deduping/tracing react helps for the other components

from @ivory wing's vite config:
https://github.com/tsu-moe/tsu-stack/blob/main/apps/web/vite.config.ts#L122-L127

// vite.config.ts
export default defineConfig({
  resolve: {
+   dedupe: ["react", "react-dom"],
    tsconfigPaths: true,
  },
  plugins: [
    nitro({
+     traceDeps: ["react"],
    }),

for Command I'm just wrapping it in ClientOnly for now since I don't need it open on page load

cyan nacelle
#

does this all work without nitro?

thin pasture
thin pasture
thin pasture
cyan nacelle
#

theoretically no, but practically yes

#

just want to know if this is somehow caused by nitro

#

if yes we should involve pi0

sacred inlet
#

let me try with other adapters

sacred inlet
#

repro is from the official shadcn/ui monorepo template:

pnpm dlx shadcn@latest init --preset b2D2iPH7I --base base --template start --monorepo

and manually upgrading it to Vite 8 with components like Tooltip, DropdownMenu, Command added to the index page

cyan nacelle
#

cc @fallow carbon

cyan nacelle
sacred inlet
fallow carbon
#

error seems comming from rolldown/vite8 bundling. Adding react, react-dom to trace deps fixes issues for me. no dedup needed. https://tss-test-web.vercel.app/

export default defineConfig({
  resolve: {
    tsconfigPaths: true,
  },
  nitro: {
    traceDeps: ["react", "react-dom"],
  },
  plugins: [
    nitro(),
    tailwindcss(),
    tanstackStart(),
    viteReact(),
  ],
}) 
thin pasture
#

Build seems to work locally:

Following the vite config of https://github.dev/mugnavo/tanstarter/blob/main/vite.config.ts with added nitro: {
traceDeps: ["react", "react-dom"],
},

Build on Vercel succeeds, but visiting application gives https 500 error.

Server logs shows:
2026-04-06 08:53:58.715 [error] Error: Client-only API called on the server side. Run client-only code in onMount, or conditionally run client-only component with <Show>.
at notSup (file:///var/task/_libs/@solid-primitives/event-listener+%5B...%5D.mjs:565:8)
... 3 lines matching cause stack trace ...
at async onImport.tracePromise.proto (node:internal/modules/esm/loader:660:26) {
cause: Error: Client-only API called on the server side. Run client-only code in onMount, or conditionally run client-only component with <Show>.
at notSup (file:///var/task/_libs/@solid-primitives/event-listener+%5B...%5D.mjs:565:8)
at file:///var/task/_libs/@tanstack/devtools+%5B...%5D.mjs:1650:32
at ModuleJob.run (node:internal/modules/esm/module_job:413:25)
at process.processTicksAndRejections (node:internal/process/task_queues:103:5)
at async onImport.tracePromise.proto (node:internal/modules/esm/loader:660:26),
status: 500,
statusText: undefined,
headers: undefined,
data: undefined,
body: undefined,
unhandled: true
}

#

^ this happens after upgrading to vite 8.0.4

sacred inlet
fallow carbon
#

I guess so. Feel free to also open it in nitro with reproduction i can ping vite team there

#

In general react dist is so nasty (CJS) we have traceDeps as escape hatch for such bundler issues..

sacred inlet
thin pasture
thin pasture
# sacred inlet now this is likely from tanstack devtools, can you try commenting out TanstackDe...

Still same error 🙁

TypeError: Cannot destructure property '__extends' of '__toESM(...).default' as it is undefined.
at file:///var/task/_ssr/DaVN2H6n.mjs:827:7
... 5 lines matching cause stack trace ...
at async Object.fetch (file:///var/task/_ssr/scKqIYLB.mjs:5471:10) {
cause: TypeError: Cannot destructure property '__extends' of '__toESM(...).default' as it is undefined.
at file:///var/task/_ssr/DaVN2H6n.mjs:827:7
at ModuleJob.run (node:internal/modules/esm/module_job:413:25)
at process.processTicksAndRejections (node:internal/process/task_queues:103:5)
at async onImport.tracePromise.proto (node:internal/modules/esm/loader:660:26)
at async loadEntries (file:///var/task/_ssr/scKqIYLB.mjs:5116:22)
at async startRequestResolver (file:///var/task/_ssr/scKqIYLB.mjs:5301:20)
at async Object.fetch (file:///var/task/_ssr/scKqIYLB.mjs:5471:10),
status: 500,
statusText: undefined,
headers: undefined,
data: undefined,
body: undefined,
unhandled: true
}

#

Build local and Vercel succeds, it is just the live site that is not working for some reason.

thin pasture
#

vite.config.ts:

#

turbo.json:

fallow carbon
#

@thin pasture please feel free to DM me your repro if private i can check 👍

nocturne ruin
#

Experiencing a similar issue with Start monorepos and Nitro v3/vite 8.

https://github.com/alex-delia/nitro-baseui-bug

Works fine in dev, but after building and running the production build locally, this error appears:

web:start: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
web:start: 1. You might have mismatching versions of React and the renderer (such as React DOM)
web:start: 2. You might be breaking the Rules of Hooks
web:start: 3. You might have more than one copy of React in the same app
web:start: See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.
web:start: 1265 |     exports.useSyncExternalStore = function (
web:start: 1266 |       subscribe,
web:start: 1267 |       getSnapshot,
web:start: 1268 |       getServerSnapshot
web:start: 1269 |     ) {
web:start: 1270 |       return resolveDispatcher().useSyncExternalStore(
web:start:                                       ^
web:start: TypeError: null is not an object (evaluating 'resolveDispatcher().useSyncExternalStore')

Seems to be related to the Baseui dialog being ssr'd and the way Nitro/Vite is bundling the dependency

#

When adding

nitro: {
traceDeps: ["react", "react-dom"],
},

this is the error:

{
  "name": "ResolveMessage",
  "position": null,
  "message": "Cannot find module 'react-dom/server' from '/Users/alexdelia/repos/nitro-start-monorepo-baseui/apps/web/.output/server/_libs/@tanstack/react-router+[...].mjs'",
  "level": "error",
  "specifier": "react-dom/server",
  "importKind": "import-statement",
  "referrer": "/Users/alexdelia/repos/nitro-start-monorepo-baseui/apps/web/.output/server/_libs/@tanstack/react-router+[...].mjs"
}
nocturne ruin
#

Works when dowgrading to vite 7 as well

olive kiln
#

i got vite8 and nitro v3 working on vercel!

add the following inside ur vite.config:

    nitro({
      exportConditions: ['import', 'module', 'default'],
      noExternals: true,
  }),
  ssr: {
    noExternal: true,
  },

#

heres the full vite config i used:

also impt to note, i upgraded the viteReact plugin to the latest version

export default defineConfig({
  server: {
    port: 3001,
  },
  plugins: [
    svgr({
      svgrOptions: { exportType: 'default' },
      include: '**/*.svg',
      exclude: '**/*.svg?url',
      oxcOptions: { jsx: { runtime: 'automatic' } },
    }),
    tsconfigPaths(),
    tanstackStart(),
    devtools({ consolePiping: {} }),
    viteReact(),
    nitro({
      exportConditions: ['import', 'module', 'default'],
      noExternals: true
    }),
  ],
  environments: {
    ssr: { build: { rolldownOptions: { input: './server.ts' } } },
  },
  optimizeDeps: {
    include: ['tslib'],
  },
  ssr: {
    noExternal: true,
    target: 'node',
  },
  build: {
    target: 'esnext',
  },
});