Skip to content

Commit

Permalink
[angular][xmcloud] CDP page view component (#1957)
Browse files Browse the repository at this point in the history
* remove duplicate changelog entry

* add cdp page view component to send page view events

* minor update of imports

* update changelog

* some fixes - handle empty language, handle send event error;

* do not initialize csdk and send events if not in production mode

* add comment

Co-authored-by: Illia Kovalenko <[email protected]>

* fix comment intendation

* minor update of changelog entry

Co-authored-by: Illia Kovalenko <[email protected]>

* rename personalize scop environment variable

* add migration guide entry for page view tracking

* add migrate guide for cloud sdk init

* update changelog

* remove 'public' prefix of the personalize scope env variable

---------

Co-authored-by: Illia Kovalenko <[email protected]>
  • Loading branch information
yavorsk and illiakovalenko authored Oct 29, 2024
1 parent 0c5ee0c commit 892e6d1
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 5 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ 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))
* `[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]``[sitecore-jss-angular]` Add CDP Page View component to Angular XM Cloud add-on ([#1957](https://github.com/Sitecore/jss/pull/1957))


### 🛠 Breaking Change
Expand Down
62 changes: 62 additions & 0 deletions docs/upgrades/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,69 @@ 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 { CloudSDK } from '@sitecore-cloudsdk/core/browser';
import '@sitecore-cloudsdk/events/browser';
import { environment } from '../../../environments/environment';
import { isServer } from '@sitecore-jss/sitecore-jss-angular';
...
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();
}
}
```
* scripts.component.html:
```html
<app-cloud-sdk-init></app-cloud-sdk-init>
```
* In order to be able to track Page View events in XMCloud you have to add a component that executes the page view event and render it in the scripts section; in XMCloud client side event tracking is done via CloudSDK so you need to make sure that it is initialized before firing any tracked event.
* see example code below; for more details take a look at the OOTB cdp-page-view.component.ts
```ts
import { JssContextService } from '../../jss-context.service';
import { JssState } from '../../JssState';
import { pageView, PageViewData } from '@sitecore-cloudsdk/events/browser';
...
ngOnInit(): void {
if (!isServer()) {
this.contextSubscription = this.jssContext.state.subscribe((newState: JssState) => {
...
// prepare the required data
...
const pageViewData: PageViewData = {
channel: 'WEB',
currency: 'USD',
page: route.name,
pageVariantId,
language,
};
pageView(pageViewData).catch((err) => console.debug(err));
});
}
}
```
* add the component to the scripts.component.html after the CloudSdk initialize component:
```html
<app-cloud-sdk-init></app-cloud-sdk-init>
<app-page-view></app-page-view>
```
# @sitecore-jss/sitecore-jss-proxy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@ PROXY_HOST=http://localhost:3000

# Your XM Cloud Proxy server path is needed to build the app. The build output will be copied to the proxy server path.
PROXY_BUILD_PATH=<%- locals.relativeProxyAppDestination.replace(/\\/g, '\\\\') %>dist

# ==============================================

# An optional Sitecore Personalize scope identifier.
# This can be used to isolate personalization data when multiple XM Cloud Environments share a Personalize tenant.
# This should match the PAGES_PERSONALIZE_SCOPE environment variable for your connected XM Cloud Environment.
PERSONALIZE_SCOPE=
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { isServer, CdpHelper, LayoutServicePageState } from '@sitecore-jss/sitecore-jss-angular';
import { pageView, PageViewData } from '@sitecore-cloudsdk/events/browser';
import { JssContextService } from '../../jss-context.service';
import { JssState } from '../../JssState';
import { environment } from '../../../environments/environment';

/**
* This is the CDP page view component.
* It uses the Sitecore Cloud SDK to enable page view events on the client-side.
* See Sitecore Cloud SDK documentation for details.
* https://www.npmjs.com/package/@sitecore-cloudsdk/events
*/
@Component({
selector: 'app-cdp-page-view',
template: '',
})
export class CdpPageViewComponent implements OnInit, OnDestroy {
private contextSubscription: Subscription;

constructor(private jssContext: JssContextService) {}

ngOnInit(): void {
if (!isServer()) {
this.contextSubscription = this.jssContext.state.subscribe((newState: JssState) => {
const {
route,
context: { pageState, language, variantId },
} = newState.sitecore;

// Do not create events in editing or preview mode or if missing route data
if (pageState !== LayoutServicePageState.Normal || !route?.itemId) {
return;
}

// Do not create events if disabled (e.g. we don't have consent)
if (this.disabled()) {
return;
}

const scope = process.env.PERSONALIZE_SCOPE;
const pageVariantId = CdpHelper.getPageVariantId(
route.itemId,
language || environment.defaultLanguage,
variantId as string,
scope
);

const pageViewData: PageViewData = {
channel: 'WEB',
currency: 'USD',
page: route.name,
pageVariantId,
language,
};

pageView(pageViewData).catch((err) => console.debug(err));
});
}
}

ngOnDestroy() {
if (this.contextSubscription) {
this.contextSubscription.unsubscribe();
}
}

/**
* Determines if the page view events should be turned off.
* IMPORTANT: You should implement based on your cookie consent management solution of choice.
* By default it is disabled if not in production mode
*/
disabled = () => {
return !environment.production;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class CloudSdkInitComponent implements OnInit {
constructor() {}

ngOnInit(): void {
if (!isServer) {
if (!isServer() && environment.production) {
CloudSDK({
siteName: environment.sitecoreSiteName,
sitecoreEdgeUrl: environment.sitecoreEdgeUrl,
Expand All @@ -25,8 +25,8 @@ export class CloudSdkInitComponent implements OnInit {
// Cookie may be created in personalize middleware (server), but if not we should create it here
enableBrowserCookie: true,
})
.addEvents()
.initialize();
.addEvents()
.initialize();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<ng-container>
<sc-editing-scripts></sc-editing-scripts>
<app-cloud-sdk-init></app-cloud-sdk-init>
<app-cdp-page-view></app-cdp-page-view>
</ng-container>
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { NgModule } from '@angular/core';
import { ScriptsComponent } from './scripts.component';
import { JssModule } from '@sitecore-jss/sitecore-jss-angular';
import { CloudSdkInitComponent } from './cloud-sdk-init.component';
import { CdpPageViewComponent } from './cdp-page-view.component';

@NgModule({
exports: [ScriptsComponent],
imports: [JssModule],
declarations: [ScriptsComponent, CloudSdkInitComponent],
declarations: [ScriptsComponent, CloudSdkInitComponent, CdpPageViewComponent],
})
export class ScriptsModule {}
2 changes: 2 additions & 0 deletions packages/sitecore-jss-angular/src/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export {
LayoutService,
LayoutServiceData,
LayoutServiceContextData,
LayoutServicePageState,
GraphQLLayoutService,
RestLayoutService,
PlaceholdersData,
Expand Down Expand Up @@ -103,3 +104,4 @@ export {
EventInstance,
PageViewInstance,
} from '@sitecore-jss/sitecore-jss/tracking';
export { CdpHelper } from '@sitecore-jss/sitecore-jss/personalize';

0 comments on commit 892e6d1

Please sign in to comment.