Skip to content

Static prerendering/ISR cannot work with Cloudflare as workers run in front of CDN, not behind it - incorrectly documented as if it does #7527

@rikbrown

Description

@rikbrown

Which project does this relate to?

Start

Describe the bug

I followed this guide: https://tanstack.com/start/latest/docs/framework/react/guide/isr#how-isr-works-in-tanstack-start

i.e.:

  1. I setup pre-rendering for my routes
  2. I setup my routes to return both Cache-Control and CDN-Cache-Control for SWR. e.g. 'cache-control': 'public, max-age=0, s-maxage=15' to cache on CDN for 15s.

I am deploying to a Cloudflare worker using wrangler per the hosting guide on the site.

There are two broken issues:

  1. With pre-rendering specified, Cloudflare seems to explicitly serve the plain HTML asset generated by Vite. It is sent with cf-cache-status: HIT and Cache-Control: public, max-age=0, must-revalidate (not my settings). Furthermore if I hit a subpage like /about CF serves a 307 to /about/ (with the slash) - presumably a static index.html normalisation.
  2. With pre-rendering off (but leaving the ISR headers in), Cloudflare does not respect my Cache-Control headers and does not CDN-cache. I tested by returning the currnet date via the loader - it's fresh on every request.

My LLM is telling me CF never caches worker responses and is getting me to write a custom server entry point that uses caches.default to do the caching by hand. This didn't feel right based on how the guide seems to suggest this works out of the box. And indeed, after reading through the CF Cache documentation, workers run in-front of all caching. So I don't follow how setting these cache headers could ever have Cloudflare's CDN cache cache them without a separate layer calling the cache API directly.

I tested using the start-basic-cloudflare repo, modified it to return the current timestamp from a loader and to add headers - it is not being cached. CF-Cache-Status not being set either.

However the docs seem to suggest this would be set ("monitor cache hit rates" middleware) and provide examples of calling CF's API to invalidate individual pages...

Complete minimal reproducer

https://test-tanstack-start-app.isoaccounts.workers.dev/

Steps to Reproduce the Bug

Refresh the page. Observe it's not being cached. Trust me that it's setting headers exactly per the TSS docs.

Expected behavior

Well - the docs would have it that CF's CDN would pick up the cache headers and cache the document. However, per CF's own documentation, Workers run IN FRONT of their CDN so this is impossible. You would need to directly call their cache APIs.

Screenshots or Videos

No response

Platform

relevant packages:
"react": "~19.2.6",
"react-dom": "~19.2.6",
"@tanstack/react-router": "^1.170.8",
"@tanstack/react-start": "^1.168.14",

running on CF Workers with latest wrangler and the exact setup from the example repo

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions