Nuxt 3 How to add Cache Control to generated static files
Asked Answered
L

5

6

I am creating SSR project with Nuxt 3. I am thinking to add Cache-Control Header to generated static files in .output/_nuxt directory.

I tried below code server/middleware/cache-control.ts

export default defineEventHandler((event) => {
  let res = event.res
  const year = 31536000
  const tenmin = 600
  const url = event.req.url
  const maxage = url.match(/(.+)\.(jpg|jpeg|gif|css|png|js|ico|svg|mjs)/) ? year : tenmin
  res.setHeader('Cache-Control', `max-age=${maxage} s-maxage=${maxage}`);
})

But, it does not work.

enter image description here

How to add Cache-Control to the generated static files?

Lepley answered 14/7, 2022 at 8:0 Comment(6)
Files don't respond to request. Server has to set headers.Bedell
console.log tells that network does not go through Nuxt3 server. I think I need to configure Vite server.Lepley
I add below code to nuxt.config.js. But still does not wok... ``` js export default defineNuxtConfig({ vite: { server: { headers: { "Cache-Control": "max-age=11111, s-maxage=11111" } } } }) ```Lepley
Nuxt 3 uses Nitro server by default. Where do you host your application ? Universal app can get just once files from server and then get others from other static files host. If it does like that, you have to set headers in both server and host server.Bedell
I was miss understanding what default server is... I have to add some settings to Nitro. I am currently testing with in Docker. I do not need to set host server headers for now.Lepley
It's experimental but you could try the new Route Rules: v3.nuxtjs.org/guide/concepts/rendering#route-rules but instead if you host you App on Vercel you can do it in the vercel.config file: vercel.com/guides/… I guess Netlify has something similar.Howenstein
L
14

I figure out by myself. Adding bellow code to nuxt.config.js will append cache-control to your static files. Thank you for your support!

export default defineNuxtConfig({
  nitro: {
    routeRules: {
      "/img/**": { headers: { 'cache-control': `public,max-age=${year},s-maxage=${year}` } },
      "/_nuxt/**": { headers: { 'cache-control': `public,max-age=${year},s-maxage=${year}` } },
    }
  }
})
Lepley answered 23/3, 2023 at 2:19 Comment(3)
For whom are struggling in dev mode nuxt: I was able to check cache header when I build nuxt using: npm run build export NUXT_API_HOST='[YOUR SERVER URL]' export PORT='8080' node .output/server/index.mjsGeisler
Hey @Geisler I tried this approach and it didn't work. Infact I get no cache-control header at all in my network tab after running build. What could be the problem?Accouchement
Edit. I use nuxt image which generates the images using ipx. So I had to cache the ipx folder too, then run on build test the network tab give it some time and it shows the cache correctly. '/_ipx/**': { headers: { 'cache-control': public,max-age=31536000,s-maxage=31536000` } },`Accouchement
H
5

For Nuxt3 I have used this as server middleware server/middleware/cache-control.js

export default defineEventHandler((event) => {
  if (process.env.NODE_ENV == "production") {
    const url = event.node.req.url;
    const maxage = url.match(/(.+)\.(jpg|jpeg|gif|png|ico|svg|css|js|mjs)/)
      ? 60 * 60 * 12 * 30
      : 60 * 60;
    appendHeader(
      event,
      "Cache-Control",
      `max-age=${maxage} s-maxage=${maxage}`
    );
  } else {
    appendHeader(event, "Cache-Control", `max-age=${60} s-maxage=${60}`);
  }
});
Haffner answered 16/1, 2023 at 6:23 Comment(1)
I was not able to make it works, maybe something change recently ?Holcombe
D
3

Nitro server has a setting called publicAssets, you can configure cache duration there, I have configured it for my video/image files like this

export default defineNuxtConfig({
    ....
    nitro: {
        publicAssets: [
            {
                baseURL: "video",
                dir: "public/video",
                maxAge: 60 * 60 * 24 * 365,
            },
            {
                baseURL: "images",
                dir: "public/images",
                maxAge: 60 * 60 * 24 * 365,
            },
            {
                baseURL: "animations",
                dir: "public/animations",
                maxAge: 60 * 60 * 24 * 365,
            },
        ],
        compressPublicAssets: {
            brotli: true,
            gzip: true,
        },
    },
    ....
})

baseURL is the url from where the files are served (files from public folder are served from the root path of domain), dir is the actual location of files, maxAge is caching time. Currently there is a bug and because of it nuxt will return 404 error for assets configured with publicAssets option, and there is PR waiting to be merged to nuxt, which fixes this issue (see PR and discussion here GitHub issue), you can add nitro config option under $production key in nuxt.config.ts, then this config will work only when building for production.

Disquisition answered 22/5 at 21:53 Comment(0)
S
0

Try to use the h3 function:

appendHeader(res, name, value)

Nuxt 3 works based on: https://github.com/unjs/h3

Simonnesimonpure answered 14/7, 2022 at 8:9 Comment(0)
B
0

Nuxt 3

Using Nuxt 3 hook in plugins path plugins/cache.server.ts :

export default defineNuxtPlugin((nuxtApp) => {
    nuxtApp.hook('app:rendered', ctx => {
        ctx.ssrContext?.event.node.res.setHeader('cache-control', `max-age=${60*60*24*365}`)
    })
})

Using Nitro hook in server path server/plugins/cache.ts :

import { RenderResponse } from "nitropack"

export default defineNitroPlugin((nitroApp) => {
    nitroApp.hooks.hook('render:response', (res: RenderResponse) => {
        res.headers['cache-control'] = `max-age=${60*60*24*365}`
    })
})
Bedell answered 14/7, 2022 at 8:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.