Skip to content

Code components - Data fetching

SWR 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.

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

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.

import { getPageData } from 'drupal-canvas';
const { pageTitle, breadcrumbs } = getPageData();

You can also access site information with the getSiteData utility

import { getSiteData } from 'drupal-canvas';
const { siteName } = getSiteData().branding;

Drupal's Drupal Canvas data fetch pane showing the results of access page
and site data

drupal-canvas provides the JSON:API client automatically configured with a baseUrl as well as Jsona for deserialization. Drupal core’s JSON:API module must be enabled to use this client.

The associated parameter helper package is also included as a native package.

import { JsonApiClient } from 'drupal-canvas';
import { DrupalJsonApiParams } from 'drupal-jsonapi-params';
import useSWR from 'swr';
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:

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

Utility functions for working with JSON:API and core APIs are provided in the drupal-canvas package.

The following example fetches nodes using a preconfigured version of the JSON:API client from the Drupal API Client, and outputs links to each of them using the getNodePath utility from the drupal-canvas package, which will return the path alias if exists, or fall back to the /node/[nid] path.

import { getNodePath, JsonApiClient } from 'drupal-canvas';
import { DrupalJsonApiParams } from 'drupal-jsonapi-params';
import useSWR from 'swr';
const Articles = () => {
const client = new JsonApiClient();
const { data, error, isLoading } = useSWR(
[
'node--article',
{
queryString: new DrupalJsonApiParams()
.addSort('created', 'DESC')
.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}>
<a href={getNodePath(article)}>{article.title}</a>
</li>
))}
</ul>
);
};
export default Articles;

This example builds a navigation menu using the JSON:API Menu Items module:

import { JsonApiClient, sortMenu } from 'drupal-canvas';
import useSWR from 'swr';
const client = new JsonApiClient();
const Navigation = () => {
const { data, isLoading, error } = useSWR(
['menu_items', 'main'],
([type, resourceId]) => client.getResource(type, resourceId),
);
if (error) return 'An error has occurred.';
if (isLoading) return 'Loading...';
const menu = sortMenu(data);
return (
<ul>
{menu.map((item) => (
<li key={item.id}>{item.title}</li>
))}
</ul>
);
};
export default Navigation;

You can also build a navigation menu using Drupal core’s linkset endpoint.

import { sortLinksetMenu } from 'drupal-canvas';
import useSWR from 'swr';
const Navigation = () => {
const { data, isLoading, error } = useSWR(
'/system/menu/main/linkset',
async (url) => {
const response = await fetch(url);
return response.json();
},
);
if (error) return 'An error has occurred.';
if (isLoading) return 'Loading...';
const menu = sortLinksetMenu(data);
return (
<ul>
{menu.map((item) => (
<li key={item.id}>{item.title}</li>
))}
</ul>
);
};
export default Navigation;