Streamlining Sitecore XM Cloud Layout Data with Integrated GraphQL

Optimizing Performance with Targeted Data Fetching

May 21, 2025

By David Austin

When is it a Good Time to Utilize Integrated GraphQL?

There are a lot of use cases for when you need to investigate utilizing Integrated GraphQL. You will undoubtedly encounter one of these scenarios as a front-end developer working with a Sitecore back-end.

Reducing Unnecessary Data Load

Integrated GraphQL can be used to refine your queries if your components are importing big, complicated data structures from Sitecore items, many of which contain fields you don't really require. This saves needless work, boosts performance, and minimizes front-end payloads.

Enhancing Experience Editor Compatibility

Using jsonValue in Component GraphQL Query when working with Sitecore's Experience Editor or Pages guarantees that fields stay editable while preserving effective front-end rendering. This is essential for preserving content editing flexibility without compromising efficiency.

Optimizing API Calls for Front-End Rendering

By embedding the required queries directly in Component GraphQL Query, unnecessary API calls are avoided as opposed to creating several GraphQL queries from Next.js components (such as retrieving URLs separately). This makes your codebase easier to maintain, lowers latency, and streamlines data fetching logic.

For this article, I wanted to create a component that pulls in the summary heading, summary description and a summary image from a page to display within a component. A featured article or page component. We’ll call it a Resource List for the purposes here. Each “page” being brought in, we’ll call a Resource List Card. For our example, we’re creating a list of pages related to the Empire, from Star Wars. Nothing too exciting, but it will fit our purpose.

While looking at the component we’re going to build it might not seem too crazy. What’s hidden underneath, however, is the fact that each of those three pages referenced on the right-side, actually have a lot of other fields on them, some of which contain a lot of data. Now it might not always be a single field containing a lot of data, it could very well be that an item has dozens of fields that are irrelevant to what we’re using it for.

So while we might only want three particular fields for our component, this giant Content field will also come with it. And we can see that it did when we look at the output source when the component is on the page. Completely unnecessary.

So what do we do?

Using the Integrated GraphQL

Nestled deep with the JSON Rendering you will find a field called Component GraphQL Query. It’s often overlooked as for the most part, when a component is being build, the datasource item probably only contains what is absolutely necessary. But this isn’t always the case. As we’ve seen above.

What Does the Structure of the GraphQL Look Like?

While this is indeed GraphQL, there are key differences as it effectively acts as a function with potential parameters that can be passed through. Those parameters are:

  • $datasource
  • $contextItem
  • $language

So for our function in particular, we’re able to create it as such:

query ResourceListCardQuery($datasource: String!) {
  datasource: item(path: $datasource, language: "en") {
    id
    name
    url {
      path
    }
    ... on ContentPage{
      summaryHeading{
        jsonValue
      }
      summaryDescription{
        jsonValue
      }
      summaryImage{
        jsonValue
      }
    }
  }
}

In the above script, ContentPage is our template with summaryHeading which is a Field<string>, summaryDescription is a RichTextField, and summaryImage is an ImageField. By using jsonValue we ensure that the fields are still editable within Experience Editor and Pages.

We can verify the output by using the IDE locally.

What Do We Change on the Front-end Next.js Component?

While the changes on the back-end are relatively simple you might be thinking, but I’ve already got my component working, do I have to rewrite it all? The answer, thankfully, is no, you do not.

Let’s Organize Our Types

Initially we had the following type structure setup for our component.

type ResourceListCardFields = {
  summaryHeading: Field<string>;
  summaryDescription: RichTextField;
  summaryImage: ImageField;
  url: string;
};

interface ResourceListCardProps extends ComponentProps {
  fields: ResourceListCardFields;
}

To that, I’ve now added in an additional type.

type IntegratedResourceListCardFields = {
  data: {
    datasource: {
      summaryHeading: {
        jsonValue: Field<string>;
      };
      summaryDescription: {
        jsonValue: RichTextField;
      };
      summaryImage: {
        jsonValue: ImageField;
      };
      url: {
        path: string;
      };
    };
  };
};

Let’s Update Our getStaticProps

While our component already had a getStaticProps to provide us with the URL to the item by performing an item lookup via a GraphQL query, we no longer need that as we’re now getting that as part of the integrated component GraphQL query within the JSON Rendering itself. As such, this is now one fewer call on the front-end.

const GetComponentProps = async (rendering: ComponentRendering, layoutData: LayoutServiceData) => {
  // IntegratedResourceListCardFields is the type of the fields object coming from Component GraphQL Query
  const newFields = rendering.fields as unknown as IntegratedResourceListCardFields;
  try {
    return {
      fields: {
        summaryHeading: newFields?.data?.datasource?.summaryHeading?.jsonValue,
        summaryDescription: newFields?.data?.datasource?.summaryDescription?.jsonValue,
        summaryImage: newFields?.data?.datasource?.summaryImage?.jsonValue,
        url: newFields?.data?.datasource?.url?.path,
      },
    };
  } catch (error) {
    console.error('Error assigning fields:', error);
    return {
      rendering: { ...rendering },
      route: layoutData?.sitecore?.route,
    };
  }
};

export const getStaticProps: GetStaticComponentProps = async (rendering, layoutData) => {
  return await GetComponentProps(rendering, layoutData);
};

With doing it this way, we’ve minimally impacted the way the component functions. In fact, I didn’t even touch the actual rendering portion of the component’s result.

What are the Savings Using Component GraphQL Query?

Well in this example, the savings were minimal. Even looking at the view-source alone, I only saved 2kB which you could certainly argue was a wasted effort. However, this was a very simple case. If I had more metadata fields, or additional referenced items on that page, that size savings could grow quite quickly.

The important thing to realize is that while in the beginning, it might look like a drop in the bucket, keeping your eye open for savings could have great benefits in the future.

What are the Downsides to Component GraphQL Query?

The most noticeable downside is that if this is something you and your team are not used to using, if you decide to or requirements change in the future and you have to add a field, you could very easily forget this is in place and then waste time trying to figure out why a particular field is not showing up.

The other downside is potentially increased complexity now required in the front-end to support it. The more and more fields your component requires the additional steps required to support them. It ultimately becomes a judgement call. That said, in my case because I needed to do a GQL lookup to get the URL of the item anyways, this actually reduced code and build time for the component.

Prefer a visual guide? I've got you covered — check out this video for a walkthrough of everything covered here.

Image of Fishtank employee David Austin

David Austin

Development Team Lead | 4x Sitecore Technology MVP

David is a decorated Development Team Lead with 4 Sitecore Technology MVPs and Coveo MVP awards, as well as Sitecore CDP & Personalize Certified. He's worked in IT for 25 years; everything ranging from Developer to Business Analyst to Group Lead helping manage everything from Intranet and Internet sites to facility management and application support. David is a dedicated family man who loves to spend time with his girls. He's also an avid photographer and loves to explore new places.