Use GraphQL to fetch component-level data in JSS Next.js apps

Version: 22.x

The Next.js sample app supports two methods for component-level data fetching with GraphQL:

  • Connected GraphQL, which enables you to query GraphQL endpoints from your component code.

  • Integrated GraphQL (IGQL), which involves adding queries to rendering items in XM Cloud.

Note

If you include secrets or sensitive information in component-level getStaticProps and getServerSideProps functions, that information will only be included in the client-side bundle in development mode.

Component-level data fetching with connected GraphQL

The sample application provided in the JSS Next.js starter kit includes a GraphiQL interface for exploring the schema, testing queries, and identifying which GraphQL types can be used by your components. The default path for this premade interface is ${SITECORE_API_HOST}/sitecore/api/graph/edge/ui?sc_apikey=${SITECORE_API_KEY}.

Note

The graphql-let library provides the same information about types in the corresponding .graphq.d.ts files.

To use component-level data fetching with connected GraphQL:

  1. In a GraphQL-ConnectedDemo.dynamic.graphql file, define a GraphQL query. For example:

    RequestResponse
    query ConnectedDemoQuery($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
        # Strongly-typed querying on known templates is possible!
        ...on GraphQLConnectedDemo {
          # Single-line text field
          sample1 {
            # the 'jsonValue' field is a JSON blob that represents the object that
            # should be passed to JSS field rendering helpers (i.e. text, image, link)
            jsonValue
            value
          }
          # General Link field
          sample2 {
            jsonValue
            # Structured querying of the field's values is possible
            text
            target
            url
            # Access to the template definition is possible
            definition {
              type
              shared
            }
          }
        }
      }
    
      # 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 app route template
        ...on AppRoute {
          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 AppRoute {
              pageTitle {
                jsonValue
                value
              }
            }
            url{
              path
            }
          }
        }
      }
    }

    The library graphql-let generates a file named GraphQLDemoQuery.graphql.d.ts.

  2. In your component file, add the following import statements:

    RequestResponse
    import React, { useEffect } from 'react';
    import {
      Text,
      Link,
      GetServerSideComponentProps,
      GetStaticComponentProps,
      constants,
      withDatasourceCheck,
    } from '@sitecore-jss/sitecore-jss-nextjs';
    import { GraphQLRequestClient } from '@sitecore-jss/sitecore-jss-nextjs/graphql';
    import {
      resetEditorChromes
    } from '@sitecore-jss/sitecore-jss-nextjs/utils';
    import { ComponentProps } from 'lib/component-props';
    import config from 'temp/config';
  3. If needed, update your introspection data to have access to the latest GraphQL types.

  4. Import your GraphQL query and GraphQL types:

    RequestResponse
    import { ConnectedDemoQueryDocument } from './GraphQL-ConnectedDemo.dynamic.graphql';
    import {
      AppRoute as AppRoute,
      Item,
      GraphQlConnectedDemo as GrapQLConnectedDemoDatasource,
    } from 'graphql-types';
    
  5. Define your TypeScript types and the GraphQLDemo component:

    RequestResponse
    type RouteItem = AppRoute & Item;
    
    type GraphQLConnectedDemoData = {
      datasource: GrapQLConnectedDemoDatasource;
      contextItem: RouteItem;
    };
    
    type GraphQLConnectedDemoProps = ComponentProps & GraphQLConnectedDemoData;
    
    const GraphQLConnectedDemo = (props: GraphQLConnectedDemoProps): JSX.Element => {
      useEffect(() => {
        resetEditorChromes();
      }, []);
    
      return (
        // your markup
      );
    };
  6. In your component, define getStaticProps or getServerSideProps functions. The following example implements the getStaticProps function. Because GraphQL does not work in disconnected mode, you must exit the function if the app runs in disconnected mode. You must also create a new GraphQL client using the graphqlClientFactory property from lib/graphql-client-factory. For example:

    RequestResponse
    import graphqlClientFactory from 'lib/graphql-client-factory';  
    ...
    export const getStaticProps: GetStaticComponentProps = async (rendering, layoutData) => {
      if (process.env.JSS_MODE === constants.JSS_MODE.DISCONNECTED) {    
        return null;  
      }
      const graphQLClient = graphqlClientFactory();
    }
    
  7. Perform the request and return the result:

    RequestResponse
    import graphqlClientFactory from 'lib/graphql-client-factory';  
    ...
    export const getStaticProps: GetStaticComponentProps = async (rendering, layoutData) => {
      if (process.env.JSS_MODE === constants.JSS_MODE.DISCONNECTED) {    
        return null;  
      }
      const graphQLClient = graphqlClientFactory();
    
      const result = await graphQLClient.request<YourResultType>(
        yourQuery,
        {
          datasource: rendering.dataSource,
          contextItem: layoutData?.sitecore?.route?.itemId,
          language: layoutData?.sitecore?.context?.language,
        }
      );
      return result;
    };
    
  8. Export your component, wrapped in the withDatasourceCheck higher-order component:

    RequestResponse
    export default withDatasourceCheck()&lt;ComponentProps&gt;(GraphQLConnectedDemo);

To help make sure you've configured your application correctly, you can compare it to the connected GraphQL component included in the Sitecore sample app.

Tip

If you're building a very large website using the Sitecore XM Cloud, you might have to enable retries for requests to the XM Cloud Experience Edge GraphQL endpoint for the build process to complete.

Component-level data fetching with integrated GraphQL

Integrated GraphQL (IGQL) directly affects the layout data shape returned for a specific component by the Experience Edge layout response.

A GraphQL query can be defined on the rendering item that shapes the data returned by the layout service, and can be used from the props.fields object in the same way as a standard response. This gives you more control over the shape of the data being returned.

To add IGQL to a component, you can enter the query in the Component GraphQL Query field on the rendering item of the component.

The Component GraphQL Query field, containing an integrated GraphQL query.
Tip

Refer to the integrated GraphQL component in the Sitecore sample app for configuration guidance if needed.

Do you have some feedback for us?

If you have suggestions for improving this article,