Fetching data in Pinia store - useFetch make sense here?
I have Nuxt app with Pinia. In one store, I find myself using
useFetch
for data fetching (with SSR support), then expose the status, error and another computed variable which does some computation on the data returned.
This provides pretty damn clean API, with status and error baked in.
But when I looked for examples of Pinia with useFetch, I couldn't find any. All the AI GTPs suggest exposing a function to fetch data (e.g, fetchItems()), while using $fetch.
Am I missing something here? Any reason to not useFetch on store setup?14 Replies
Hi @lazygopher. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
Using useFetch directly inside a Pinia store's setup function is technically possible and can provide a clean API with reactive status, error, and data handling, as you've described. However, there are some important caveats and potential pitfalls to be aware of, especially in the context of SSR and reactivity.
Key Considerations
1. SSR and Reactivity Issues
The Nuxt documentation and community discussions highlight that useFetch is designed to be called directly in a component setup function, plugin, or route middleware—not typically inside a Pinia store. This is because useFetch leverages Nuxt's SSR payload system to transfer data from server to client and to avoid double-fetching during hydration. When used inside a store, especially outside of a component context, you may encounter issues where the data is not available as expected, or reactivity does not work as intended on the first request. This is discussed in this Stack Overflow answer, where the only reliable way to access the response data in a store was via an interceptor, not directly from the returned refs. 2. Best Practice: Expose Fetch Functions
Most examples and recommendations suggest exposing a fetch function (e.g., fetchItems) in your store, which internally uses $fetch or useFetch when called from a component. This approach gives you more control over when and how data is fetched, and avoids the SSR/hydration pitfalls that can arise from using useFetch directly in the store's setup function. The Nuxt docs and several Stack Overflow answers recommend using $fetch for client-only actions or POST requests, and useFetch/useAsyncData for SSR-friendly, component-level data fetching. See Nuxt Data Fetching Docs and this Stack Overflow discussion for more details. 3. Reactivity and Awaiting Data
When useFetch is used in a store, you may find that the data is not immediately available, even if you use async/await. This is due to the SSR nature of Nuxt and how the payload is managed. As noted in the Stack Overflow answer, "the data is not available via await, this is related to the SSR nature of the response" and you may need to use interceptors or other workarounds to access the data reliably in a store context. Example from the Docs The Nuxt docs and examples consistently show useFetch being used in component setup functions, not in Pinia stores: Nuxt useFetch API Docs Summary - It is possible to use useFetch in a Pinia store, but it is not the recommended or most robust approach due to SSR and reactivity caveats. - Best practice is to expose a fetch function in your store and call useFetch or $fetch from the component, or use $fetch directly in the store for client-only actions. - If you need SSR support and want to avoid double-fetching, use useFetch or useAsyncData in the component, not in the store setup. If you want to keep your API clean and SSR-safe, consider moving the useFetch call to the component and exposing a fetch function in your store instead.
- Nuxt Data Fetching Docs
- Nuxt useFetch API Docs
- Stack Overflow: Http GET request via Pinia action only works on second attempt in Nuxt app
- Stack Overflow: Which to use: $fetch, useAsyncData or useFetch for GET and POST requests in Nuxt 3? ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
The Nuxt documentation and community discussions highlight that useFetch is designed to be called directly in a component setup function, plugin, or route middleware—not typically inside a Pinia store. This is because useFetch leverages Nuxt's SSR payload system to transfer data from server to client and to avoid double-fetching during hydration. When used inside a store, especially outside of a component context, you may encounter issues where the data is not available as expected, or reactivity does not work as intended on the first request. This is discussed in this Stack Overflow answer, where the only reliable way to access the response data in a store was via an interceptor, not directly from the returned refs. 2. Best Practice: Expose Fetch Functions
Most examples and recommendations suggest exposing a fetch function (e.g., fetchItems) in your store, which internally uses $fetch or useFetch when called from a component. This approach gives you more control over when and how data is fetched, and avoids the SSR/hydration pitfalls that can arise from using useFetch directly in the store's setup function. The Nuxt docs and several Stack Overflow answers recommend using $fetch for client-only actions or POST requests, and useFetch/useAsyncData for SSR-friendly, component-level data fetching. See Nuxt Data Fetching Docs and this Stack Overflow discussion for more details. 3. Reactivity and Awaiting Data
When useFetch is used in a store, you may find that the data is not immediately available, even if you use async/await. This is due to the SSR nature of Nuxt and how the payload is managed. As noted in the Stack Overflow answer, "the data is not available via await, this is related to the SSR nature of the response" and you may need to use interceptors or other workarounds to access the data reliably in a store context. Example from the Docs The Nuxt docs and examples consistently show useFetch being used in component setup functions, not in Pinia stores: Nuxt useFetch API Docs Summary - It is possible to use useFetch in a Pinia store, but it is not the recommended or most robust approach due to SSR and reactivity caveats. - Best practice is to expose a fetch function in your store and call useFetch or $fetch from the component, or use $fetch directly in the store for client-only actions. - If you need SSR support and want to avoid double-fetching, use useFetch or useAsyncData in the component, not in the store setup. If you want to keep your API clean and SSR-safe, consider moving the useFetch call to the component and exposing a fetch function in your store instead.
I'm sorry, but there are no official examples or documentation recommending the use of useFetch directly in a Pinia store's setup function, and there are known caveats with this approach regarding SSR and reactivity. For robust SSR support and predictable reactivity, use useFetch in components and expose fetch functions in your stores instead.References:
- Nuxt Data Fetching Docs
- Nuxt useFetch API Docs
- Stack Overflow: Http GET request via Pinia action only works on second attempt in Nuxt app
- Stack Overflow: Which to use: $fetch, useAsyncData or useFetch for GET and POST requests in Nuxt 3? ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@693201794137981049> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
no, use $fetch
and use useAsyncData when you call the function
Can you show a simple example? the above code works but I'm afraid I'm missing something
I also want SSR on this endpoint, so data is fetched server-side and hydrated on the client without additional call
Do you mind elaborate why it's not recommended to use useFetch in a store? What's the problem with it?
because useFetch is supposed to be called in nuxt hooks or components
useStore isn't
So it might have glitches and stuff?
yeah
so in store, using $fetch and in component use useAsyncData and it enables SSR support?
yes
don't forget about the last comment tho
need to return something
Also - is fetching data in component and updating store from the component is a good pattern?
Or trigger the fetch on the store, and wrap the logic of updating state in it
it's up to you
u can do
so now in component u just to call it
but also
return true
And if I want to have lazy, so on the UX I get loading indicator, should I do it without await? right now with the useFetch it shows loading indicator