Upgrading to Sitecore Headless Services Next.js Version 21.2.*: A Step-by-Step Guide
Recently, I upgraded the XM Cloud SUGCON North America Next.js site to the Sitecore Headless Services version 21.2.2. Previously, we were on version 21.1.1 and upgraded to 21.2.2. This article documents the changes required because version 21.2.0 introduces breaking changes for Next.js applications.
The new version of Sitecore JSS for Next.js introduced breaking changes to add a better distinction between JSS libraries and Next.js official libraries. Follow along to see the process for upgrading the sitecore-jss-nextjs
package to version 21.2.*.
Reason for upgrading to version 21.2.*
My biggest reason for upgrading was that the Next.js package version 21.2.* supports rendering components built in XM Cloud Component Builder as React Server Components. For the earlier version, components built in the Component Builder will render client-side, but I wanted to take advantage of the server-side rendering, so I upgraded my Next.js JSS version.
To learn more about XM Cloud Component Builder, check out my video: Building Your First Component in XM Cloud Component Builder
Step One: Upgrade your package.json file
The first step is upgrading your package.json
dependencies to be on the version of sitecore-jss-nextjs
you want.
1"@sitecore-jss/sitecore-jss-nextjs": "^21.2.2", 2"@sitecore-jss/sitecore-jss-cli": "^21.2.2",
You will want to ensure your Next.js and CLI packages are upgraded. Here is a link to the full package.json
file used in the SUGCON NA site. If you have a version
property in your package.json
, you can also update that. It only affects logging.
Run npm install
from the terminal in the directory that your package.json
lives in to install the new versions. Once the npm install
finishes, running npm run build
will break, so the following steps are to fix the build.
Step 2: Fix the component-props.ts file
The argument structure for fetchServerSideComponentProps
and fetchStaticComponentProps
have changed, so we need to make changes inside of src/lib/page-props-factory/plugins/component-props.ts
to reflect those changes. The exec
method now looks like the code below. Notice the explicit setting of moduleFactory
on lines 10 and 16.
1// src/lib/page-props-factory/plugins/component-props.ts 2async exec(props: SitecorePageProps, context: GetServerSidePropsContext | GetStaticPropsContext) { 3 if (!props.layoutData.sitecore.route) return props; 4 5 // Retrieve component props using side-effects defined on components level 6 if (isServerSidePropsContext(context)) { 7 props.componentProps = await this.componentPropsService.fetchServerSideComponentProps({ 8 layoutData: props.layoutData, 9 context, 10 moduleFactory: componentModule, 11 }); 12 } else { 13 props.componentProps = await this.componentPropsService.fetchStaticComponentProps({ 14 layoutData: props.layoutData, 15 context, 16 moduleFactory: componentModule, 17 }); 18 } 19 20 return props; 21 }
Step Three: Changed Import Locations
Multiple import locations have moved. The JSS team made changes to clarify the JSS packages and what comes as an official Next.js package.
The SiteInfo
and SiteResolver
imports have moved.
1// Old Import 2import { SiteInfo, SiteResolver } from '@sitecore-jss/sitecore-jss-nextjs/middleware' 3 4// New Import 5import { SiteInfo, SiteResolver } from '@sitecore-jss/sitecore-jss-nextjs'
The tryParseEnvValue
import has moved as well.
1// Old Import 2import { tryParseEnvValue } from '@sitecore-jss/sitecore-jss-nextjs/middleware'; 3 4// New Import 5import { tryParseEnvValue } from '@sitecore-jss/sitecore-jss-nextjs/utils';
Also, the imports for the following have all been deprecated and should be changed:
isEditorActive
resetEditorChromes
resolveUrl
handleEditorFastRefresh
getPublicUrl
The above exports should now import from @sitecore-jss/sitecore-jss-nextjs/utils
. Search for your application and ensure you update the imports for all these.
Step Four: Update or Create the FEaaSWrapper.tsx
The FEaaSWrapper.tsx
is the SXA component that wraps components built in XM Cloud Component Builder with React Server Components so they can be rendered server-side.
Either update or create this component in src/components/FEaaSWrapper.tsx
with the complete code below.
1import { GetServerSideComponentProps, GetStaticComponentProps, FEaaSComponent, FEaaSComponentProps, FEaaSComponentParams,fetchFEaaSComponentServerProps,constants} from '@sitecore-jss/sitecore-jss-nextjs'; 2import React from 'react'; 3 4export const Default = (props: FEaaSComponentProps): JSX.Element => { 5 const styles = `component feaas ${props.params?.styles}`.trimEnd(); 6 const id = props.params?.RenderingIdentifier; 7 return ( 8 <div className={styles} id={id ? id : undefined}> 9 <div className="component-content"> 10 <FEaaSComponent {...props} /> 11 </div> 12 </div> 13 ); 14}; 15 16/** 17 * Will be called during SSG 18 * @param {ComponentRendering} rendering 19 * @param {LayoutServiceData} layoutData 20 * @param {GetStaticPropsContext} context 21 */ 22export const getStaticProps: GetStaticComponentProps = async (rendering, layoutData) => { 23 if (process.env.JSS_MODE === constants.JSS_MODE.DISCONNECTED) { 24 return null; 25 } 26 const params: FEaaSComponentParams = rendering.params || {}; 27 const result = await fetchFEaaSComponentServerProps( 28 params, 29 layoutData.sitecore.context.pageState 30 ); 31 return result; 32}; 33 34/** 35 * Will be called during SSR 36 * @param {ComponentRendering} rendering 37 * @param {LayoutServiceData} layoutData 38 * @param {GetStaticPropsContext} context 39 */ 40export const getServerSideProps: GetServerSideComponentProps = async (rendering, layoutData) => { 41 if (process.env.JSS_MODE === constants.JSS_MODE.DISCONNECTED) { 42 return null; 43 } 44 const params: FEaaSComponentParams = rendering.params || {}; 45 const result = await fetchFEaaSComponentServerProps( 46 params, 47 layoutData.sitecore.context.pageState 48 ); 49 return result; 50};
Step Five: Verify your work
Now it’s time to verify your work, and fingers crossed 🤞, your application builds successfully. Run the npm run build
command in your root project directory and confirm a successful build.
If you upgraded to JSS 21.2.* for the server-side rendering benefits of XM Cloud Components, you can verify that those work. Start your app with npm run dev
and confirm that the request coming back from the server contains your fully rendered HTML. You should not see <feass-component>
components coming from the server. Those should now be rendered out server-side.
Closing
You’ve done it! You upgraded the sitecore-jss-nextjs
package to version 21.2.*! You are ready to take full advantage and get the most benefit from XM Cloud Component Builder.