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.
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).
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.
Watch the following video for a demonstration of how component-level data fetching works in a JSS app:
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 thecomponentName
argument. ThemoduleFactory
function definition is in thesrc/temp/componentBuilder
file. If not present, generate it by runningscripts/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.
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.
import {
Text,
RichText,
Field,
GetServerSideComponentProps,
GetStaticComponentProps,
withDatasourceCheck
} 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>;
};
};
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 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);