Skip to main content

Admin Panel API: Fetch client

Page summary:

The useFetchClient hook and getFetchClient utility from @strapi/strapi/admin let plugins make authenticated HTTP requests from the admin panel. All requests automatically include the user's authentication token and support automatic token refresh.

Strapi provides a built-in HTTP client for the admin panel that handles authentication automatically. Plugin developers should use this client instead of raw fetch or axios to ensure requests are properly authenticated and intercepted.

Prerequisites

Before diving deeper into the concepts on this page, please ensure you have:

useFetchClient

The useFetchClient hook is designed for use inside React components. It returns an object with get, post, put, and del methods:

my-plugin/admin/src/components/MyComponent.js
import { useFetchClient } from '@strapi/strapi/admin';

const MyComponent = () => {
const { get, post, put, del } = useFetchClient();

const fetchData = async () => {
const { data } = await get('/my-plugin/my-endpoint');
// data contains the parsed JSON response
};
};

getFetchClient

For non-React contexts (services, utility functions, event handlers outside of component trees), use getFetchClient instead:

my-plugin/admin/src/utils/api.js
import { getFetchClient } from '@strapi/strapi/admin';

const { get, post } = getFetchClient();

export const fetchItems = async () => {
const { data } = await get('/my-plugin/items');
return data;
};

Sending data with post and put

The post and put methods accept a data parameter as their second argument:

my-plugin/admin/src/utils/api.js
import { getFetchClient } from '@strapi/strapi/admin';

const { post, put } = getFetchClient();

// Create a new item
export const createItem = async (payload) => {
const { data } = await post('/my-plugin/items', payload);
return data;
};

// Update an existing item
export const updateItem = async (id, payload) => {
const { data } = await put(`/my-plugin/items/${id}`, payload);
return data;
};
Tip

When sending FormData (e.g., file uploads), the fetch client automatically removes the Content-Type header so the browser can set the correct multipart boundary.

Request options

All methods accept an options object with the following properties:

OptionTypeDescription
paramsobjectQuery string parameters, serialized automatically
headersRecord<string, string>Additional request headers (merged with defaults)
signalAbortSignalFor cancelling requests (automatically provided by useFetchClient)
validateStatus(status: number) => boolean | nullCustom function to determine which HTTP statuses should throw
responseType'json' | 'blob' | 'text' | 'arrayBuffer'Controls response parsing (see Response types). Only effective on get.

Using query parameters

Pass params to automatically serialize query strings:

const { data } = await get('/content-manager/collection-types/api::article.article', {
params: {
page: 1,
pageSize: 10,
sort: 'title:asc',
},
});

Response types

By default, responses are parsed as JSON. The get method accepts a responseType option to handle non-JSON responses such as file downloads, CSV exports, or binary data:

responseType valueResponse parsed as
jsonJSON object (default)
blobBlob
textPlain text string
arrayBufferArrayBuffer

Non-JSON responses include status and headers in the return object:

my-plugin/admin/src/components/DownloadButton.js
import { useFetchClient } from '@strapi/strapi/admin';

const DownloadButton = () => {
const { get } = useFetchClient();

const downloadFile = async (url) => {
const { data: blob, status, headers } = await get(url, { responseType: 'blob' });
// Process the blob, e.g. trigger a file download
};
};

Error handling

The fetch client throws a FetchError when a request fails. Use the isFetchError utility to safely check errors:

my-plugin/admin/src/components/MyComponent.js
import { useFetchClient, isFetchError } from '@strapi/strapi/admin';

const MyComponent = () => {
const { get } = useFetchClient();

const fetchData = async () => {
try {
const { data } = await get('/my-plugin/my-endpoint');
// handle success
} catch (error) {
if (isFetchError(error)) {
// error.status contains the HTTP status code
console.error('Request failed:', error.status, error.message);
} else {
throw error; // re-throw non-fetch errors
}
}
};
};
Note

When a request returns a 401 status (except on authentication endpoints), the fetch client automatically attempts to refresh the authentication token and retry the request before throwing an error.

👉 For server-side error handling (controllers, services, middlewares), see Error handling.