diff --git a/docs/1.getting-started/6.data-fetching.md b/docs/1.getting-started/6.data-fetching.md index 02ba9dfdbf..d283ecc2db 100644 --- a/docs/1.getting-started/6.data-fetching.md +++ b/docs/1.getting-started/6.data-fetching.md @@ -24,9 +24,9 @@ When using a framework like Nuxt that can perform calls and render pages on both The [`useFetch`](/docs/api/composables/use-fetch) and [`useAsyncData`](/docs/api/composables/use-async-data) composables ensure that once an API call is made on the server, the data is properly forwarded to the client in the payload. -The payload is a JavaScript object accessible through [`useNuxtApp().payload`](/docs/api/composables/use-nuxt-app#payload). It is used on the client to avoid refetching the same data when the code is executed in the browser. +The payload is a JavaScript object accessible through [`useNuxtApp().payload`](/docs/api/composables/use-nuxt-app#payload). It is used on the client to avoid refetching the same data when the code is executed in the browser [during hydration](/docs/guide/concepts/rendering#universal-rendering). -::callout +::callout{color="blue" icon="i-ph-info-duotone"} Use the [Nuxt DevTools](https://devtools.nuxt.com) to inspect this data in the **Payload tab**. :: @@ -34,6 +34,10 @@ Use the [Nuxt DevTools](https://devtools.nuxt.com) to inspect this data in the * Nuxt uses Vue’s [``](https://vuejs.org/guide/built-ins/suspense) component under the hood to prevent navigation before every async data is available to the view. The data fetching composables can help you leverage this feature and use what suits best on a per-calls basis. +::callout{color="blue" icon="i-ph-info-duotone"} +You can add the [``](/docs/api/components/nuxt-loading-indicator) to add a progress bar between page navigations. +:: + ## `useFetch` The [`useFetch`](/docs/api/composables/use-fetch) composable is the most straightforward way to perform data fetching. @@ -44,7 +48,7 @@ const { data: count } = await useFetch('/api/count') ``` @@ -58,69 +62,85 @@ This composable is a wrapper around the [`useAsyncData`](/docs/api/composables/u Nuxt includes the `ofetch` library, and is auto-imported as the `$fetch` alias globally across your application. It's what `useFetch` uses behind the scenes. -```ts -const users = await $fetch('/api/users').catch((error) => error.data) +```vue [pages/todos.vue] + ``` -::callout -Beware that using only `$fetch` will not provide [network calls de-duplication and navigation prevention](#why-using-specific-composables). It is recommended to use `$fetch` when posting data to an event handler, when doing client-side only logic, or combined with `useAsyncData`. -:: - -The `ofetch` library is built on top of [the `fetch` API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) and adds handy features to it: - -- Works the same way in browser, Node or worker environments -- Automatic response parsing -- Error handling -- Auto-retry -- Interceptors - -::read-more{title="ofetch" to="https://github.com/unjs/ofetch" target="_blank"} -Read the full documentation of `ofetch` +::callout{color="amber" icon="i-ph-warning-duotone"} +Beware that using only `$fetch` will not provide [network calls de-duplication and navigation prevention](#why-using-specific-composables). :br +It is recommended to use `$fetch` for client-side interactions (event based) or combined with [`useAsyncData`](#useasyncdata) when fetching the initial component data. :: ::read-more{to="/docs/api/utils/dollarfetch"} -Read more about `$fetch` +Read more about `$fetch`. :: ## `useAsyncData` The `useAsyncData` composable is responsible for wrapping async logic and returning the result once it is resolved. -Indeed, `useFetch(url)` is nearly equivalent to `useAsyncData(url, () => $fetch(url))` - it's developer experience sugar for the most common use case. +::callout +`useFetch(url)` is nearly equivalent to `useAsyncData(url, () => $fetch(url))` :br +Iit's developer experience sugar for the most common use case. +:: There are some cases when using the [`useFetch`](/docs/api/composables/use-fetch) composable is not appropriate, for example when a CMS or a third-party provide their own query layer. In this case, you can use [`useAsyncData`](/docs/api/composables/use-async-data) to wrap your calls and still keep the benefits provided by the composable. -The first argument of [`useAsyncData`](/docs/api/composables/use-async-data) is the unique key used to cache the response of the second argument, the querying function. This argument can be ignored by directly passing the querying function. In that case, it will be auto-generated. - -```ts +```vue [pages/users.vue] + ``` -Since the autogenerated key only takes into account the file and line where `useAsyncData` is invoked, it is recommended to always create your own key to avoid unwanted behavior, if you are creating your own custom composable that is wrapping `useAsyncData`. +::callout{color="blue" icon="i-ph-info-duotone"} +The first argument of [`useAsyncData`](/docs/api/composables/use-async-data) is a unique key used to cache the response of the second argument, the querying function. This key can be ignored by directly passing the querying function, the key will be auto-generated. +:br :br +Since the autogenerated key only takes into account the file and line where `useAsyncData` is invoked, it is recommended to always create your own key to avoid unwanted behavior, like when you are creating your own custom composable wrapping `useAsyncData`. +:br :br +Setting a key can be useful to share the same data between components using [`useNuxtData`](/docs/api/composables/use-nuxt-data) or to [refresh specific data](/docs/api/utils/refresh-nuxt-data#refresh-specific-data). +:: -```ts -const id = ref(1) +```vue [pages/users/[id\\].vue] + ``` The `useAsyncData` composable is a great way to wrap and wait for multiple `useFetch` to be done, and then retrieve the results of each. -```ts +```vue + ``` ::read-more{to="/docs/api/composables/use-async-data"} -Read more about `useAsyncData` +Read more about `useAsyncData`. :: ## Options @@ -153,16 +173,18 @@ const { pending, data: posts } = useFetch('/api/posts', { You can alternatively use [`useLazyFetch`](/docs/api/composables/use-lazy-fetch) and `useLazyAsyncData` as convenient methods to perform the same. -```ts +```vue + ``` ::read-more{to="/docs/api/composables/use-lazy-fetch"} -Read more about `useLazyFetch` +Read more about `useLazyFetch`. :: ::read-more{to="/docs/api/composables/use-lazy-async-data"} -Read more about `useLazyAsyncData` +Read more about `useLazyAsyncData`. :: ### Client-only fetching @@ -191,7 +213,9 @@ The `pick` option helps you to minimize the payload size stored in your HTML doc ```vue