N
Nuxt5mo ago
_bits

cannot invalidate cached data using getCachedData

Hey everyone! I'm having an issue with useLazyFetch caching behavior in Nuxt 3 and could use some help figuring out the best solution. Problem Description I have a page component using useLazyFetch with a specific cache key:
const {data, refresh, status} = useLazyFetch<Inbox>('/api/inbox', {
key: CacheKeys.inbox,
})
const {data, refresh, status} = useLazyFetch<Inbox>('/api/inbox', {
key: CacheKeys.inbox,
})
The page has functionality that updates the data, and I use refreshNuxtData(CacheKeys.inbox) to refresh the cache. This works perfectly while I stay on the same page. However, here's where it breaks: 1. User views page with data 2. User triggers an update (data gets modified in backend) 3. I call refreshNuxtData(CacheKeys.inbox) - works correctly, shows fresh data 4. User navigates to different page 5. User navigates back to original page Problem: The page shows the old data from before the update happened, not the refreshed data It seems like when I navigate away and come back, Nuxt is serving the cached data from before the refresh occurred, completely ignoring that refreshNuxtData was called. My Questions What's the recommended way to handle this scenario? Should the cache persist through navigation changes even after explicit refresh calls?
18 Replies
kapa.ai
kapa.ai5mo ago
Hi @_bits. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Your observation matches known issues and recent changes in Nuxt 3’s data caching system. Here’s what’s happening and what you can do: Why is this happening? Nuxt 3 introduced a "purge cached data" mechanism to prevent memory leaks: when you navigate away from a page, the cached data for that page (tied to your key) is purged unless you disable this feature. When you return, the cache is empty, and depending on the order of composable calls (especially if you use useNuxtData before useLazyFetch), the fetch composable may not re-fetch as expected, or may serve stale data due to how dependencies are tracked and cache is managed. This is a known issue in Nuxt 3.17.x and related to the new purge logic (see issue discussion). Should the cache persist after explicit refresh calls? By default, Nuxt’s cache is designed to be purged when the last component using the data is unmounted (i.e., when you navigate away). Explicitly calling refreshNuxtData only refreshes the data for the current session; it does not persist the refreshed data across navigation if the cache is purged on unmount. So, yes, the cache is cleared on navigation unless you change the default behavior. Recommended solutions 1. Disable cache purging (experimental):
You can disable the automatic purging of cached data by setting the following in your nuxt.config.ts:
export default defineNuxtConfig({
experimental: {
purgeCachedData: false
}
})
export default defineNuxtConfig({
experimental: {
purgeCachedData: false
}
})
This will keep your cache alive across navigation, so after calling refreshNuxtData, the updated data will persist when you return to the page.
See: purgeCachedData docs 2. Order of composable calls:
If you use useNuxtData and useLazyFetch with the same key, make sure to call useLazyFetch before useNuxtData. Otherwise, the cache may not be properly re-initialized on navigation (see issue). 3. Use unique keys or force re-fetch:
As a workaround, you can use a unique key (e.g., based on a timestamp or route param) to force Nuxt to treat each visit as a new fetch, but this may defeat the purpose of caching. Summary - By default, Nuxt purges cached data on navigation, so explicit refreshes do not persist across page changes. - To persist refreshed data, set purgeCachedData: false in your config. - Be mindful of the order in which you call composables with shared keys. If you need more granular control, consider using the experimental options or tracking cache state manually, but be aware of the trade-offs regarding memory usage and reactivity. Related Nuxt docs: purgeCachedData
Issue: cache purging and navigation ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5mo ago
<@996332881821577286> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
_bits
_bitsOP5mo ago
@kapa.ai Okay, i now figured out that this error only occurs when i use useLazyFetch inside a custom composable Hello @kapa.ai can u answer my question above?
kapa.ai
kapa.ai5mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You're encountering a known behavior in Nuxt 3's data caching system. By default, Nuxt will purge cached data from useAsyncData and useFetch (including useLazyFetch) when you navigate away from a page, unless you explicitly disable this feature. This means that even if you call refreshNuxtData to refresh the cache while on the page, navigating away and back will cause Nuxt to serve the original cached data (or re-fetch, depending on configuration), not the updated data you just refreshed. Should the cache persist through navigation changes after explicit refresh calls?
By default, no—the cache is cleared on navigation to prevent memory leaks and ensure fresh data is loaded when needed. This is controlled by the experimental.purgeCachedData option, which is true by default. If you want the cache to persist across navigation (so that your explicit refresh is respected even after leaving and returning to the page), you can disable this behavior:
// nuxt.config.ts
export default defineNuxtConfig({
experimental: {
purgeCachedData: false
}
})
// nuxt.config.ts
export default defineNuxtConfig({
experimental: {
purgeCachedData: false
}
})
See: Nuxt purgeCachedData docs Summary of recommendations: - If you want refreshed data to persist across navigation, set purgeCachedData: false in your config. - Otherwise, the default behavior is to clear the cache on navigation, so explicit refreshes only affect the current session on the page. This behavior and workaround are confirmed in the Nuxt documentation and related GitHub issues and discussions Nuxt purgeCachedData docs | Experimental features guide | GitHub issue: cache purge on navigation. If you need more granular cache control, you may need to manage cache state manually or adjust your data fetching strategy. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5mo ago
<@996332881821577286> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
_bits
_bitsOP5mo ago
@kapa.ai the purged data thing is not working when i use useLazyFetch inside a custom composable, do you know why?
kapa.ai
kapa.ai5mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the knowledge sources provided, there are known issues and caveats when using useFetch/useLazyFetch inside custom composables, especially regarding cache behavior and data purging: 1. Duplicate or Unexpected Requests:
Wrapping useFetch (and by extension, useLazyFetch) inside a custom composable can lead to unexpected behaviors, such as duplicate requests or cache not being invalidated as expected. This is because composables are not as isolated as you might expect—multiple components using the same composable can end up sharing the same data and cache key, leading to conflicts or stale data being served. This is discussed in this Stack Overflow post and a related Nuxt GitHub issue. 2. Cache Purging May Not Work as Expected:
When you use useLazyFetch inside a custom composable, Nuxt's internal tracking of dependencies and cache keys can get confused, especially if the composable is used in multiple places or if the key is not unique per usage. This can result in the cache not being purged as expected on navigation, or in data being shared across components unintentionally. The Nuxt team has acknowledged that wrapping fetch composables can cause such issues, and recommends caution (see issue). 3. Key Management is Critical:
If you use the same key for multiple calls (or across multiple components), Nuxt will share the cache and refs, which can lead to stale or unexpected data. If you want cache purging and reactivity to work as expected, ensure that each usage has a unique key, or avoid wrapping fetch composables in custom composables unless you fully control their usage and lifecycle Singleton Data Fetching Layer. Summary:
The purged data mechanism may not work as expected when using useLazyFetch inside a custom composable due to how Nuxt tracks and shares cache keys and dependencies. This can lead to stale data or cache not being invalidated on navigation. To avoid these issues, use unique keys for each usage, and be cautious about wrapping fetch composables in custom composables. If you need more predictable cache purging, consider using useLazyFetch directly in your components, or carefully manage keys and composable usage. If you need further details or a workaround, please provide a code example or clarify your use case. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5mo ago
<@996332881821577286> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
_bits
_bitsOP5mo ago
@kapa.ai So what would you advise us how do we fix the problem? DOnt use lazy fetch inside custom composbales?
kapa.ai
kapa.ai5mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the knowledge sources, wrapping useFetch or useLazyFetch inside custom composables can indeed lead to unexpected cache and reactivity issues in Nuxt 3. This is because composables are not as isolated as you might expect—multiple components using the same composable can end up sharing the same data and cache key, which can cause stale data or prevent cache purging from working as intended. This behavior is discussed in detail in a Stack Overflow post, where it was found that wrapping fetch composables inside custom composables led to bugs and unexpected data sharing between components. The recommended practice is to use fetch composables like useFetch and useLazyFetch directly inside your component's setup function, plugins, or route middleware, rather than wrapping them in custom composables Why is Vue's Composable not Isolated?. Advice:
- Avoid using useLazyFetch (or useFetch) inside custom composables if you want predictable cache purging and reactivity. - Use these fetch composables directly in your page or component setup functions. This approach aligns with Nuxt's intended usage and helps prevent the cache and reactivity issues you've encountered. If you need to share data or logic, consider separating the data fetching (using useFetch/useLazyFetch in the component) from the logic (which can be placed in a composable). If you have a specific use case that requires a custom composable, ensure that you manage cache keys carefully and understand the implications, but the safest and most predictable approach is to use fetch composables directly in your components. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5mo ago
<@996332881821577286> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
johntanzer
johntanzer5mo ago
Pretty sure this was fixed in last patch. Why version u using?
_bits
_bitsOP5mo ago
thought so, but we used latest version. The problem occurs when you use useFetch inside a custom composable.
johntanzer
johntanzer5mo ago
Cc @danielroe any clues?
danielroe
danielroe5mo ago
this might be the same issue as https://github.com/nuxt/nuxt/pull/32096. do you have a minimal reproduction?
_bits
_bitsOP5mo ago
So we had a composable lets call it. const {data} = useInbox() we used useInbox() on serveral places pages/index.vue pages/[..slug].vue and maybe thats the issue template/default.vue so when we did a refresh on index.vue, the data was correct, when we cliked on slugs page and back, maybe we got the data from default.vue? We fixed it now by fetching inside the default.vue and only get the data by useNuxtData('inbox'), inside index.vue and [slug].vue but somehow feels not right.
johntanzer
johntanzer5mo ago
Can you reproduce using https://nuxt.new
_bits
_bitsOP5mo ago
Will try it tomorrow.

Did you find this page helpful?