---
title: Code components - Data fetching
---

## SWR

[SWR](https://swr.vercel.app/) is provided as a native package and can be
imported and used for general data fetching. Data returned will be shown in the
"Data Fetch" pane under the component preview.

```jsx
import useSWR from 'swr';

export default function Profile() {
  const { data, error, isLoading } = useSWR(
    'https://my-site.com/api/user',
    fetcher,
  );

  if (error) return <div>failed to load</div>;
  if (isLoading) return <div>loading...</div>;
  return <div>hello {data.name}!</div>;
}
```

![Drupal's Drupal Canvas data fetch pane showing the results of fetching
menus data as JSON](../../../assets/images/data-fetch-1.webp)

## Drupal data

### Page and site data

You can access information about the current page with the `getPageData`
utility. Results can be viewed in the Data Fetch pane below the component
preview.

```js
import { getPageData } from '@/lib/drupal-utils';
const { pageTitle, breadcrumbs } = getPageData();
```

You can also access site information with the `getSiteData` utility

```js
import { getSiteData } from '@/lib/drupal-utils';
const { siteName } = getSiteData().branding;
```

![Drupal's Drupal Canvas data fetch pane showing the results of access page
and site data](../../../assets/images/data-fetch-2.webp)

### JSON:API

[`@drupal-api-client/json-api-client`](https://project.pages.drupalcode.org/api_client/) and the
associated [parameter helper package](https://project.pages.drupalcode.org/api_client/jsonapi-tutorial/parameters/#generating-query-strings-with-drupal-jsonapi-params)
are also provided as native packages. [JSON:API module](https://www.drupal.org/docs/core-modules-and-themes/core-modules/jsonapi-module)
must be enabled to interface with this client.

You do not need to provide a baseUrl for the client, it will be
configured automatically, as well as [deserialization](https://project.pages.drupalcode.org/api_client/jsonapi-tutorial/deserializing-data/).

```jsx
import useSWR from 'swr';
import { JsonApiClient } from '@drupal-api-client/json-api-client';
import { DrupalJsonApiParams } from 'drupal-jsonapi-params';
const client = new JsonApiClient();

export default function List() {
  const { data, error, isLoading } = useSWR(
    [
      'node--article',
      {
        queryString: new DrupalJsonApiParams()
          .addInclude(['field_tags'])
          .getQueryString(),
      },
    ],
    ([type, options]) => client.getCollection(type, options),
  );

  if (error) return 'An error has occurred.';
  if (isLoading) return 'Loading...';
  return (
    <ul>
      {data.map((article) => (
        <li key={article.id}>{article.title}</li>
      ))}
    </ul>
  );
}
```

You can override the `baseUrl` and any default options:

```js
const client = new JsonApiClient('https://drupal-api-demo.party', {
  serializer: undefined,
  cache: undefined,
});
```

### Helper utilities

Utility functions for working with JSON:API and core APIs are also provided in
the `@/lib/jsonapi-utils` and `@/lib/drupal-utils` packages respectively.

### Examples

Given a node returned from `JSON:API`, return either the path alias or fall back
to /node/x path:

```jsx
import { getNodePath } from '@/lib/jsonapi-utils';
const articles = data.map((article) => ({
  ...article,
  _path: getNodePath(article),
}));

// Sort menu items from jsonapi_menu_items module into a tree with additional
// _children and _hasSubmenu properties.
import { sortMenu } from '@/lib/jsonapi-utils';
const { data } = useSWR(['menu_items', 'main'], ([type, resourceId]) =>
  client.getResource(type, resourceId),
);
const menu = sortMenu(data);
```

Using the [core linkset endpoint](https://www.drupal.org/docs/develop/decoupled-drupal/decoupled-menus/decoupled-menus-overview):

```jsx
import { sortMenu } from '@/lib/drupal-utils';
const { data } = useSWR('/system/menu/main/linkset', async (url) => {
  const response = await fetch(url);
  return response.json();
});
const menu = sortMenu(data);
```
