Nuxt 3 caching with ISR/SWR does not work as expected

Hi,

I have a minimal Nuxt 3 app with different pages set up to use different rendering modes.
https://extraordinary-zuccutto-58a082.netlify.app

nuxt.config is as following:

export default defineNuxtConfig({

ssr: true,

routeRules: {

"/isr_ttl": { isr: 60 },

"/isr_no_ttl": { isr: true },

"/swr_ttl": { swr: 60 },

"/swr_no_ttl": { swr: true },

},

});

I use 2 timestamps to check whether caching works as expected: one comes from API response, another one is rendered in browser.

I tried deploying this app with different nitro presets or without a preset at all and all of the deploys produce unexpected behaviour with at least some rendering modes. Please see the summary below:

NITRO_PRESET = netlify_builder

SSR: cached for at least 2 mins

SWR without TTL: cached permanently

SWR with TTL of 60 seconds: cached permanently

ISR without TTL: cached permanently

ISR with TTL of 60 seconds: cached permanently

Unexpected behaviour:

SSR (expected no caching),

SWR without TTL (expected to be cached until response changes),

SWR with TTL of 60 seconds (expected to be cached for 60 seconds),

ISR with TTL of 60 seconds (expected to be cached for 60 seconds),

NITRO_PRESET = netlify_edge

SSR: no caching

SWR without TTL: cached until response changes

SWR with TTL of 60 seconds: cached for 60 seconds

ISR without TTL: no caching

ISR with TTL of 60 seconds: no caching

Unexpected behaviour:

ISR without TTL (expected to be cached permanently),

ISR with TTL of 60 seconds (expected to be cached for 60 seconds),

NITRO_PRESET = netlify

SSR: no caching

SWR without TTL: cached permanently

SWR with TTL of 60 seconds: cached permanently

ISR without TTL: cached permanently

ISR with TTL of 60 seconds: cached permanently

Unexpected behaviour:

SWR without TTL (expected to be cached until response changes),

SWR with TTL of 60 seconds (expected to be cached for 60 seconds),

ISR with TTL of 60 seconds (expected to be cached for 60 seconds),

no NITRO_PRESET

SSR: no caching

SWR without TTL: cached permanently

SWR with TTL of 60 seconds: cached permanently

ISR without TTL: cached permanently

ISR with TTL of 60 seconds: cached for at least 2 mins

Unexpected behaviour:

SWR without TTL (expected to be cached until response changes),

SWR with TTL of 60 seconds (expected to be cached for 60 seconds),

ISR with TTL of 60 seconds (expected to be cached for 60 seconds),

Can someone please advise what should be the proper preset to use for these rendering modes and in general, how to fix the issue to make sure that they work as expected?

Unfortunately, this is a Nuxt issue at this point. In the past, Netlify didn’t support SWR cache headers and we used On Demand Builders instead to provide ISR for Next and Nuxt. However, we now support SWR and ODB should not be used anymore. Thus, the netlify_builder preset is obselete and should not be used anymore. In the current approach, you either get all as the ODB or all as standard Handler (as Nuxt doesn’t generate different Functions). Nuxt would have to make sure that its presets are now following the Netlify’s cache control headers (which should work if they’re following the standard).

Hi,

I will open an issue for Nuxt. Can you please clarify what preset do we expect ISR and SWR to work with if Nuxt fixes the issue? I understand from your response that netlify_builder preset shouldn’t be used anymore. So do we expect it to work without presets? Or with netlify_edge preset?

It should work with either netlify or netlify_edge. netlify_builder should not be used unless there’s a very strong reason to use it. I don’t know how Nuxt generates the function, but as far as I’m aware, it’s not possible to have the same function run as a builder as well as a normal function.

Going forward, ISR and SWR is just a matter of setting correct response headers: Caching | Netlify Docs. So as long as the correct headers are set, it should work regardless of the preset.