Skip to content

Tanstack-start on Cloudflare: ServerFn not working with API routes #4255

@cherishh

Description

@cherishh

Which project does this relate to?

Start

Describe the bug

This probably is an issue only related to Cloudflare Workers

  1. Create an API route /api/test;
  2. In page /count, do the following:
  • Create a route loader. In loader, call serverFn const count = await getCountServerFn().
  • In getCountServerFn, simply fetch(${BASE_URL}/api/test)
  1. In local development, everything is ok. Soft navigation to /count, or do a hard refresh on /count, I can see the count number being rendered.
  2. Build preview, everything is still ok.
  3. Deploy to Cloudflare Works as is.
  4. On production, no matter do a soft navigation to /count or do a hard refresh, it will resulting an error.

Additional information(all in production):
For simplicity I used page /count for illustration. Below you can see the actual page is /user/deprecated

  • Soft navigate to page:
Image Image
  • Hard refresh:
Image Image
  • API route itself seems fine. I can fetch this API point from frontend with no problem(fetch in useEffect).

Your Example Website or App

https://tanstack-start-on-workers-v0.tuxi.workers.dev/user/deprecated

Steps to Reproduce the Bug or Issue

As mentioned above

Expected behavior

I can call API routes just fine in serverFn on Cloudflare

Screenshots or Videos

As mentioned above

Platform

  • OS: Mac OS Sequoia 15.4.1
  • Browser: Chrome 137.0.7151.41
  • Version: 1.116.1

Additional context

/routes/user/deprecated.tsx

import { createFileRoute } from '@tanstack/react-router';
import { createServerFn } from '@tanstack/react-start';
import { BASE_URL } from '@/utils/base-url';

const getCountServerFn = createServerFn({ method: 'GET' }).handler(async () => {
  const res = await fetch(`${BASE_URL}/api/test`);
  if (!res.ok) {
    throw new Error(`api/test failed: ${res.status} ${res.statusText}`);
  }
  return res.json();
});

export const Route = createFileRoute('/user/deprecated')({
  loader: async ({ context }) => {
    const count = await getCountServerFn();

    return { count };
  },
  component: RouteComponent,
  errorComponent: () => <div>error</div>,
});

function RouteComponent() {
  const { count } = Route.useLoaderData();

  return (
    <div>
      <h2>
        <pre>{JSON.stringify(count, null, 2)}</pre>
      </h2>
    </div>
  );
}

/routes/api/test.ts

import { createAPIFileRoute } from '@tanstack/react-start/api';
import { Redis } from '@upstash/redis/cloudflare';

export const APIRoute = createAPIFileRoute('/api/test')({
  GET: async ({ request, params, env }) => {
    console.log('get test api', JSON.stringify(request));
    const redis = Redis.fromEnv(
      env ?? {
        UPSTASH_REDIS_REST_URL: 'xxx',
        UPSTASH_REDIS_REST_TOKEN: 'xxx',
      }
    );
    const count = await redis.incr('counter');
    return new Response(JSON.stringify({ count }));
  },
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions