---
title: "Component-level data fetching in JSS Next.js apps"
slug: "component-level-data-fetching-in-jss-next-js-apps"
abstract: "Overview of how JSS Next.js apps retrieve component-level data and how it can be accessed"
---
# Component-level data fetching in JSS 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](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/prerendering-methods-and-data-fetching-strategies-in-jss-next-js-apps.html "Prerendering methods and data fetching strategies in JSS Next.js apps").

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 `getStaticProps` for static generation (SG) or the `getServerSideProps` function for server-side rendering (SSR).

> [!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.

> [!important]
> Component-level data fetching is not intended to work in error pages.

## The ComponentPropsService class

The `SitecorePagePropsFactory` class uses an instance of the `ComponentPropsService` class that helps identify which components require data retrieval. The `ComponentPropsService` class is provided by the NPM package `@sitecore-jss/sitecore-jss-nextjs`.

The `ComponentPropsService` class accepts the following parameters:

- `moduleFactory` - a function that returns a Next.js component module using the `componentName` argument. The `moduleFactory` function definition is in the `src/temp/componentBuilder` file. If not present, generate it by running `scripts/bootstrap.ts`.
- `layoutData` - Layout Service data for your page.
- `context` - the Next.js SSG or SSR context.

The `ComponentPropsService` class 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 `src/temp/componentBuilder` file.

If the component defines and exports the functions `getStaticProps` or `getServerSideProps`, the `ComponentPropsService` class runs 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 by reading them from the component props context using the rendering UID.

> [!note]
> This example component contains an implementation of both `getStaticProps` and `getServerSideProps` functions. In a real component, you must define only one of them, depending on the rendering mode you choose.

```typescript
import {
  Text,
  RichText,
  Field,
  GetServerSideComponentProps,
  GetStaticComponentProps,
  withDatasourceCheck,
  useComponentProps,
} from '@sitecore-jss/sitecore-jss-nextjs';
import { ComponentParams, ComponentRendering } from '@sitecore-jss/sitecore-jss-nextjs';

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

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

type Post = {
  title: string;
  body: string;
};

const ContentBlock = (props: ContentBlockProps): JSX.Element => {
  const { fields, rendering } = props;

  // Component-level fetched data is stored by rendering.uid
  const post = useComponentProps<Post>(rendering.uid);

  return (
    <div className="contentBlock">
      <Text tag="h2" className="contentTitle" field={fields.heading} />
      <RichText className="contentDescription" field={fields.content} />

      {/* Demonstrate using fetched data returned by getStaticProps/getServerSideProps */}
      {post && (
        <section className="contentPost">
          <h3>{post.title}</h3>
          <p>{post.body}</p>
        </section>
      )}
    </div>
  );
};

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

// Note: Define only ONE of these in a real component, based on rendering mode.
export const getStaticProps: GetStaticComponentProps = async (rendering, layoutData, context) => {
  const post = await fetchPost();
  return post;
};

export const getServerSideProps: GetServerSideComponentProps = async (rendering, layoutData) => {
  const post = await fetchPost();
  return post;
};

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

```