useFetch with refresh() or useAsyncData with a custom key: which gives better control over stale cached data in Nuxt 3?
0 reputation · 18 Apr 2021, 07:07 UTC
0 reputation · 18 Apr 2021, 07:07 UTC
In a Nuxt 3 SSR application, I need to decide how to fetch data that changes frequently on the backend. Both useFetch and useAsyncData hydrate server results into the payload to avoid double-fetching, but I am unsure which approach gives more predictable control when cached results risk becoming stale.
My understanding is that useFetch is a wrapper around useAsyncData and $fetch, so it auto-generates a key from the URL and options, while useAsyncData lets me define the key explicitly and wrap multiple calls or transformations. The concern is that a shared or poorly chosen key can cause components to reuse outdated serialized data, and that the server-side cache may serve stale responses unless refresh() is called deliberately.
The concrete constraint: several components on different routes consume the same upstream endpoint, but each route should be able to invalidate or re-fetch independently without triggering redundant requests elsewhere.
Which of the two composables is the better fit for per-route invalidation without redundant fetches? Does an explicit key in useAsyncData change hydration behavior compared to the auto-generated key in useFetch? And what is the recommended way to verify in Nuxt DevTools that hydration is happening without a second network request?
35275 reputation · 18 Apr 2021, 10:22 UTC
For independent invalidation of the same endpoint across routes, useAsyncData with an explicit, route‑specific key is the better choice. It lets each route own its cache entry so calling refresh() updates only that entry without triggering refetches elsewhere.
useFetch is a thin wrapper that automatically builds a cache key from the request URL and options. All components that call the same URL share the same key, so a refresh() invalidates the shared entry and causes every route to refetch.useAsyncData lets you supply any string as the key. By incorporating route information (e.g., the current path, a route‑unique ID, or a combination of path and query) you create distinct cache entries for each route while still benefiting from SSR hydration.useAsyncData with a key that includes the route:const { data, refresh } = await useAsyncData(
`my-data-${useRoute().path}`, // explicit, route‑unique key
() => $fetch('/api/my-data')
)refresh (e.g., via a button) to invalidate only that route’s cache:<button @click="refresh">Reload data</button>refresh() is called, Nuxt updates the cache entry for that key only; other routes retain their existing entries and do not issue a second network request.refresh() and observe that only the route‑specific entry updates in the State tab and that no duplicate request is fired for other routes using the same endpoint.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.