remix
remix copied to clipboard
[Cloudflare Pages] Static assets in public directory are served via functions
What version of Remix are you using?
v1.7.5
Steps to Reproduce
- Create a new Cloudflare project
- Drop a static asset in the public directory (favicon, images, whatever)
- Deploy the site
- Notice that any request to static assets responds with the cache header
cf-cache-statusofEXPIRED. All assets inbuildrespond with acf-cache-statusofHIT.
This impacts a couple of things:
- Billing (static assets are free)
- The response back to the user is not cached for as long as a static asset.
Expected Behavior
All assets should be served statically (not via a function).
Actual Behavior
All assets in public (not in public/build) are served via a function.
For a quick win in my own project, I have modified my _routes.json (inside public) to exclude certain extensions, which seems to be working for now.
Example:
{
"version": 1,
"include": [
"/*"
],
"exclude": [
"/build/*",
"/*.png",
"/*.svg",
"/*.webp",
"/*.ico"
]
}
I tried to see if I could fix this and submit a PR, but I am not sure there is a way to resolve this. Attempting to "exclude": "/*" doesn't run functions at all.
Happy to adjust the readme of the Cloudflare template or if someone else can think of any solutions, I don't mind implementing them.
If you place images under a subfolder in public, you can then add this to the include without relying on extensions which seems a bit flakey to me.
This won't catch assets that you want to serve at the root of course, like favicons.
@tom-sherman was just taking another look at this and while your idea works, your favicon will still be loaded via the function.
You could probably use a redirect for those.
The problem for me isn't serving the asset via the worker, but it counts towards your bill and it's not cached the same.
Edit: Ah wait I think you meant https://developers.cloudflare.com/pages/platform/redirects/, which would make sense.
Things outside the public/build directory aren't really our responsibility. The CF Pages template gives you direct access to public/_routes.json and public/_headers which are the levers you need to adjust caching behavior for anything else you might add to public. For us to assume caching behavior for any other random thing you drop into public would be assuming too much, and would inevitably lead to a conflict in the future when someone wants to disable that behavior.
Closing this as I don't think there is anything for us to do here.
@inssein following up in case it's helpful since I also ran into this. I'm surprised that this applies to static assets needed for the app as well, not just files you add to public. I totally get the argument that a rule for anything that ends up in /assets could be troublesome, but this default behavior is not great for prod, maybe a doc would clear this up on the remix side
Here's what I did since I don't have any other assets I care about with my app.
in public/_headers
/assets/*
Cache-Control: public, max-age=31536000, immutable
Those are the same value that remix-serve uses when i start a remix app in prod mode locally, and that file gets moved over during the build step