#SPA mode error when deploying to CF

17 messages · Page 1 of 1 (latest)

modest flare
#

im getting a TypeError: Cannot read properties of undefined (reading 'compatibilityFlags') error when deploying to CF with start when i enable SPA mode with these settings:

// vite.config.ts
export default defineConfig({
  plugins: [
    ...
    cloudflare({ viteEnvironment: { name: 'ssr' } }),
    tanstackStart({
      spa: {
        enabled: true,
      },
    }),
  ],
})

reverting the commit makes it work again

any ideas why this happens?

Also noticed that ssr is set to true under the CF plugin as based on the deployement guide
Could this be the reason? Any way to deploy start to CF with ssr set to false?

old quartz
#

<@&1433977931444519046>

#

where does this error occur?

#

locally?

modest flare
old quartz
#

so thats a good question for our cloudflare colleagues here then

modest flare
#

thanks, i'll also try crossposting on the cf server

delicate sierra
#

SPA mode does prerendering and this doesn't currently work with Cloudflare because Start prerenders in Node. The error is because Node is trying to access a value that only exists in the Workers runtime. We are currently working together on a solution to make prerendering runtime agnostic so that routes will be prerendered in the target runtime.

thorn minnow
#

Any timeline on this? Are there any current workarounds?

old quartz
thorn minnow
#

Is there a deployment guide to Cloudflare pages?

modern oar
thorn minnow
#

Ok - my understanding is that workers is suitable to deploy static assets but I can’t find any info on configuring this in my app/wrangler config. The normal CF guide fails to deploy with spa mode enabled

thorn minnow
#

Here’s what I found via some LLM assisted sluething;


### Why `server.js` exists in SPA mode

With this config:

```ts
tanstackStart({
  spa: {
    enabled: true,
    prerender: {
      outputPath: '/',
      crawlLinks: true,
      retryCount: 3,
    },
  },
})

Start is doing static prerendering of your routes. To prerender, it spins up a Node-ish server build, hits the routes, writes out HTML, then leaves that server bundle in the build output. That server.js is build-time only – it is not needed (or used) at runtime on Cloudflare if you’re serving a pure SPA with static assets.

So from Cloudflare’s point of view it’s just “another file in dist”, and static-assets happily uploads it.

You have two sane options.


Option 1: Only point Wrangler at the client output

If your build output looks something like:

dist/
  client/
    index.html
    assets/...
  server/
    server.js

(or .output/public + .output/server), then set assets.directory to the client/public dir only:

# wrangler.toml
name = "my-tanstack-spa"
compatibility_date = "2025-01-01"

[assets]
directory = "./dist/client"            # or "./.output/public"
not_found_handling = "single-page-application"

Now server.js simply isn’t in the assets tree, so it’s never uploaded.


Option 2: Use .assetsignore to exclude server.js

If you can’t or don’t want to change the directory (e.g. everything is flattened into dist/), add an .assetsignore file inside that directory:

# dist/.assetsignore
server.js
server.mjs
server/**

Wrangler uses .assetsignore just like .gitignore and will skip matching files when uploading static assets.


Does this check out?
thorn minnow
#

Seems to be working 👍