diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8d7d5e8214..61e01ab264 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -89,6 +89,16 @@ Our versioning strategy is as follows:
* `[templates/angular]``[templates/node-xmcloud-proxy]``[templates/node-headless-ssr-proxy]``[templates/node-headless-ssr-experience-edge]` Adjust out of box .gitignore rules
+## 22.2.0
+
+### 🛠 Breaking Change
+
+* `[templates/nextjs-xmcloud]` CloudSDK dependencies have been updated to 0.4.0 ([#1933](https://github.com/Sitecore/jss/pull/1933))
+* `[templates/nextjs-xmcloud]` `@sitecore/components` dependency has been updated to 2.0.0 ([#1933](https://github.com/Sitecore/jss/pull/1933))
+* `[templates/nextjs-xmcloud]` `lib/context` import has been removed. Values from `temp/config` can be used instead. ([#1933](https://github.com/Sitecore/jss/pull/1933))
+* `[sitecore-jss-nextjs]` `Context` import and `@sitecore-jss/sitecore-jss-nextjs/context` submodule have been removed. ([#1933](https://github.com/Sitecore/jss/pull/1933))
+
+
## 22.1.4
### 🐛 Bug Fixes
diff --git a/docs/upgrades/22.x/22.2.md b/docs/upgrades/22.x/22.2.md
new file mode 100644
index 0000000000..c135874e7c
--- /dev/null
+++ b/docs/upgrades/22.x/22.2.md
@@ -0,0 +1,129 @@
+# Nextjs - XMCloud
+
+* Update the `@sitecore/components` dependency to `~2.0.0`
+* Update the `@sitecore-cloudsdk/events` dependency to `^0.4.0`
+* Add the dependency on `@sitecore-cloudsdk/core` with version `^0.4.0`. You should now have the below dependencies present:
+```
+ "@sitecore/components": "~2.0.0",
+ "@sitecore-cloudsdk/core": "^0.4.0",
+ "@sitecore-cloudsdk/events": "^0.4.0",
+```
+* Remove the `src/lib/context` folder
+
+* Update `src/Bootstrap.tsx`:
+ * Remove the context import:
+ ```
+ import { context } from 'src/lib/context';
+ ```
+ * Add imports required for CloudSDK setup:
+ ```
+ import { CloudSDK } from '@sitecore-cloudsdk/core/browser';
+ import '@sitecore-cloudsdk/events/browser';
+ import { LayoutServicePageState } from '@sitecore-jss/sitecore-jss-nextjs';
+ ```
+ * Remove the context.init() call:
+ ```
+ context.init({
+ siteName: props.site?.name || config.sitecoreSiteName,
+ pageState: props.layoutData?.sitecore?.context?.pageState,
+ });
+ ```
+ * Replace it with CloudSDK initialization, making sure it is performed within `useEffect()` and only in normal, non-dev mode:
+ ```
+ useEffect(() => {
+ const pageState = props.layoutData?.sitecore?.context.pageState;
+ if (process.env.NODE_ENV === 'development')
+ console.debug('Browser Events SDK is not initialized in development environment');
+ else if (pageState !== LayoutServicePageState.Normal)
+ console.debug('Browser Events SDK is not initialized in edit and preview modes');
+ else {
+ CloudSDK({
+ sitecoreEdgeUrl: config.sitecoreEdgeUrl,
+ sitecoreEdgeContextId: config.sitecoreEdgeContextId,
+ siteName: props.site?.name || config.sitecoreSiteName,
+ enableBrowserCookie: true,
+ // Replace with the top level cookie domain of the website that is being integrated e.g ".example.com" and not "www.example.com"
+ cookieDomain: window.location.hostname.replace(/^www\./, ''),
+ })
+ .addEvents()
+ .initialize();
+ }
+ }, [props.site?.name]);
+ ```
+
+* Update `src/components/CDPPageView.tsx`:
+ * Remove the context import:
+ ```
+ import { context } from 'lib/context';
+ ```
+ * Add import for CloudSDK:
+ ```
+ import { pageView } from '@sitecore-cloudsdk/events/browser';
+ ```
+ * Replace the context promise code
+ ```
+ context
+ .getSDK('Events')
+ .then((Events) =>
+ Events.pageView({
+ channel: 'WEB',
+ currency: 'USD',
+ page: route.name,
+ pageVariantId,
+ language,
+ })
+ )
+ .catch((e) => console.debug(e));
+ ```
+ with a simplified `pageView` direct call:
+ ```
+ pageView({
+ channel: 'WEB',
+ currency: 'USD',
+ page: route.name,
+ pageVariantId,
+ language,
+ }).catch((e) => console.debug(e));
+ ```
+
+* Update `src/byoc/index.ts` to make sure Forms are functioning post-upgrade:
+ * Rename the file to `index.tsx`
+ * Remove the context import:
+ ```
+ import { context } from 'lib/context';
+ ```
+ * Add imports for config and CloudSDK:
+ ```
+ import React from 'react';
+ import * as Events from '@sitecore-cloudsdk/events/browser';
+ import config from 'temp/config';
+ import {
+ LayoutServicePageState,
+ SitecoreContextReactContext,
+ } from '@sitecore-jss/sitecore-jss-nextjs';
+ ```
+ * Remove the existing `FEAAS.setContextProperties()` call
+ * Add the component defintion that will hold the updated logic:
+ ```
+ const BYOCInit = (): JSX.Element | null => {
+ const sitecoreContext = React.useContext(SitecoreContextReactContext).context;
+ // Set context properties to be available within BYOC components
+ FEAAS.setContextProperties({
+ sitecoreEdgeUrl: config.sitecoreEdgeUrl,
+ sitecoreEdgeContextId: config.sitecoreEdgeContextId,
+ pageState: sitecoreContext?.pageState || LayoutServicePageState.Normal,
+ siteName: sitecoreContext?.site?.name || config.sitecoreSiteName,
+ eventsSDK: Events,
+ });
+
+ return ;
+ };
+ ```
+ * Replace the default import at the end of the file with
+ ```
+ export default BYOCInit;
+ ```
+
+* If you have any other instances of using CloudSDK in your app, follow the CloudSDK 0.4.0 upgrade guide.
+
+* Remove any other `lib/context` import, if present. If you used `context.getSDK()` method, you can now use CloudSDK method calls directly. If `context` was used to retrieve other values, consider using `temp/config` instead.
\ No newline at end of file
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/package.json b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/package.json
index c2d7a5e3aa..a2952f9d48 100644
--- a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/package.json
+++ b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/package.json
@@ -1,7 +1,8 @@
{
"dependencies": {
- "@sitecore/components": "^1.1.10",
- "@sitecore-cloudsdk/events": "^0.3.1",
+ "@sitecore/components": "~2.0.0",
+ "@sitecore-cloudsdk/core": "^0.4.0",
+ "@sitecore-cloudsdk/events": "^0.4.0",
"@sitecore-feaas/clientside": "^0.5.17"
}
}
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/Bootstrap.tsx b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/Bootstrap.tsx
index e7343b9bc3..c69834458b 100644
--- a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/Bootstrap.tsx
+++ b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/Bootstrap.tsx
@@ -1,21 +1,36 @@
+import { useEffect } from 'react';
import { SitecorePageProps } from 'lib/page-props';
-import { context } from 'src/lib/context';
+import { CloudSDK } from '@sitecore-cloudsdk/core/browser';
+import '@sitecore-cloudsdk/events/browser';
import config from 'temp/config';
+import { LayoutServicePageState } from '@sitecore-jss/sitecore-jss-nextjs';
/**
* The Bootstrap component is the entry point for performing any initialization logic
* that needs to happen early in the application's lifecycle.
*/
const Bootstrap = (props: SitecorePageProps): JSX.Element | null => {
- /**
- * Initializes the application Context and associated Software Development Kits (SDKs).
- * This function is the entry point for setting up the application's context and any SDKs that are required for its proper functioning.
- * It prepares the resources needed to interact with various services and features within the application.
- */
- context.init({
- siteName: props.site?.name || config.sitecoreSiteName,
- pageState: props.layoutData?.sitecore?.context?.pageState,
- });
+ // Browser ClientSDK init allows for page view events to be tracked
+ useEffect(() => {
+ const pageState = props.layoutData?.sitecore?.context.pageState;
+ if (process.env.NODE_ENV === 'development')
+ console.debug('Browser Events SDK is not initialized in development environment');
+ else if (pageState !== LayoutServicePageState.Normal)
+ console.debug('Browser Events SDK is not initialized in edit and preview modes');
+ else {
+ CloudSDK({
+ sitecoreEdgeUrl: config.sitecoreEdgeUrl,
+ sitecoreEdgeContextId: config.sitecoreEdgeContextId,
+ siteName: props.site?.name || config.sitecoreSiteName,
+ enableBrowserCookie: true,
+ // Replace with the top level cookie domain of the website that is being integrated e.g ".example.com" and not "www.example.com"
+ cookieDomain: window.location.hostname.replace(/^www\./, ''),
+ })
+ .addEvents()
+ .initialize();
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [props.site?.name]);
return null;
};
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/byoc/index.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/byoc/index.tsx
similarity index 57%
rename from packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/byoc/index.ts
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/byoc/index.tsx
index 3339b869b2..311324be4f 100644
--- a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/byoc/index.ts
+++ b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/byoc/index.tsx
@@ -1,26 +1,43 @@
+import React from 'react';
import * as FEAAS from '@sitecore-feaas/clientside/react';
+import * as Events from '@sitecore-cloudsdk/events/browser';
import '@sitecore/components/context';
import dynamic from 'next/dynamic';
-import { context } from 'lib/context';
+import config from 'temp/config';
+import {
+ LayoutServicePageState,
+ SitecoreContextReactContext,
+} from '@sitecore-jss/sitecore-jss-nextjs';
/**
* This is an out-of-box bundler for External components (BYOC) (see Sitecore documentation for more details)
* It enables registering components in client-only or SSR/hybrid contexts
* It's recommended to not modify this file - please add BYOC imports in corresponding index.*.ts files instead
*/
-// Set context properties to be available within BYOC components
-FEAAS.setContextProperties(context);
-
// Import your client-only components via client-bundle. Nextjs's dynamic() call will ensure they are only rendered client-side
const ClientBundle = dynamic(() => import('./index.client'), {
ssr: false,
});
-// Import your hybrid (server rendering with client hydration) components via index.hybrid.ts
-import './index.hybrid';
-
// As long as component bundle is exported and rendered on page (as an empty element), client-only BYOC components are registered and become available
// The rest of components will be regsitered in both server and client-side contexts when this module is imported into Layout
FEAAS.enableNextClientsideComponents(dynamic, ClientBundle);
-export default FEAAS.ExternalComponentBundle;
+// Import your hybrid (server rendering with client hydration) components via index.hybrid.ts
+import './index.hybrid';
+
+const BYOCInit = (): JSX.Element | null => {
+ const sitecoreContext = React.useContext(SitecoreContextReactContext).context;
+ // Set context properties to be available within BYOC components
+ FEAAS.setContextProperties({
+ sitecoreEdgeUrl: config.sitecoreEdgeUrl,
+ sitecoreEdgeContextId: config.sitecoreEdgeContextId,
+ pageState: sitecoreContext?.pageState || LayoutServicePageState.Normal,
+ siteName: sitecoreContext?.site?.name || config.sitecoreSiteName,
+ eventsSDK: Events,
+ });
+
+ return ;
+};
+
+export default BYOCInit;
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/components/CdpPageView.tsx b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/components/CdpPageView.tsx
index c02f64d33b..5ae9ac0f9d 100644
--- a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/components/CdpPageView.tsx
+++ b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/components/CdpPageView.tsx
@@ -4,8 +4,8 @@ import {
useSitecoreContext,
} from '@sitecore-jss/sitecore-jss-nextjs';
import { useEffect } from 'react';
+import { pageView } from '@sitecore-cloudsdk/events/browser';
import config from 'temp/config';
-import { context } from 'lib/context';
/**
* This is the CDP page view component.
@@ -46,19 +46,14 @@ const CdpPageView = (): JSX.Element => {
variantId as string,
scope
);
- // there are cases where Events SDK will be absent which are expected to reject
- context
- .getSDK('Events')
- .then((Events) =>
- Events.pageView({
- channel: 'WEB',
- currency: 'USD',
- page: route.name,
- pageVariantId,
- language,
- })
- )
- .catch((e) => console.debug(e));
+ // there can be cases where Events are not initialized which are expected to reject
+ pageView({
+ channel: 'WEB',
+ currency: 'USD',
+ page: route.name,
+ pageVariantId,
+ language,
+ }).catch((e) => console.debug(e));
}, [pageState, route, variantId, site]);
return <>>;
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/context/index.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/context/index.ts
deleted file mode 100644
index 4323c5ff53..0000000000
--- a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/context/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { Context } from '@sitecore-jss/sitecore-jss-nextjs/context';
-import config from 'temp/config';
-
-import Events from './sdk/events';
-
-/**
- * List of SDKs to be initialized.
- * Each SDK is defined as a module with the @type {SDK} type.
- */
-const sdks = {
- Events,
-};
-
-/**
- * Context instance that is used to initialize the application Context and associated Software Development Kits (SDKs).
- */
-export const context = new Context({
- sitecoreEdgeUrl: config.sitecoreEdgeUrl,
- sitecoreEdgeContextId: config.sitecoreEdgeContextId,
- siteName: config.sitecoreSiteName,
- sdks,
-});
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/context/sdk/events.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/context/sdk/events.ts
deleted file mode 100644
index a9faf3d12a..0000000000
--- a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/context/sdk/events.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import * as Events from '@sitecore-cloudsdk/events/browser';
-import { SDK } from '@sitecore-jss/sitecore-jss-nextjs/context';
-
-const sdkModule: SDK = {
- sdk: Events,
- init: async (props) => {
- // Events module can't be initialized on the server side
- // We also don't want to initialize it in development mode
- if (typeof window === 'undefined')
- throw 'Browser Events SDK is not initialized in server context';
- if (process.env.NODE_ENV === 'development')
- throw 'Browser Events SDK is not initialized in development environment';
-
- await Events.init({
- siteName: props.siteName,
- sitecoreEdgeUrl: props.sitecoreEdgeUrl,
- sitecoreEdgeContextId: props.sitecoreEdgeContextId,
- // Replace with the top level cookie domain of the website that is being integrated e.g ".example.com" and not "www.example.com"
- cookieDomain: window.location.hostname.replace(/^www\./, ''),
- // Cookie may be created in personalize middleware (server), but if not we should create it here
- enableBrowserCookie: true,
- });
- },
-};
-
-export default sdkModule;
diff --git a/packages/sitecore-jss-nextjs/context.d.ts b/packages/sitecore-jss-nextjs/context.d.ts
deleted file mode 100644
index 72e501678d..0000000000
--- a/packages/sitecore-jss-nextjs/context.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './types/context/index';
diff --git a/packages/sitecore-jss-nextjs/context.js b/packages/sitecore-jss-nextjs/context.js
deleted file mode 100644
index e9529d5720..0000000000
--- a/packages/sitecore-jss-nextjs/context.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('./dist/cjs/context/index');
diff --git a/packages/sitecore-jss-nextjs/package.json b/packages/sitecore-jss-nextjs/package.json
index 2a3e47b97f..4bccdec895 100644
--- a/packages/sitecore-jss-nextjs/package.json
+++ b/packages/sitecore-jss-nextjs/package.json
@@ -29,7 +29,8 @@
"url": "https://github.com/sitecore/jss/issues"
},
"devDependencies": {
- "@sitecore-cloudsdk/personalize": "^0.3.1",
+ "@sitecore-cloudsdk/core": "^0.4.0",
+ "@sitecore-cloudsdk/personalize": "^0.4.0",
"@types/chai": "^4.3.4",
"@types/chai-as-promised": "^7.1.5",
"@types/chai-string": "^1.4.2",
@@ -65,8 +66,8 @@
"typescript": "~4.9.4"
},
"peerDependencies": {
- "@sitecore-cloudsdk/events": "^0.3.1",
- "@sitecore-cloudsdk/personalize": "^0.3.1",
+ "@sitecore-cloudsdk/core": "^0.4.0",
+ "@sitecore-cloudsdk/personalize": "^0.4.0",
"next": "^14.2.7",
"react": "^18.2.0",
"react-dom": "^18.2.0"
diff --git a/packages/sitecore-jss-nextjs/src/context/context.test.ts b/packages/sitecore-jss-nextjs/src/context/context.test.ts
deleted file mode 100644
index dcade0ff67..0000000000
--- a/packages/sitecore-jss-nextjs/src/context/context.test.ts
+++ /dev/null
@@ -1,248 +0,0 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable dot-notation */
-import sinon from 'sinon';
-import { expect } from 'chai';
-import { Context } from './';
-import { LayoutServicePageState } from '@sitecore-jss/sitecore-jss-react';
-
-describe('Context', () => {
- const sdks = {
- Foo: {
- sdk: { foo: true },
- init: () =>
- new Promise((resolve) => {
- setTimeout(() => {
- resolve();
- }, 300);
- }),
- },
- Bar: {
- sdk: { bar: true },
- init: () => {
- return new Promise((resolve) => {
- setTimeout(() => {
- resolve();
- }, 500);
- });
- },
- },
- };
-
- const errorSdk = {
- Error: {
- sdk: { error: 'yes' },
- init: () => {
- return new Promise((_, reject) => {
- reject('Cannot init Error');
- });
- },
- },
- };
-
- const fooInitSpy = sinon.spy(sdks.Foo, 'init');
- const barInitSpy = sinon.spy(sdks.Bar, 'init');
-
- const props = {
- sitecoreEdgeUrl: 'https://edgeurl',
- sitecoreEdgeContextId: 'contextid',
- siteName: '',
- sdks,
- };
-
- afterEach(() => {
- fooInitSpy.resetHistory();
- barInitSpy.resetHistory();
- });
-
- describe('constructor', () => {
- it('should create a new context', () => {
- const context = new Context(props);
-
- expect(context.sitecoreEdgeUrl).to.equal(props.sitecoreEdgeUrl);
- expect(context.sitecoreEdgeContextId).to.equal(props.sitecoreEdgeContextId);
- expect(context.siteName).to.equal(props.siteName);
- });
-
- it('should provide all the properties when context instance is merged as an object', () => {
- const context = new Context(props);
-
- const merged = { ...context };
-
- expect(merged.sitecoreEdgeUrl).to.equal(props.sitecoreEdgeUrl);
- expect(merged.sitecoreEdgeContextId).to.equal(props.sitecoreEdgeContextId);
- expect(merged.siteName).to.equal(props.siteName);
- expect(merged.getSDK).to.equal(context.getSDK);
- expect(merged.isInitialized).to.equal(context.isInitialized);
- });
- });
-
- describe('init', () => {
- it('should initialize the context', (done) => {
- const context = new Context(props);
-
- context.init();
-
- expect(context.isInitialized).to.be.true;
- expect(context.siteName).to.equal(props.siteName);
-
- expect(context.sdks.Bar).to.equal(undefined);
- expect(context.sdks.Foo).to.equal(undefined);
-
- Promise.all([
- context.getSDK('Foo').then((sdk) => {
- expect(fooInitSpy.calledOnce).to.be.true;
- expect(sdk).to.deep.equal(sdks.Foo.sdk);
-
- return;
- }),
- context.getSDK('Bar').then((sdk) => {
- expect(barInitSpy.calledOnce).to.be.true;
- expect(sdk).to.deep.equal(sdks.Bar.sdk);
-
- return;
- }),
- ]).then(() => {
- expect(context.sdks.Foo).to.deep.equal(sdks.Foo.sdk);
- expect(context.sdks.Bar).to.deep.equal(sdks.Bar.sdk);
-
- done();
- });
- });
-
- it('should use normal pageMode when context is initialized with empty props', () => {
- const context = new Context(props);
-
- context.init();
-
- expect(context.isInitialized).to.be.true;
- expect(context.pageState).to.equal(LayoutServicePageState.Normal);
- });
-
- it('should initialize the context with a different site name', (done) => {
- const context = new Context(props);
-
- context.init({ siteName: 'website' });
-
- expect(context.isInitialized).to.be.true;
- expect(context.siteName).to.equal('website');
-
- expect(context.sdks.Bar).to.equal(undefined);
- expect(context.sdks.Foo).to.equal(undefined);
-
- Promise.all([
- context.getSDK('Foo').then((sdk) => {
- expect(fooInitSpy.calledOnce).to.be.true;
- expect(sdk).to.deep.equal(sdks.Foo.sdk);
-
- return;
- }),
- context.getSDK('Bar').then((sdk) => {
- expect(barInitSpy.calledOnce).to.be.true;
- expect(sdk).to.deep.equal(sdks.Bar.sdk);
-
- return;
- }),
- ]).then(() => {
- expect(context.sdks.Foo).to.deep.equal(sdks.Foo.sdk);
- expect(context.sdks.Bar).to.deep.equal(sdks.Bar.sdk);
-
- done();
- });
- });
-
- it('should initialize the context with a different page mode', () => {
- const context = new Context(props);
-
- context.init({ pageState: LayoutServicePageState.Edit });
-
- expect(context.isInitialized).to.be.true;
- expect(context.pageState).to.equal(LayoutServicePageState.Edit);
- });
-
- it('should not initialize the context if it is already initialized', () => {
- const context = new Context(props);
-
- context.init({ siteName: 'website-1' });
-
- expect(context.isInitialized).to.be.true;
-
- context.init({ siteName: 'website-2' });
-
- expect(context.siteName).to.equal('website-1');
- });
-
- it('should not fail context init when an SDK init throws', (done) => {
- const localProps = { ...props, sdks: errorSdk };
- const context = new Context(localProps);
- try {
- context.init();
- } catch (e) {
- done(e);
- } finally {
- done();
- }
- });
-
- it('should reject when getting SDK that rejected initialization', (done) => {
- const localProps = { ...props, sdks: errorSdk };
- const context = new Context(localProps);
- context.init();
- context
- .getSDK('Error')
- .then(() => {
- done('should not resolve');
- })
- .catch((e) => {
- expect(e).to.be.equal('Cannot init Error');
- done();
- });
- });
- });
-
- describe('getSDK', () => {
- it('should return the SDKs', (done) => {
- const context = new Context(props);
-
- context.init();
-
- expect(context.sdks.Bar).to.equal(undefined);
- expect(context.sdks.Foo).to.equal(undefined);
-
- Promise.all([
- context.getSDK('Foo').then((sdk) => {
- expect(fooInitSpy.calledOnce).to.be.true;
- expect(sdk).to.deep.equal(sdks.Foo.sdk);
-
- return;
- }),
- context.getSDK('Bar').then((sdk) => {
- expect(barInitSpy.calledOnce).to.be.true;
- expect(sdk).to.deep.equal(sdks.Bar.sdk);
-
- return;
- }),
- ]).then(() => {
- expect(context.sdks.Foo).to.deep.equal(sdks.Foo.sdk);
- expect(context.sdks.Bar).to.deep.equal(sdks.Bar.sdk);
-
- done();
- });
- });
-
- it('should reject unknown SDK', async () => {
- const context = new Context(props);
- const sdk = 'Baz';
-
- context.init();
-
- return context
- .getSDK(sdk)
- .then(() => {
- throw new Error('should not resolve');
- })
- .catch((e) => {
- expect(e).to.equal(`Unknown SDK '${sdk}'`);
- });
- });
- });
-});
diff --git a/packages/sitecore-jss-nextjs/src/context/context.ts b/packages/sitecore-jss-nextjs/src/context/context.ts
deleted file mode 100644
index 3e020395d2..0000000000
--- a/packages/sitecore-jss-nextjs/src/context/context.ts
+++ /dev/null
@@ -1,164 +0,0 @@
-import { LayoutServicePageState } from '@sitecore-jss/sitecore-jss-react';
-
-/**
- * Software Development Kit (SDK) instance
- */
-export type SDK = {
- /**
- * The Software Development Kit (SDK) library instance
- */
- sdk: SDKType;
- /**
- * Initializes the Software Development Kit (SDK)
- */
- init: (props: InitSDKProps) => Promise;
-};
-
-/**
- * Software Development Kits (SDKs) to be initialized
- */
-type SDKModulesType = Record;
-
-/**
- * Properties that are passed to the Context.
- */
-export interface ContextInitProps {
- /**
- * Your Sitecore site name
- */
- siteName?: string;
- /**
- * Sitecore page state (normal, preview, edit)
- */
- pageState?: LayoutServicePageState;
-}
-
-/**
- * Configuration that is passed to the Context.
- */
-export interface ContextConfig {
- /**
- * Your Sitecore Edge URL
- */
- sitecoreEdgeUrl: string;
- /**
- * Your Sitecore Edge Context ID
- */
- sitecoreEdgeContextId: string;
- /**
- * Your Sitecore site name
- */
- siteName: string;
- /**
- * Software Development Kits (SDKs) to be initialized
- */
- sdks: { [module in keyof SDKModules]: SDKModules[module] };
-}
-
-/**
- * Properties that are passed to the Software Development Kit (SDK) initialization function.
- */
-type InitSDKProps = Omit, 'sdks'>;
-
-/**
- * Context instance that is used to initialize the application Context and associated Software Development Kits (SDKs).
- */
-export class Context {
- /**
- * Indicates whether the Context and SDK(s) have been initialized
- */
- public isInitialized = false;
- /**
- * The Sitecore Edge URL
- */
- public readonly sitecoreEdgeUrl: string;
- /**
- * The Sitecore Edge Context ID
- */
- public readonly sitecoreEdgeContextId: string;
- /**
- * The Sitecore site name
- */
- public siteName: string;
- /**
- * Sitecore page state (normal, preview, edit)
- */
- public pageState: LayoutServicePageState;
- /**
- * Software Development Kits (SDKs) to be initialized
- */
- public readonly sdks: { [module in keyof SDKModules]?: SDKModules[module]['sdk'] } = {};
- /**
- * Promises for the SDKs
- */
- protected sdkPromises: { [module in keyof SDKModules]?: Promise } = {};
-
- protected sdkErrors: { [module in keyof SDKModules]?: string } = {};
-
- constructor(protected props: ContextConfig) {
- this.sitecoreEdgeUrl = props.sitecoreEdgeUrl;
- this.sitecoreEdgeContextId = props.sitecoreEdgeContextId;
- this.siteName = props.siteName;
- this.pageState = LayoutServicePageState.Normal;
- }
-
- public init(props: ContextInitProps = {}) {
- // Context and SDKs are initialized only once
- if (this.isInitialized) return;
-
- this.isInitialized = true;
-
- if (props.siteName) {
- this.siteName = props.siteName;
- }
-
- if (props.pageState) {
- this.pageState = props.pageState;
- }
-
- // iterate over the SDKs and initialize them
- for (const sdkName of Object.keys(this.props.sdks) as (keyof SDKModules)[]) {
- this.initSDK(sdkName);
- }
- }
-
- /**
- * Retrieves the Software Development Kit (SDK) instance, ensuring it is initialized before returning
- *
- * @param {string} name SDK name
- * @returns initialized SDK
- */
- public getSDK = (name: T): Promise => {
- if (!this.sdkPromises[name]) {
- return Promise.reject(`Unknown SDK '${String(name)}'`);
- } else {
- return this.sdkPromises[name]!.then((result) => {
- return (
- (this.sdkErrors[name] && Promise.reject(this.sdkErrors[name])) || Promise.resolve(result)
- );
- });
- }
- };
-
- /**
- * Initializes the Software Development Kit (SDK)
- *
- * @param {T} name SDK name
- * @returns {void}
- */
- protected initSDK(name: T): void {
- this.sdkPromises[name] = new Promise((resolve) => {
- this.props.sdks[name]
- .init(this)
- .then(() => {
- this.sdks[name] = this.props.sdks[name].sdk;
- resolve(this.sdks[name]);
- })
- .catch((e) => {
- // if init rejects, we mark SDK as failed - so getSDK call would reject with a reason
- this.sdkErrors[name] = e;
- resolve(undefined);
- });
- });
- }
-}
diff --git a/packages/sitecore-jss-nextjs/src/context/index.ts b/packages/sitecore-jss-nextjs/src/context/index.ts
deleted file mode 100644
index b7719c3c1b..0000000000
--- a/packages/sitecore-jss-nextjs/src/context/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { Context, ContextConfig, SDK } from './context';
diff --git a/packages/sitecore-jss-nextjs/src/index.ts b/packages/sitecore-jss-nextjs/src/index.ts
index 82dc99b4c0..a3bb4beee6 100644
--- a/packages/sitecore-jss-nextjs/src/index.ts
+++ b/packages/sitecore-jss-nextjs/src/index.ts
@@ -128,8 +128,6 @@ export { BYOCWrapper };
export { ComponentBuilder, ComponentBuilderConfig } from './ComponentBuilder';
-export { Context, ContextConfig, SDK } from './context';
-
export {
ComponentFactory,
Image,
diff --git a/packages/sitecore-jss-nextjs/src/middleware/personalize-middleware.ts b/packages/sitecore-jss-nextjs/src/middleware/personalize-middleware.ts
index c6977d43e7..3748eb7169 100644
--- a/packages/sitecore-jss-nextjs/src/middleware/personalize-middleware.ts
+++ b/packages/sitecore-jss-nextjs/src/middleware/personalize-middleware.ts
@@ -9,7 +9,8 @@ import {
} from '@sitecore-jss/sitecore-jss/personalize';
import { debug } from '@sitecore-jss/sitecore-jss';
import { MiddlewareBase, MiddlewareBaseConfig } from './middleware';
-import { init, personalize } from '@sitecore-cloudsdk/personalize/server';
+import { CloudSDK } from '@sitecore-cloudsdk/core/server';
+import { personalize } from '@sitecore-cloudsdk/personalize/server';
export type CdpServiceConfig = {
/**
@@ -119,13 +120,15 @@ export class PersonalizeMiddleware extends MiddlewareBase {
request: NextRequest;
response: NextResponse;
}): Promise {
- await init(request, response, {
+ await CloudSDK(request, response, {
sitecoreEdgeUrl: this.config.cdpConfig.sitecoreEdgeUrl,
sitecoreEdgeContextId: this.config.cdpConfig.sitecoreEdgeContextId,
siteName,
cookieDomain: hostname,
enableServerCookie: true,
- });
+ })
+ .addPersonalize()
+ .initialize();
}
protected async personalize(
diff --git a/yarn.lock b/yarn.lock
index 17d339ab44..257f31f85a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5997,30 +5997,41 @@ __metadata:
languageName: node
linkType: hard
-"@sitecore-cloudsdk/core@npm:^0.3.1":
- version: 0.3.1
- resolution: "@sitecore-cloudsdk/core@npm:0.3.1"
+"@sitecore-cloudsdk/core@npm:^0.4.0":
+ version: 0.4.0
+ resolution: "@sitecore-cloudsdk/core@npm:0.4.0"
dependencies:
- "@sitecore-cloudsdk/utils": ^0.3.1
+ "@sitecore-cloudsdk/utils": ^0.4.0
debug: ^4.3.4
- checksum: c19d750b1c194f7575d20b3d46739d7b41545087a9fb794ba44ab9b2d812f2b2035caf19c4f4ba51e6ff628c99f2e4a18b0a7a2578b413c7adb04f3d77f392a3
+ checksum: 0640147f4767c6d84f90bbefe011fcc76d2fb47adc078f5017f7c2d686c7eff53a661cd77c4b70315c06b2be0b071c8d279a0db3502bcf5e6e288d1a36dd8896
languageName: node
linkType: hard
-"@sitecore-cloudsdk/personalize@npm:^0.3.1":
- version: 0.3.1
- resolution: "@sitecore-cloudsdk/personalize@npm:0.3.1"
+"@sitecore-cloudsdk/events@npm:^0.4.0":
+ version: 0.4.0
+ resolution: "@sitecore-cloudsdk/events@npm:0.4.0"
dependencies:
- "@sitecore-cloudsdk/core": ^0.3.1
- "@sitecore-cloudsdk/utils": ^0.3.1
- checksum: e48b1429f67be22069bfd8cc6349660ed346877fef5537def5f36c962fd2264969ff02fb2e16333dabc683c4dd0373ae12ce56b97a6850910ab618957b9586d9
+ "@sitecore-cloudsdk/core": ^0.4.0
+ "@sitecore-cloudsdk/utils": ^0.4.0
+ checksum: 0e36c44b4bfd23e71b46f20d9ef852e8a948da3ff9f037e37b8a68f4c36220f48d44c2a032979855a5945ed0b100272f7a477ea1f7fdc6b77eab4a32a1d22657
languageName: node
linkType: hard
-"@sitecore-cloudsdk/utils@npm:^0.3.1":
- version: 0.3.1
- resolution: "@sitecore-cloudsdk/utils@npm:0.3.1"
- checksum: c6578ec04823a77aaf7cb6f9cdb842c227698507c38b722db0b9fe1c6b21ee169443cc6b9b8ca77f86c9a4dfc835e1c3b85369079c70ef88e555c8243275d9a6
+"@sitecore-cloudsdk/personalize@npm:^0.4.0":
+ version: 0.4.0
+ resolution: "@sitecore-cloudsdk/personalize@npm:0.4.0"
+ dependencies:
+ "@sitecore-cloudsdk/core": ^0.4.0
+ "@sitecore-cloudsdk/events": ^0.4.0
+ "@sitecore-cloudsdk/utils": ^0.4.0
+ checksum: 62668f95a111c1b25668c20fc7cf0bf1958b3aefaf2b9c6cdb79179de4e508b7b466e25654f8efcaefdbffd86a715f210e76f2fda964650f601b0fc9e0579893
+ languageName: node
+ linkType: hard
+
+"@sitecore-cloudsdk/utils@npm:^0.4.0":
+ version: 0.4.0
+ resolution: "@sitecore-cloudsdk/utils@npm:0.4.0"
+ checksum: ec5a0611ad4d6ae4b3c2a7542c2021f0b956d2c78e08cab1ff8bd5e6300c3059d5fff6022d0ed2462cd0b4f127d02b5bfabf34e890cddbb51876aebaca3033dc
languageName: node
linkType: hard
@@ -6213,7 +6224,8 @@ __metadata:
version: 0.0.0-use.local
resolution: "@sitecore-jss/sitecore-jss-nextjs@workspace:packages/sitecore-jss-nextjs"
dependencies:
- "@sitecore-cloudsdk/personalize": ^0.3.1
+ "@sitecore-cloudsdk/core": ^0.4.0
+ "@sitecore-cloudsdk/personalize": ^0.4.0
"@sitecore-jss/sitecore-jss": 22.2.0-canary.80
"@sitecore-jss/sitecore-jss-dev-tools": 22.2.0-canary.80
"@sitecore-jss/sitecore-jss-react": 22.2.0-canary.80
@@ -6255,8 +6267,8 @@ __metadata:
ts-node: ^10.9.1
typescript: ~4.9.4
peerDependencies:
- "@sitecore-cloudsdk/events": ^0.3.1
- "@sitecore-cloudsdk/personalize": ^0.3.1
+ "@sitecore-cloudsdk/core": ^0.4.0
+ "@sitecore-cloudsdk/personalize": ^0.4.0
next: ^14.2.7
react: ^18.2.0
react-dom: ^18.2.0