From 08f9696e59550f10d4f2483199ce4e6ebb77d79a Mon Sep 17 00:00:00 2001 From: yavorsk Date: Wed, 30 Oct 2024 12:44:47 +0200 Subject: [PATCH 1/4] modify cloudsk init component to not initialize cloudsk if in edit or preview mode or missing route data --- .../scripts/cloud-sdk-init.component.ts | 53 +++++++++++++------ 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/packages/create-sitecore-jss/src/templates/angular-xmcloud/src/app/routing/scripts/cloud-sdk-init.component.ts b/packages/create-sitecore-jss/src/templates/angular-xmcloud/src/app/routing/scripts/cloud-sdk-init.component.ts index 9801861595..6543234566 100644 --- a/packages/create-sitecore-jss/src/templates/angular-xmcloud/src/app/routing/scripts/cloud-sdk-init.component.ts +++ b/packages/create-sitecore-jss/src/templates/angular-xmcloud/src/app/routing/scripts/cloud-sdk-init.component.ts @@ -1,8 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Subscription } from 'rxjs'; import { CloudSDK } from '@sitecore-cloudsdk/core/browser'; import '@sitecore-cloudsdk/events/browser'; +import { isServer, LayoutServicePageState } from '@sitecore-jss/sitecore-jss-angular'; import { environment } from '../../../environments/environment'; -import { isServer } from '@sitecore-jss/sitecore-jss-angular'; +import { JssContextService } from '../../jss-context.service'; +import { JssState } from '../../JssState'; /** * Component to init CloudSDK logic - to allow events throughout the site @@ -11,22 +14,42 @@ import { isServer } from '@sitecore-jss/sitecore-jss-angular'; selector: 'app-cloud-sdk-init', template: '', }) -export class CloudSdkInitComponent implements OnInit { - constructor() {} +export class CloudSdkInitComponent implements OnInit, OnDestroy { + private contextSubscription: Subscription; + + constructor(private jssContext: JssContextService) {} ngOnInit(): void { if (!isServer() && environment.production) { - CloudSDK({ - siteName: environment.sitecoreSiteName, - sitecoreEdgeUrl: environment.sitecoreEdgeUrl, - sitecoreEdgeContextId: environment.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, - }) - .addEvents() - .initialize(); + this.contextSubscription = this.jssContext.state.subscribe((newState: JssState) => { + const { + route, + context: { pageState }, + } = newState.sitecore; + + // Do not initialize CloudSDK in editing or preview mode or if missing route data + if (pageState !== LayoutServicePageState.Normal || !route?.itemId) { + return; + } + + CloudSDK({ + siteName: environment.sitecoreSiteName, + sitecoreEdgeUrl: environment.sitecoreEdgeUrl, + sitecoreEdgeContextId: environment.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, + }) + .addEvents() + .initialize(); + }); + } + } + + ngOnDestroy() { + if (this.contextSubscription) { + this.contextSubscription.unsubscribe(); } } } From f5d8eceda27491b51dcc3d9df19de5ae9e587cf5 Mon Sep 17 00:00:00 2001 From: yavorsk Date: Wed, 30 Oct 2024 12:48:59 +0200 Subject: [PATCH 2/4] changelog update --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 582ba0a68f..8d7d5e8214 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,7 +72,7 @@ Our versioning strategy is as follows: * `[template/node-xmcloud-proxy]` `[sitecore-jss-proxy]` Introduced /api/healthz endpoint ([#1928](https://github.com/Sitecore/jss/pull/1928)) * `[sitecore-jss]` `[sitecore-jss-angular]` Render field metdata chromes in editMode metadata - in edit mode metadata in Pages, angular package field directives will render wrapping `code` elements with field metadata required for editing; ([#1926](https://github.com/Sitecore/jss/pull/1926)) * `[angular-xmcloud]``[sitecore-jss-angular]` Analytics and CloudSDK integration - * `[angular-xmcloud]` Add CloudSDK initialization on client side ([#1952](https://github.com/Sitecore/jss/pull/1952))([#1957](https://github.com/Sitecore/jss/pull/1957)) + * `[angular-xmcloud]` Add CloudSDK initialization on client side ([#1952](https://github.com/Sitecore/jss/pull/1952))([#1957](https://github.com/Sitecore/jss/pull/1957))([#1961](https://github.com/Sitecore/jss/pull/1961)) * `[angular-xmcloud]``[sitecore-jss-angular]` Add CDP Page View component to Angular XM Cloud add-on ([#1957](https://github.com/Sitecore/jss/pull/1957)) From 770bfd8e69b5ea1180e4830c66a8537ccab555c6 Mon Sep 17 00:00:00 2001 From: yavorsk Date: Wed, 30 Oct 2024 15:00:45 +0200 Subject: [PATCH 3/4] update migration entry for csdk initialization --- docs/upgrades/unreleased.md | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/docs/upgrades/unreleased.md b/docs/upgrades/unreleased.md index 1ba6496bf1..c3297832b2 100644 --- a/docs/upgrades/unreleased.md +++ b/docs/upgrades/unreleased.md @@ -299,18 +299,32 @@ If you plan to use the Angular SDK with XMCloud, you will need to perform next s import '@sitecore-cloudsdk/events/browser'; import { environment } from '../../../environments/environment'; import { isServer } from '@sitecore-jss/sitecore-jss-angular'; + import { JssContextService } from '../../jss-context.service'; + import { JssState } from '../../JssState'; ... ngOnInit(): void { if (!isServer() && environment.production) { - CloudSDK({ - siteName: environment.sitecoreSiteName, - sitecoreEdgeUrl: environment.sitecoreEdgeUrl, - sitecoreEdgeContextId: environment.sitecoreEdgeContextId, - cookieDomain: window.location.hostname.replace(/^www\./, ''), - enableBrowserCookie: true, - }) - .addEvents() - .initialize(); + this.contextSubscription = this.jssContext.state.subscribe((newState: JssState) => { + const { + route, + context: { pageState }, + } = newState.sitecore; + + // Do not initialize CloudSDK in editing or preview mode or if missing route data + if (pageState !== LayoutServicePageState.Normal || !route?.itemId) { + return; + } + + CloudSDK({ + siteName: environment.sitecoreSiteName, + sitecoreEdgeUrl: environment.sitecoreEdgeUrl, + sitecoreEdgeContextId: environment.sitecoreEdgeContextId, + cookieDomain: window.location.hostname.replace(/^www\./, ''), + enableBrowserCookie: true, + }) + .addEvents() + .initialize(); + }); } } ``` From 03bf2685f2574002473c32d74fa6a471295b6c06 Mon Sep 17 00:00:00 2001 From: yavorsk Date: Wed, 30 Oct 2024 17:23:03 +0200 Subject: [PATCH 4/4] modify csdk initialization logic to run only once in the browser --- docs/upgrades/unreleased.md | 42 ++++++++++--------- .../scripts/cloud-sdk-init.component.ts | 17 +++----- 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/docs/upgrades/unreleased.md b/docs/upgrades/unreleased.md index c3297832b2..abe7d1452d 100644 --- a/docs/upgrades/unreleased.md +++ b/docs/upgrades/unreleased.md @@ -295,6 +295,7 @@ If you plan to use the Angular SDK with XMCloud, you will need to perform next s * In XMCloud client side event tracking is done via CloudSDK so you need to make sure that it is initialized before send any event. See the following example of a component that does that; note that it should be added to the scripts.component.html before any other scripts that uses it; for more details take a look at the OOTB cloud-sdk-init.component.ts: ```ts + import { take } from 'rxjs/operators'; import { CloudSDK } from '@sitecore-cloudsdk/core/browser'; import '@sitecore-cloudsdk/events/browser'; import { environment } from '../../../environments/environment'; @@ -304,26 +305,27 @@ If you plan to use the Angular SDK with XMCloud, you will need to perform next s ... ngOnInit(): void { if (!isServer() && environment.production) { - this.contextSubscription = this.jssContext.state.subscribe((newState: JssState) => { - const { - route, - context: { pageState }, - } = newState.sitecore; - - // Do not initialize CloudSDK in editing or preview mode or if missing route data - if (pageState !== LayoutServicePageState.Normal || !route?.itemId) { - return; - } - - CloudSDK({ - siteName: environment.sitecoreSiteName, - sitecoreEdgeUrl: environment.sitecoreEdgeUrl, - sitecoreEdgeContextId: environment.sitecoreEdgeContextId, - cookieDomain: window.location.hostname.replace(/^www\./, ''), - enableBrowserCookie: true, - }) - .addEvents() - .initialize(); + // to ensure that CloudSDK initialization logic runs only once in the browser, take only the first emitted value of state + this.jssContext.state.pipe(take(1)).subscribe((newState: JssState) => { + const { + route, + context: { pageState }, + } = newState.sitecore; + + // Do not initialize CloudSDK in editing or preview mode or if missing route data + if (pageState !== LayoutServicePageState.Normal || !route?.itemId) { + return; + } + + CloudSDK({ + siteName: environment.sitecoreSiteName, + sitecoreEdgeUrl: environment.sitecoreEdgeUrl, + sitecoreEdgeContextId: environment.sitecoreEdgeContextId, + cookieDomain: window.location.hostname.replace(/^www\./, ''), + enableBrowserCookie: true, + }) + .addEvents() + .initialize(); }); } } diff --git a/packages/create-sitecore-jss/src/templates/angular-xmcloud/src/app/routing/scripts/cloud-sdk-init.component.ts b/packages/create-sitecore-jss/src/templates/angular-xmcloud/src/app/routing/scripts/cloud-sdk-init.component.ts index 6543234566..035d58f751 100644 --- a/packages/create-sitecore-jss/src/templates/angular-xmcloud/src/app/routing/scripts/cloud-sdk-init.component.ts +++ b/packages/create-sitecore-jss/src/templates/angular-xmcloud/src/app/routing/scripts/cloud-sdk-init.component.ts @@ -1,5 +1,5 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { Component, OnInit } from '@angular/core'; +import { take } from 'rxjs/operators'; import { CloudSDK } from '@sitecore-cloudsdk/core/browser'; import '@sitecore-cloudsdk/events/browser'; import { isServer, LayoutServicePageState } from '@sitecore-jss/sitecore-jss-angular'; @@ -14,14 +14,13 @@ import { JssState } from '../../JssState'; selector: 'app-cloud-sdk-init', template: '', }) -export class CloudSdkInitComponent implements OnInit, OnDestroy { - private contextSubscription: Subscription; - +export class CloudSdkInitComponent implements OnInit { constructor(private jssContext: JssContextService) {} ngOnInit(): void { if (!isServer() && environment.production) { - this.contextSubscription = this.jssContext.state.subscribe((newState: JssState) => { + // to ensure that CloudSDK initialization logic runs only once in the browser, take only the first emitted value of state + this.jssContext.state.pipe(take(1)).subscribe((newState: JssState) => { const { route, context: { pageState }, @@ -46,10 +45,4 @@ export class CloudSdkInitComponent implements OnInit, OnDestroy { }); } } - - ngOnDestroy() { - if (this.contextSubscription) { - this.contextSubscription.unsubscribe(); - } - } }