diff --git a/docs/docs/core/hooks/use-fetch-client.mdx b/docs/docs/core/hooks/use-fetch-client.mdx new file mode 100644 index 0000000000..83d28fe201 --- /dev/null +++ b/docs/docs/core/hooks/use-fetch-client.mdx @@ -0,0 +1,103 @@ +--- +title: useFetchClient +slug: /hooks/use-fetch-client +description: API reference for the useFetchClient hook in Strapi +tags: + - hooks + - axios + - data +--- + +## Usage + +The following example shows a basic way to use the `useFetchClient` hook to make a get request to a Strapi backend endpoint: + +```jsx +import {useState} from "react" +import useFetchClient from '@strapi/admin/admin/src/hooks/useFetchClient'; + +const Component = () => { + const [items, setItems] = useState([]); + const { get } = useFetchClient(); + const requestURL = "/some-endpoint"; + + const handleGetData = async () => { + const { data } = await get(requestURL); + setItems(data.items); + } + + return( +
+
+ { + items && items.map(item =>

{item.name}

)) + } +
+ +
+ ) +} +``` + +## Methods + +Essentially, this is an abstraction around the axios instance exposed by a hook. It provides a simple interface to handle API calls to the Strapi backend. +It handles request cancellations inside the hook with an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController). This is typically triggered when the component is unmounted so all the requests that it is currently making are aborted. + +The hook exposes four methods: + +- **get(url, config)**: requires a relative url (`string`) and makes a `GET` request to the Strapi backend with an optional configuration `object` passed as second parameter. +- **post(url, data, config)**: requires a relative url (`string`) and makes a `POST` request with the required data `object` to the Strapi backend with the optional configuration `object` passed as third parameter. +- **put(url, data, config)**: requires a relative url (`string`) and makes a `PUT` request with the required data `object` to the Strapi backend with the optional configuration `object` passed as third parameter. +- **del(url, config)**: requires a relative url (`string`) and makes a `DELETE` request to the Strapi backend with an optional configuration `object` passed as second parameter. + +## Implementation details + +The following information is the internal additions we've added to the axios instance via two request interceptors. As well as an explanation of the `baseUrl`. + +### Base URL + +The default URL will be the one defined in the environment variable: `STRAPI_ADMIN_BACKEND_URL`. + +### Interceptors + +#### Request + +The request interceptor adds the following parameters to the header: + +```js +{ + Authorization: `Bearer `, + Accept: 'application/json', + 'Content-Type': 'application/json', +} +``` + +#### Response + +If everything works correctly, the response is returned as it comes from the backend. However, if it contains a **status code of 401** the authentication details will be removed from +the application storage and the window will be reloaded. + +:::caution +Have this in mind if using this hook in pages where the auth token is not available, such as `login`, because it will create an infinite loop. See the [Troubleshooting](#troubleshooting) section for more information. +::: + +## Further Reading + +- [axios instance API](https://axios-http.com/docs/instance) +- [AbortController](https://axios-http.com/docs/cancellation) + +## Troubleshooting + +### Authentication problems + +Trying to access a protected route from a context where the auth token is not available may lead to an infinite loop due to the response interceptor that +reloads the page when obtaining a 401 response. One option to avoid this from happening is to not consider a 401 response as an error, see below: + +```js +const { + data: { data: properties }, +} = await get(`/protected-endpoint`, { + validateStatus: (status) => status < 500, +}); +``` diff --git a/docs/sidebars.js b/docs/sidebars.js index c64e6f077a..6154e8ff2a 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -39,6 +39,17 @@ const sidebars = { }, ], }, + { + type: 'category', + label: 'Hooks', + items: [ + { + type: 'doc', + label: 'useFetchClient', + id: 'core/hooks/use-fetch-client', + }, + ], + }, { type: 'category', label: 'Content Type Builder',