Use GraphQL to fetch component-level data in a Next.js Content SDK app
The following example describes how to execute server-side GraphQL queries to get data and use it to populate components. Although this example does not use code generation to automatically create the required types of GraphQL queries and return objects, we strongly recommend introducing code generation in your own work flow.
-
Familiarize yourself with the best practices for working with GraphQL.
-
If you're building a very large website using SitecoreAI, you might need to enable retries for requests to the SitecoreAI Experience Edge GraphQL endpoint for the build process to complete.
To use GraphQL to fetch component-level data in a Next.js app:
-
In your component file, define a GraphQL query. For example:
RequestResponseconst myGraphQLQuery = ` query ($datasource: String!, $contextItem: String!, $language: String!) { # Datasource query # $datasource should be set to the ID of the rendering's datasource item datasource: item(path: $datasource, language: $language) { id name } # Context/route item query # $contextItem should be set to the ID of the current context item (the route item) contextItem: item(path: $contextItem, language: $language) { id # Get the page title from the Page template ...on Page { pageTitle { value } } # List the children of the current route children(hasLayout: true) { results { id # typing fragments can be used anywhere! # so in this case, we're grabbing the 'pageTitle' # field on all child route items. ...on Page { pageTitle { value } } url { path } } } } }` -
Also in your component file, add the following import statements:
RequestResponseimport React, { JSX } from 'react'; import { Field, RichText as JssRichText } from '@sitecore-content-sdk/nextjs'; import { ComponentProps } from 'lib/component-props'; import { GraphQLRequestClient } from '@sitecore-content-sdk/nextjs/client'; import scConfig from 'sitecore.config'; -
Define the types for the result of the GraphQL query. For example:
RequestResponsetype Item = { id: string; url: { path: string; }; pageTitle: { value: string; jsonValue: { value: string; }; }; }; type ItemSearchResults = { results: Item[]; }; type GraphQLDemoDataSource = { name: string; id: string; }; -
Define your TypeScript types and the
GraphQLDemocomponent:RequestResponsetype GraphQLDemoData = { datasource: { name: string; id: string; }; contextItem: { id: string; children: ItemSearchResults; pageTitle: { value: string; }; }; }; type GraphQLDemoProps = ComponentProps & GraphQLDemoData; const GraphQLDemo = (props: GraphQLDemoProps): JSX.Element => { return ( // your markup ); }; -
Define the
getComponentServerPropsfunction and initializeGraphQLRequestClient:RequestResponseimport { GraphQLRequestClient } from '@sitecore-content-sdk/nextjs/client'; ... export const getComponentServerProps = async (rendering, layoutData) => { const graphqlendpoint = `https://${scConfig.api.local.apiHost}/sitecore/api/graph/edge`; const graphQLClient = new GraphQLRequestClient(graphqlendpoint, { scConfig.api.local.apiKey, }); } -
Perform the request and return the result:
RequestResponseimport { GraphQLRequestClient } from '@sitecore-content-sdk/nextjs/client'; ... export const getComponentServerProps = async (rendering, layoutData) => { const graphqlendpoint = `https://${scConfig.api.local.apiHost}/sitecore/api/graph/edge`; const graphQLClient = new GraphQLRequestClient(graphqlendpoint, { scConfig.api.local.apiKey, }); const result = await graphQLClient.request<YourResultType>( myGraphQLQuery, { datasource: rendering.dataSource, contextItem: layoutData?.sitecore?.route?.itemId, language: layoutData?.sitecore?.context?.language, }); return result; }See The Sitecore configuration file for more information.
-
Export your component, wrapped in the
withDatasourceCheckhigher-order component:RequestResponseexport default withDatasourceCheck()<ComponentProps>(GraphQLDemo);
Use the SitecoreClient's getData method
SitecoreClient's getData methodFor apps that use Content SDK 1.2 or later, the SitecoreClient API exposes a simple, typed way to run raw GraphQL requests. It forwards your call to the SDK’s low-level GraphQLClient.request with the same retry, header, and fetch behavior you’ve configured.
Given below is the type signature of the getData method:
getData<T = unknown>( query: string | import('graphql').DocumentNode, variables?: Record<string, unknown>, fetchOptions?: FetchOptions ): Promise<T>The following example retrieves results (id and name) where the name equals Home and the language is en:
type SearchResult = { search: { results: { id: string; name: string }[] } };
const res = await client.getData<SearchResult>(
`
query SearchByName($name: String!, $lang: String!) {
search(where: { name: { equals: $name } }, language: $lang) {
results { id name }
}
}`,
{ name: 'Home', lang: 'en' }
);The following example uses the graphql-tag library to build the query and it retrieves results (id) where the language is en.
import { gql } from 'graphql-tag';
const Query = gql`
query ($lang: String!) { search(language: $lang) { results { id } } }
`;
const res = await client.getData<{ search: { results: { id: string }[] } }>(Query, { lang: 'en' });