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

Set proper Cache-Control max-age for static assets #1791

Closed
dbo opened this issue Apr 24, 2017 · 20 comments · May be fixed by Qdigital/next.js#25
Closed

Set proper Cache-Control max-age for static assets #1791

dbo opened this issue Apr 24, 2017 · 20 comments · May be fixed by Qdigital/next.js#25

Comments

@dbo
Copy link
Contributor

dbo commented Apr 24, 2017

I am missing a proper max-age resp. Cache-Control header set for /static assets (serve defaults to set max-age to 0). I plan to invalidate/bust the browser cache using query parameters on these. Shouldn't static assets always be served with long max-age?

@sergiodxa
Copy link
Contributor

That idea is that you set a CDN, I think the Next static folder it's only for development usage.

@arunoda
Copy link
Contributor

arunoda commented May 2, 2017

@dbo since we don't hash static files, we are not possible to do that.
It's a pretty good idea to move your static content into a CDN or something similar and avoid /static as possible as you can.

We should improve this behavior in the future. But it's not happening anytime sooner.

@arunoda arunoda closed this as completed May 2, 2017
@dbo
Copy link
Contributor Author

dbo commented May 2, 2017

@arunoda So if it's generally discouraged to be used on zeit/now (other than during dev-time), I think it's worth to be stressed out in the README.

@myylow
Copy link

myylow commented Jun 17, 2017

I ran into this problem when using CloudFlare as a CDN. It takes the cache settings from the origin server (max-age=0), so all assets in /static/ are not cached despite being on the CDN. A next.js config setting would be nice as an improvement at some point, but a workaround if using Express as a server is pretty easy:

    server.use("/static", express.static(__dirname + "/static", {
        maxAge: "365d"
    }));

It needs to come before the next catch-all '*' route in your server.js to take effect.

@aseem2625
Copy link

@mike-low
You don't sent immutable ?

Mine is like

app.use(Express.static(path.join(appDir, '/dist/'), {
	setHeaders(res) {
		res.setHeader("Cache-Control", "public,max-age=31536000,immutable");
	}
}));

@sheerun
Copy link
Contributor

sheerun commented Dec 13, 2017

@sergiodxa Probably at least files from _next should get non-zero max age by default as they are in hashed folders.

@martpie
Copy link
Contributor

martpie commented Sep 14, 2018

since we don't hash static files, we are not possible to do that.

Any plan to change that one day? Having expire headers is quite common and a recommended practice

@bovas85

This comment has been minimized.

@timneutkens
Copy link
Member

@bovas85 I've hidden your comment as it's related to Nuxt.js, not Next.js.

@bovas85
Copy link

bovas85 commented Oct 29, 2018

Sorry! I read nuxt and commented 👎 my bad :)

@timneutkens
Copy link
Member

@bovas85 no worries at all 😄

@fabb
Copy link
Contributor

fabb commented Jan 29, 2019

i tried providing max-age like @mike-low and @aseem2625 suggested, but it did not change the cache header on my static resources. any suggestions? i also tried etag: false without any effect.

@geochanto
Copy link

geochanto commented Oct 4, 2019

server.use("/static", express.static(__dirname + "/static", {
maxAge: "365d"
}));

This works for /static folder, but not for /_next/static... I tried changing /static to /_next or /_next/static, but that did not work either.

I put this line right above this one, as suggested:

    server.get( '*', ( req, res ) => {
        return handle( req, res );
    } );

Response header cache-control max-age is still 0 for CSS files coming from /_next/static/css. Any tips?

@DaleOC
Copy link

DaleOC commented Oct 6, 2019

Same here.

I have the following, which is not working

 app.prepare().then(() => {
const server = express();


server.use('/images', express.static(path.join(__dirname, 'images'), {
    maxAge: dev ? '0' : '365d'
}));
server.use(compression());
server.use(bodyParser.json());

 server.get('*', (req, res) => {
        res.setHeader(
          "Cache-Control",
          "public, max-age=31536000, immutable",
        );

    return handle(req, res)
});

@HDv2b
Copy link

HDv2b commented Jun 18, 2020

@DaleOC @geochanto @fabb I had the same issue. Eventually got it:

(async () => {
  await app.prepare();
  const server = express();

  server.get("*.woff2?", (req, res) => {
    res.setHeader("Cache-Control", "public,max-age=31536000,immutable");
    return handle(req, res);
  });

  server.get("*", (req, res) => handle(req, res));

  await server.listen(port);
  console.log(`> Ready on http://localhost:${port}`); // eslint-disable-line no-console
})();

@jerrygreen
Copy link
Contributor

jerrygreen commented Dec 6, 2020

How about changing "Cache-Control" for production whereas no custom Node server is running? I.e. pure NextJS

UPD.

@FDiskas
Copy link

FDiskas commented Mar 24, 2021

So all of you suggest me move my robots.txt to cdn? How it is going to work? robots should be in the same domain. and what about other files like sitemap.xml?

It should be some how without custom server ability to add custom headers to static files.

So just letting others to know how it could be solved without custom server

  async headers() {
    return [
      {
        source: '/:all*(svg|jpg|png)',
        locale: false,
        headers: [
          {
            key: 'Cache-Control',
            value: 'public, max-age=9999999999, must-revalidate',
          }
        ],
      },
    ]
  },

@manziEric
Copy link

manziEric commented Jun 14, 2021

So all of you suggest me move my robots.txt to cdn? How it is going to work? robots should be in the same domain. and what about other files like sitemap.xml?

It should be some how without custom server ability to add custom headers to static files.

So just letting others to know how it could be solved without custom server

  async headers() {
    return [
      {
        source: '/:all*(svg|jpg|png)',
        locale: false,
        headers: [
          {
            key: 'Cache-Control',
            value: 'public, max-age=9999999999, must-revalidate',
          }
        ],
      },
    ]
  },

@FDiskas does this work and in what folder needs your code to be add ? next.config.js ?

@jerrygreen
Copy link
Contributor

jerrygreen commented Jun 14, 2021

@manziEric look: just add your robots.txt into root of your public folder, and it works, no problem.

BUT if you don’t like the Cache-Control header that is set by default, you may change it, according to documentation. More info in my previous answer with the links: #1791 (comment) (and yes, these changes are being done via next.config.js)

@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.