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

Re: @remix-run/serve sets high max-age and immutable cache header on everything #9353

Open
kenteramin opened this issue May 1, 2024 · 6 comments · May be fixed by #10441
Open

Re: @remix-run/serve sets high max-age and immutable cache header on everything #9353

kenteramin opened this issue May 1, 2024 · 6 comments · May be fixed by #10441

Comments

@kenteramin
Copy link

Reproduction

  1. Create a remix app
  2. Run build then start
  3. Open the page
  4. Check the headers on the /favicon.ico request

The favicon from /public comes with Cache-Control: public, max-age=31536000, immutable

System Info

remix 2.9.1

Used Package Manager

npm

Expected Behavior

The server config from
https://github.com/remix-run/remix/blob/main/packages/remix-serve/cli.ts
says app.use(express.static("public", { maxAge: "1h" }));.
So it is expected to have maxAge=1h

Actual Behavior

We actually get an immutable maxAge=1y

@kenteramin
Copy link
Author

There was already a bug of the same nature
#903

@kenteramin
Copy link
Author

So, actually the problem is that here

app.use(
  build.publicPath,
  express.static(build.assetsBuildDirectory, {
    immutable: true,
    maxAge: "1y",
  })
);
app.use(express.static("public", { maxAge: "1h" }));

build.assetsBuildDirectory is just build/client, so it handles all the requests to the public folder.

The config should actually be something like this

app.use(
  build.publicPath,
  express.static(build.assetsBuildDirectory + "/assets", {
    immutable: true,
    maxAge: "1y",
  })
);
app.use(express.static(build.assetsBuildDirectory, { maxAge: "1h" }));

@kenteramin kenteramin changed the title Re: @remix-run/serve sets high max-age and immutable cache header on everything Re: @remix-run/serve sets high max-age and immutable cache header on everything May 1, 2024
@istarkov
Copy link

The main problem is that these headers are also sent on a 404 error.
A 404 on static files is not uncommon during deployment, for example on Vercel. And a cached 404 makes it impossible to fully use the site.

@remorses
Copy link

remorses commented Oct 5, 2024

This issue seems to be fixed in the react-router codebase but not Remix
https://github.com/remix-run/react-router/blob/bc1c1c8ef87b7bf97f1f168604b89a5da61939da/packages/react-router-serve/cli.ts#L81

@bhouston
Copy link

This is a pretty serious bug. It just resulted in a cached forever file on 10,000 visitors to my website that now I have to rename in order to update, but I can not easily rename it because of the nature of it.

I run https://web3dsurvey.com and I recently moved to Remix and the way you embed this tracker is now "public, max-age=31536000, immutable" on 10,000 visitors:

https://web3dsurvey.com/collector-iframe.html (more secure method)
https://web3dsurvey.com/collector.js (old method)

I tried replacing the files in /public with custom routes that force the headers, e.g.:

import { LoaderFunctionArgs } from '@remix-run/node';
import fs from 'fs';
import path from 'path';

const filePath = path.join(process.cwd(), 'content', 'collector.js');
const fileContent = fs.readFileSync(filePath, 'utf-8');
const fileLength = Buffer.byteLength(fileContent);

export async function loader({ request, params }: LoaderFunctionArgs) {
  return new Response(fileContent, {
    headers: {
      'Content-Type': 'application/javascript',
      'Cache-Control': 'max-age=300',
      'Content-Length': fileLength.toString()
    }
  });
}

Strangely it worked for collector-iframe.html, but not for collector.js.

That is pretty inconvenient for me. :/

@bhouston
Copy link

I've moved away from remix:server and adopted the Fastify integration and now it works properly:

https://github.com/mcansh/remix-fastify

/assets is immutable, cached forever because it has unique URLs.

/public is no-cache, but it will serve up 304 unmodified to save bandwidth.

Those are good defaults.

@remorses remorses linked a pull request Jan 28, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants