Continuing our exploration of Sitecore Personalize integrations, today let’s dive into a key implementation for modern websites i.e. integration of Sitecore Personalize with a Next.js website using the Sitecore Engage SDK.
As I shared in my previous blog posts, there are multiple ways to integrate Sitecore Personalize into your applications. However, when working with Next.js the optimal approach is leveraging the Sitecore Engage SDK. I will share the step by step process in this blog post.

Sitecore Engage SDK
Sitecore Engage SDK empowers developers with granular control over personalization logic, enabling seamless integration with Next.js’s server-side rendering (SSR) and client-side interactivity. Whether you’re building dynamic user segments, A/B testing campaigns, or real-time content targeting, this method ensures your personalization strategy aligns perfectly with Next.js’s capabilities.
Things Needed for Integration
- Access to Sitecore Personalize (prod or nonprod).
- Client Key Can be found in Sitecore Personalize.
- Point of Sale (POS) created in Sitecore Personalize.
Please check this blog post if you do not know how to get these values from Sitecore Personalize.
Integration Steps with Next.js
Please follow the steps below for integration
- Install the Engage SDK by running the following command, you can run it in Powershell after navigating to your solution folder where package.json file is located or you can use Visual Studio Code and run it in the Terminal Tab
npm install @sitecore/engage
- Once the install command finishes, you will see a change to your package.json file with latest engage SDK version included in it
"@sitecore/engage": "^1.4.3"
- Create a new folder under /src/lib called personalize then create three files. Source code for these is shared below
– load-engage.ts
– engage.ts
– engage-events.ts - The last step is to call the load engage method in your DefaultLayout.tsx file so that it loads on each page load. Source code is shared below
useEngage();
- The
useEngage
method also triggers the page view event which should be triggered on each page load.
load-engage.ts
import { Engage, init } from '@sitecore/engage';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let engage: Engage | null = null;
export const loadEngage = async (): Promise<void> => {
engage = await init({
clientKey: process.env.NEXT_PUBLIC_SITECORE_PERSONALIZE_CLIENT_KEY || '',
targetURL: 'https://api-engage-us.sitecorecloud.io',
pointOfSale: process.env.NEXT_PUBLIC_SITECORE_PERSONALIZE_POS || '',
cookieDomain: process.env.NEXT_PUBLIC_SITECORE_PERSONALIZE_COOKIE_DOMAIN || '',
cookieExpiryDays: 365,
forceServerCookieMode: false,
includeUTMParameters: true,
webPersonalization: true,
});
};
export { engage };
Link to file on GitHub: https://github.com/zaheer-tariq/Sitecore-Blog-Gists/blob/main/NextJs/src/lib/personalize/load-engage.ts
engage.ts
import { useEffect } from 'react';
import { useRouter } from 'next/router';
import { engage, loadEngage } from 'lib/personalize/load-engage';
import { engageSendPageViewEvent } from 'lib/personalize/engage-events';
const useEngage = (): void => {
const router = useRouter();
useEffect(() => {
const initializeEngage = async (): Promise<void> => {
try {
await loadEngage(); // Ensure Engage is loaded
if (engage) {
engageSendPageViewEvent();
} else {
console.error('Engage is still not initialized');
}
} catch (error) {
console.error('Error initializing Engage:', error);
}
};
initializeEngage();
}, [router.asPath]);
};
export default useEngage;
Link to file on GitHub: https://github.com/zaheer-tariq/Sitecore-Blog-Gists/blob/main/NextJs/src/lib/personalize/engage.ts
engage-events.ts
import { engage } from 'lib/personalize/load-engage';
import { getCookie } from 'cookies-next';
const channel = 'Web';
const pos = process.env.NEXT_PUBLIC_SITECORE_PERSONALIZE_POS || '';
export const engageSendPageViewEvent = async (): Promise<void> => {
if (!engage) return;
try {
const language = (getCookie('LOCALE') as string) || 'en';
const currency = (getCookie('currency') as string) || 'USD';
await engage.pageView({
channel: channel,
language: language,
currency: currency,
page: window.location.pathname,
});
} catch (error) {
console.error('Error sending personalize page view event:', error);
}
};
Link to file on GitHub: https://github.com/zaheer-tariq/Sitecore-Blog-Gists/blob/main/NextJs/src/lib/personalize/engage-events.ts
DefaultLayout.tsx
import React, { useEffect, useState } from 'react';
import Head from 'next/head';
import { Placeholder, LayoutServiceData, Field } from '@sitecore-jss/sitecore-jss-nextjs';
import useEngage from 'lib/personalize/engage';
interface DefaultLayoutProps {
layoutData: LayoutServiceData;
}
const DefaultLayout = ({ layoutData }: DefaultLayoutProps): JSX.Element => {
useEngage();
return (
<>
<Head>
<title>Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charSet="UTF-8" />
</Head>
<body>
<div className="container mx-auto px-4 py-8">
<Placeholder name="jss-main" rendering={layoutData} />
</div>
</body>
</>
);
};
export default DefaultLayout;
Link to file on GitHub: https://github.com/zaheer-tariq/Sitecore-Blog-Gists/blob/main/NextJs/src/rendering/src/layouts/DefaultLayout.tsx
Run and Test
After adding the above code to your application, its time to run and test it. You should be able to see page view events flowing to Sitecore personalize. Check this blog post for some debugging tips and known issues.
Happy coding! Let me know in comments if you face issues.
Hashtags:
#Sitecore #SitecorePersonalize #EngageSDK #WebDevelopment #Nextjs #DeveloperGuide #TechTutorial #DigitalExperience #WebDev #Personalization #TechTips