Component-level data fetching in Next.js apps

Next.js can prerender pages at build time or on each request using page-level data fetching strategies for each rendering form.

If you want to fetch component-specific data at the component level, you can use a mechanism similar to page-level data fetching by implementing and exporting the getComponentServerProps function.

Note

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

Important

Component-level data fetching is not intended to work in error pages.

The ComponentPropsService class

The SitecoreClient class implementation for Next.js allows for retrieval of component-level props via its getComponentData method. It will called in [[...path]].tsx

The getComponentData accepts the following parameters:

  • layoutData - Layout Service data from your page.

  • context - the Next.js SSG or SSR context.

  • components - list of registered components from componentMap (imported from .sitecore/component-map out-of-the-box).

The getComponentData method traverses the layout service data and looks at all the renderings. To find the components that require data fetching, the service watches the component using the rendering.componentName property against the list of component registrations in the component map.

If the component defines and exports the getComponentServerProps function, getComponentData will invoke the ComponentPropsService class and run the function. After applying all side effects, it stores the component data in a componentProps object in the format { [rendering.uid]: data }.

For example, the following component defines a data-fetching function and displays the injected component props.

Note

If your component contains code that's executed based on static or server side Next.js context, use the isServerSidePropsContext helper method with the following import:

RequestResponse
import { isServerSidePropsContext } from '@sitecore-content-sdk/nextjs/utils'; 
RequestResponse
import { JSX } from 'react';
import {
  Text,
  RichText,
  Field,
  withDatasourceCheck,
  ComponentParams,
  ComponentRendering,
  GetComponentServerProps,
} from '@sitecore-content-sdk/nextjs';

type ComponentProps = {
  rendering: ComponentRendering;
  params: ComponentParams;
};

type ContentBlockProps = ComponentProps & {
  fields: {
    heading: Field<string>;
    content: Field<string>;
  };
};

const ContentBlock = ({ fields }: ContentBlockProps): JSX.Element => (
  <div className="contentBlock">
    <Text tag="h2" className="contentTitle" field={fields.heading} />
    <RichText className="contentDescription" field={fields.content} />
  </div>
);

const fetchPost = () =>
  fetch('https://jsonplaceholder.typicode.com/posts/1').then((res) => res.json());

export const getComponentServerProps: GetComponentServerProps = async (
  rendering,
  layoutData,
  context
) => {
  const post = await fetchPost();
  return post;
};

export default withDatasourceCheck()<ContentBlockProps>(ContentBlock);

Do you have some feedback for us?

If you have suggestions for improving this article,