Sitecore JSS — Hybrid data fetching — SSG and SSR together
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:

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