I create a JavaScript object that matches the interface of my request library, axios in my case. The cache is basically a middleware to it created by function wrapping. Kind of like how memoize works but with a bit of extra smarts.
I have my own .get(), .post(), .delete() and .put() functions. So when a .get() is called, it's a cache check and return the stored value. If not found call axios.get() with the passed in args and store in cache before returning.
The post() function clears the cache then passes through the arguments to axios.post().
Etc.
The 5 minutes is accomplished with an entry on the event loop to remove said item.
It's only like 30 lines of code.
The real wins for this is in basic navigation. Clicking around site exploring, makes it snappy. Another advantage is lowering the total request count a bit to the backend, lowering the cloud bill.
If your baseline is so a new fetch every single time anyway, it doesn’t take much to achieve some pretty impressive wins.