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.

Before you begin

To use GraphQL to fetch component-level data in a Next.js app:

  1. In your component file, define a GraphQL query. For example:

    RequestResponse
    const 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
            }
          }
        }
      }
    }`
  2. Also in your component file, add the following import statements:

    RequestResponse
    import 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';
    
  3. Define the types for the result of the GraphQL query. For example:

    RequestResponse
    type Item = {
      id: string;
      url: {
        path: string;
      };
      pageTitle: {
        value: string;
        jsonValue: {
          value: string;
        };
      };
    };
    
    type ItemSearchResults = {
      results: Item[];
    };
    
    type GraphQLDemoDataSource = {
      name: string;
      id: string;
    };
  4. Define your TypeScript types and the GraphQLDemo component:

    RequestResponse
    type 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
      );
    };
  5. Define the getComponentServerProps function and initialize GraphQLRequestClient:

    RequestResponse
    import { 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,
      });
    }
  6. Perform the request and return the result:

    RequestResponse
    import { 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.

  7. Export your component, wrapped in the withDatasourceCheck higher-order component:

    RequestResponse
    export default withDatasourceCheck()<ComponentProps>(GraphQLDemo);

Use the SitecoreClient's getData method

For 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:

RequestResponse
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:

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

RequestResponse
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' });

Do you have some feedback for us?

If you have suggestions for improving this article,