Cache dynamic asset with next js but allow revalidate

using next js with netlify, wondering how I can use next.js API call with edge / cdn cache.
the use case is that I’m generating a js static file and want it to be cached for several hours, in case any OTHER users will land on the same API call.
eg. http://my-site.com/api/js/123123.js, should be generated on demand. but cached on the browser AND the cdn/edge (in this case, 123123 is a random id that can be changed)
while still having the ability to revalidate on demand (eg. when the js output should be changed)

my naive approach was to set “stale-while-revalidate” but that’s not going to work. i don’t even see that being propagated when accessing that resource…

// request to api/js/[id]
const RenderJs = async (req: NextApiRequest, res: NextApiResponse) => {
  const code = await generateCode(req.query.id);

  res.setHeader(
    'Cache-Control',
    `public, s-maxage=${fresh}, stale-while-revalidate=${stale}`
  );
  res.send(code)
}

it seems like this is what you get out of the box with Vercel.
reading here Caching responses from Serverless Functions – Vercel Docs
just setting the Cache-Control header is enough. even in API routes

export default function handler(req, res) {
  res.setHeader('Cache-Control', 's-maxage=86400');
  res.status(200).json({ name: 'John Doe' });
}

Netlify provides On Demand Builders:

which can be used to create any custom output that can be cached for time decided by you.

In terms of Next.js, I believe you can use ISR to achieve the same functionality, however I don’t know if you can produce JavaScript assets with ISR. If you can, then you should be able to use native Next.js functionality to achieve your goal.

thanks, but it seems that those solutions would not resolve my issue

  1. not apparent way to render assets with ISR, the only output I can see is HTML
  2. on-demand builder seem cool, but the don’t support invalidation (or at least as I can see)

my current workaround is using vercel. they don’t support reading file system as easily as in netlify. but the headers are being read, and I can invalidate the cache when I need to

Hey there, @AlonMiz :wave:

Thanks for following up! Sorry to hear that these suggestions don’t work in your situation. I will loop in our team that works on this, however I am not sure if they will have additional suggestions at this time.

Hey @AlonMiz,

Both of your statements are incorrect.

You could render a JavaScript file and cache it using On Demand Builders.

On Demand Builders also support revalidation based on time. They don’t (yet) support revalidation on demand (refresh hooks in terms of Next.js), but they do support revalidation after a specified time period.

Revalidation on demand is in works too.

@hrishikesh

  1. On-Demand Builders are not under next js, they are a proprietary solution. so my statement is correct regarding that. I understand that on-demand builders are able to build any asset, including js. but without on-demand revalidation, it doesn’t satisfy my needs.
  2. revalidation with on-demand only works with a timeout. not on-demand invalidation. which is what I need.,

on-demand revalidation:

Hello @AlonMiz :wave:

Thanks for that feedback. Our Support team has reviewed and what you are trying to do does not currently seem possible with next.js on any platform, including netlify. Hopefully you can find another platform or framework that fits all of your needs!

1 Like