Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server function calls not working on Cloudflare #2633

Closed
dotnize opened this issue Oct 24, 2024 · 15 comments · Fixed by #2744
Closed

server function calls not working on Cloudflare #2633

dotnize opened this issue Oct 24, 2024 · 15 comments · Fixed by #2744
Labels
start Everything about TanStack Start

Comments

@dotnize
Copy link

dotnize commented Oct 24, 2024

Which project does this relate to?

Start

Describe the bug

Server functions don't work on Cloudflare deployments (via cloudflare-pages preset), wrangler dev, and apparently also on Stackblitz.

[wrangler:inf] GET / 200 OK (56ms)
✘ [ERROR] Error: Context is not available

      at Object.use
  (file:///home/nize/dev/web/tss-cloudflare-server-fn/.wrangler/tmp/pages-liyiqW/chunks/runtime.mjs:1:103891)
      at V
  (file:///home/nize/dev/web/tss-cloudflare-server-fn/.wrangler/tmp/pages-liyiqW/chunks/runtime.mjs:455:96187)
      at _
  (file:///home/nize/dev/web/tss-cloudflare-server-fn/.wrangler/tmp/pages-liyiqW/chunks/runtime.mjs:455:108302)
      at null.<anonymous>
  (file:///home/nize/dev/web/tss-cloudflare-server-fn/.wrangler/tmp/pages-liyiqW/chunks/runtime.mjs:455:107762)
      at Object.assign._ [as url]
  (file:///home/nize/dev/web/tss-cloudflare-server-fn/.wrangler/tmp/pages-liyiqW/chunks/runtime.mjs:455:108277)
      at Object.assign.url
  (file:///home/nize/dev/web/tss-cloudflare-server-fn/.wrangler/tmp/pages-liyiqW/chunks/runtime.mjs:455:106760)
      at Object.beforeLoad
  (file:///home/nize/dev/web/tss-cloudflare-server-fn/.wrangler/tmp/pages-liyiqW/chunks/runtime.mjs:455:108503)
      at null.<anonymous>
  (file:///home/nize/dev/web/tss-cloudflare-server-fn/.wrangler/tmp/pages-liyiqW/chunks/runtime.mjs:1:148928)
      at null.<anonymous>
  (file:///home/nize/dev/web/tss-cloudflare-server-fn/.wrangler/tmp/pages-liyiqW/chunks/runtime.mjs:1:152252)
      at new Promise (<anonymous>) {
    routerCode: 'BEFORE_LOAD'
  }

Your Example Website or App

https://github.com/dotnize/tss-cloudflare-server-fn

Steps to Reproduce the Bug or Issue

or stackblitz: https://stackblitz.com/~/github.com/dotnize/tss-cloudflare-server-fn

  1. pnpm install
  2. pnpm build
  3. pnpm preview via wrangler

The app doesn't work at all due to a server fn call in __root.tsx's beforeLoad. Server fn calls from other routes/loaders (like in index.tsx) also don't work.

Expected behavior

Server functions should work as expected, as it already works on local vinxi dev, node-server builds, or Vercel deployments

repo deployment on vercel, working as expected:
https://tss-cloudflare-server-fn.vercel.app/

Screenshots or Videos

No response

Platform

  • OS: Linux
  • Browser: Chrome
  • Version: 130

Additional context

No response

@vseventer
Copy link

vseventer commented Oct 28, 2024

Having the same issue - one thing (possibly related) I have noted is that even the samples I checked on the website are broken with the same error, for example https://tanstack.com/router/latest/docs/framework/react/examples/start-basic-react-query)

Image

@xstevenyung
Copy link
Contributor

i had the same error but in a different use.

i was calling a server function on form submit. while everything work locally, i had the same Context is not available once deployed on cloudflare but using json actually fix it for me in this specific use-case

import { createServerFn, json } from "@tanstack/start";

const action = createServerFn("POST", async () => {
  // this doesn't work on cloudflare but work locally
  // return { msg: 'hello' };
  // this works on cloudflare
  return json({ msg: 'hello' });
});

// ...

function Page() {
  return (
    <form
      onSubmit={async (event) => {
        event.preventDefault();
        event.stopPropagation();
        await action();
      }}
    >
       {/* ... */}
    </form>
  )
}

no clue if this is related in some way

@xstevenyung
Copy link
Contributor

after some digging, seems like the issue might come from nitro

related issue: nitrojs/nitro#1943

@Talent30
Copy link

Talent30 commented Oct 29, 2024

I got it working, this is my config

import type { App } from "vinxi";

import { defineConfig } from "@tanstack/start/config";

const tanstackApp = defineConfig({
  server: {
    preset: "cloudflare-pages",
    rollupConfig: {
      external: ["node:async_hooks"],
    },
  },
});

const routers = tanstackApp.config.routers.map((r) => {
  return {
    ...r,
    middleware: r.target === "server" ? "./app/middleware.tsx" : undefined,
  };
});

const app: App = {
  ...tanstackApp,
  config: {
    ...tanstackApp.config,
    routers: routers,
  },
};

export default app;

@vseventer
Copy link

vseventer commented Oct 30, 2024

The rollupConfig.external addition posted by @Talent30 seems to work for me too. I did have to create a wrangler.toml to set compatibility_flags = [ "nodejs_compat" ] to get it to build.

@Talent30
Copy link

The rollupConfig.external addition posted by @Talent30 seems to work for me too. I did have to create a wrangler.toml to set compatibility_flags = [ "nodejs_compat" ] to get it to build.

Yes you need that. Nitro needs async context

@Talent30
Copy link

Talent30 commented Oct 30, 2024

If it is working for everyone we might need to submit a PR to update the deployment doc.

@SeanCassiere SeanCassiere added the start Everything about TanStack Start label Nov 1, 2024
@SeanCassiere
Copy link
Member

Just so I'm up to date on this thread, we are waiting on nitrojs/nitro#1943 to be resolved, so that it may be updated in Vinxi, correct?

@Talent30
Copy link

Talent30 commented Nov 1, 2024

Just so I'm up to date on this thread, we are waiting on unjs/nitro#1943 to be resolved, so that it may be updated in Vinxi, correct?

Hi, @SeanCassiere.

I don't think this will be fixed by Nitro in the near future since no one has had looked at the issue for a year now.

For now, we have to set compatibility_flags = [ "nodejs_compat" ] and rollupConfig: { external: ["node:async_hooks"], } as the configuration I posted previously.

Perhaps we should update the documentation to tell people to enable compatibility_flags = [ "nodejs_compat" ] and update the cloudflare-pages default to include rollupConfig.external.

What are your thoughts?

@aretrace
Copy link

aretrace commented Nov 1, 2024

@SeanCassiere @Talent30
I'm interested in deploying to Cloudflare, definitely would want this in the docs.

@schiller-manuel
Copy link
Contributor

just create PRs for the docs then?

@Talent30
Copy link

Talent30 commented Nov 3, 2024

just create PRs for the docs then?

Hi there,

Would you like me to put the rollupConfig.external setting in for cloudflare-pages preset as well?

@xstevenyung
Copy link
Contributor

xstevenyung commented Nov 13, 2024

using the rollupConfig.external doesn't seems to fix all the issues.

i also stumble upon the same error when using getWebRequest in a server fn. it seems like the issue come from vinxi (or maybe nitro?) and that the folks at solid-start already had the same issue a while back.

Just so I'm up to date on this thread, we are waiting on nitrojs/nitro#1943 to be resolved, so that it may be updated in Vinxi, correct?

while we are waiting for nitro to integrate the support on the cloudflare preset, it's possible today to pass manually the unenv preset to fix this issue like so:

import { defineConfig } from "@tanstack/start/config";
import tsConfigPaths from "vite-tsconfig-paths";
import { cloudflare } from "unenv";

export default defineConfig({
  server: {
    preset: "cloudflare-pages",
    unenv: cloudflare,
  },
  vite: {
    plugins: [tsConfigPaths()],
  },
});

we still need the wrangler.toml node_compat flag but this seems to solve the issue

related issue: solidjs/solid-start#1527

@josippapez
Copy link

@SeanCassiere I've encountered the exact same error with the firebase deployment but i was unable to fix it or find a workaround. Should this issue be reopened?

example of my app.config.ts

export default defineConfig({
  server: {
    preset: 'firebase',
    firebase: {
      serverFunctionName: 'serverBriskfitStatic',
      gen: 2,
      nodeVersion: '22',
      httpsOptions: {
        region: 'europe-west3',
        maxInstances: 5,
      },
    },
    alias: {
      '/fonts': '/public/fonts',
    },
    esbuild: {
      options: {
        sourceMap: true,
        target: 'es2022',
      },
    },
  },
  vite: {
    resolve: {
      alias: {
        '/fonts': '/public/fonts',
      },
    },
    plugins: [
      tsConfigPaths({
        projects: ['./tsconfig.json'],
      }),
      // visualizer({ open: process.env.NODE_ENV === "production" }),
    ],
    build: {
      minify: true,
      rollupOptions: {
        treeshake: true,
      },
    },
  },
});

and this is the example of my serverFn:

export const setLoginCookie = createServerFn({
  method: 'POST',
})
  .validator((data: { token: string }) => data)
  .handler(({ data }) => {
    const event = getEvent();

    const { token } = data;
    setCookie(event, USER_AUTH_KEY, token, {
      httpOnly: true,
      sameSite: 'strict',
      secure: true,
      expires: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days
    });
  });

@SeanCassiere
Copy link
Member

SeanCassiere commented Dec 21, 2024

Should this issue be reopened?

@josippapez sInce it's for a different deployment target, it'd be best if it has its own separate issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
start Everything about TanStack Start
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants