Sitecore JSS — Hybrid data fetching — SSG and SSR together

Only Sitecore
3 min readJul 29, 2024

Very often we see a question, “how to use SSR + SSG together in JSS?”. Well, if you search then you would see a documentation like below:

link: https://doc.sitecore.com/xp/en/developers/hd/latest/sitecore-headless-development/prerendering-methods-and-data-fetching-strategies-in-jss-next-js-apps.html#incremental-static-regeneration-isr

Now, if you see the above explanation, it won’t give you much context as to “how to do the real implementation”. Let’s implement this now. I am going to give you steps that you can follow to achieve this.

Step 1: Page route

Let’s say, you are using SSG as your default data fetching. In that scenario, if you open the [[…path]].tsx, you would see the getStaticPath and getStaticProps as expected:

Now, it’s the time to take a decision which routes you want to include in your SSR fetching. Make sense, right? Let’s imagine you have a route called “livedata” like below:

You would know that in the nextjs, this route will add as soon as you create them under pages, automatically. I used a “[slug].tsx” to make sure any pages you added under “livedata/” in sitecore CM, are served throughthis page.

Step 2: Restrict the route in the middleware

This is quite important. If you already configured the path route in the step 1, you would be surprised to see that all the request is served through the default [[…path]].tsx. The reason is valid. This is called Optional Catch-all Segments

The above configuration in the middleware would make sure “livedata” will be ignored to served by the [[..path]].tsx. Great. Let’s go to the next step

Step 3: Implement the SSR

Since are all good, we can now open the [slug].tsx under “livedata” and add the SSR code we need. An example could be like below:

const SitecorePage = ({ notFound, componentProps, layoutData, headLinks }: SitecorePageProps) => {
console.log("Inside LiveData => SitecorePage", layoutData);
useEffect(() => {
handleEditorFastRefresh();
}, [])

if(notFound || !layoutData?.sitecore?.route){
return <NotFound></NotFound>
}

const isEditing = layoutData.sitecore.context.pageEditing;
const isComponentRendering = layoutData.sitecore.context.renderingType === RenderingType.Component;

return (
<ComponentPropsContext value={componentProps}>
<SitecoreContext
componentFactory={componentBuilder.getComponentFactory({ isEditing })}
layoutData={layoutData}>
{isComponentRendering ? (
<EditingComponentPlaceholder rendering={layoutData?.sitecore?.route} />
) : (
<Layout layoutData={layoutData} headLinks={headLinks} />
)}
</SitecoreContext>
</ComponentPropsContext>
)
}

export const getServerSideProps: GetServerSideProps = async (context) => {
console.log("Inside server side props: LiveData");
if (context.params) context.params.path = context.resolvedUrl;
const props = await sitecorePagePropsFactory.create(context);
return {
props,
notFound: props.notFound
}
}

export default SitecorePage;

That’s it.

Any page you can create under “home -> livedata -> ” would be served through SSR.

Other considerations

Since you are avoiding some routes to use the default SSG, it’s wise to ignore those pages in the SSG process. You can easily configure that via “sitemap-fetcher”. Example can be this:

That’s all for today.

cheers

github: https://github.com/mdarifuzzaman/jss-hybrid-rendering

youtube: https://youtu.be/-IheDd_teQg

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

Write a response