A.E.O Catalyst – Sitecore Marketplace App – Pilot Works

Setting the Context:

To me one of most interesting concepts that was discussed in SUGCON Europe 2026 was A.E.O – Answer Engine Optimization and the other was Marketplace Apps. When marketplace was released last year, spent a couple of days exploring it. Went through its fundamentals only to draw a comparison of such a feature with other SaaS offerings. How they handled security, what are the extension points provided, how the marketplace apps are allowed to communicate with Sitecore contents, what’s the supported tech stacks etc. Never got a chance to explore more.

SUGCON only fueled my interest on these two concepts. If you are unaware of A.E.O, let me explain and you will understand why it’s important in today’s AI world.

In the last Digital Wave – where a customer reaches our brand sites via a simple search in search engine (directly or indirectly), we were required to focus on S.E.O – Search Engine Optimization. We ensured brand sites top the search results by focusing on keywords, meta data, XML Sitemaps, robots.txt, fixing broken links etc.

With the introduction of AI Agents to search engines, users no more look for first page of the search result, instead look for AI responses. Refer below,

This paradigm shift means,

  1. Users often stop at AI’s summarized answer.
  2. AI native search behavior – role of AI engines in shaping how users consume information. (A.E.O)

“More than half of google search end without a site visit”

___________________________________________________________________

The Idea:

From CMS, we have features or we build feature to check the page’s S.E.O readiness, page’s user readability readiness, whether page contain any broken links and fix them etc. Similarly, it would only be right to have a feature to check the A.E.O readiness of the page. Whether page answers questions directly, is the content structure for easy parsing, is schema markup implemented etc.

All this led to developing a marketplace app for SitecoreAI, with a screen in Page Context Panel Extension Point that allows users to check their page's A.E.O maturity, preparedness.

____________________________________________________________________

The Resolution:

Setting up the base for a marketplace app is easy and straight forward. Either clone the https://github.com/Sitecore/marketplace-starter or create a fresh next.js app and install necessary packages and initialize the SDK as mentioned here https://doc.sitecore.com/mp/en/developers/sdk/0/sitecore-marketplace-sdk/quick-start–manual-.html

In SitecoreAI portal, Go to App Studio-> Create App create an app.

Extension Points: Sitecore allows 5 extension points – locations inside SitecoreAI Portal where your customization can be inserted. Depending upon the extension point, sitecoreai provides additional properties for the app to use.

For more details on these extension points – Standalone, Full Screen, Dashboard Widgets, Page Context Panel, Custom Fields check https://doc.sitecore.com/mp/en/developers/marketplace/extension-points.html

For our requirement, as I mentioned earlier Page context panel – Page Builder extension point fits perfectly. So configured that end point. (Added Full screen for testing some features here (ref. screenshot). Please ignore it)

Next important configuration to mind is, the API access. This is important because, to access certain sitecore items, we need access to context ids – live id and preview id. Preview ID and Live ID is needed for our extension to execute GraphQL queries.

This Context IDs is available via App Context -> Resource Access -> Context -> preview/live ids. Only if this API access checked, sitecore returns the context ids in the app context. If not it Resource Access will be returned as an empty array.

appContext.resourceAccess?.[0]?.context?.preview;

Configure the deployment url. With the extension point route configured, when the extension point is accessed, the control is passed to this URL.

In our case, for Page context panel – Page Builder – /pages-contextpanel-extension route is configured. So, https://localhost:3001/pages-contextpanel-extension will be shown in the extension point.

const { client, error, isInitialized } = useMarketplaceClient();
const [appContext, setAppContext] = useState<ApplicationContext>();
const sitecoreContextId = appContext?.resourceAccess?.[0]?.context?.preview || appContext?.resourceAccess?.[0]?.context?.live;
const graphqlQuery = {
query: `
query {
item(
where: {
database: "master",
path: "${pagePath}"
}
) {
itemId
name
fields(ownFields: true, excludeStandardFields: true) {
nodes {
name
value
}
}
}
}
`,
};
const response = await sdkClient.mutate("xmc.authoring.graphql" as any, {
params: {
query: {
sitecoreContextId,
},
body: graphqlQuery,
},
});

This is the graphql query used to fetch the context page items fields and values.

Based on the pages field values we determine their AEO Readiness Score and generate the page’s JSON-LD

JSON-LD

JSON‑LD (JavaScript Object Notation for Linked Data) is a method of encoding structured data using the JSON format to create a machine-readable web. It is the most recommended format by Google for implementing schema markup because it is easy to maintain and does not interfere with a page’s visual presentation. It provides a standardized way to describe your page’s content so AI engines can parse it easily. This varies depending upon the page context. For e.g.: if it’s an Article Page, sample JSON-LD

{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Understanding AEO Readiness for Modern Content",
"alternativeHeadline": "Answer Engine Optimization Explained",
"description": "A detailed guide on how to prepare your content for Answer Engine Optimization (AEO), ensuring visibility in AI-driven answers.",
"articleBody": "Full article text or summary goes here...",
"author": {
"@type": "Person",
"name": "Pushpaganan",
"url": "https://example.com/author/pushpaganan",
"sameAs": [
"https://www.linkedin.com/in/pushpaganan",
"https://twitter.com/pushpaganan"
]
},
"editor": {
"@type": "Person",
"name": "Jane Doe"
},
"contributor": {
"@type": "Person",
"name": "John Smith"
},
"datePublished": "2026-05-23",
"dateModified": "2026-05-23",
"publisher": {
"@type": "Organization",
"name": "SitecoreAI Blog",
"logo": {
"@type": "ImageObject",
"url": "https://example.com/logo.png",
"width": 600,
"height": 60
}
},
"image": [
"https://example.com/images/aeo-readiness-cover.jpg"
],
"keywords": "Answer Engine Optimization, AEO, SEO, AI search",
"wordcount": "1200",
"inLanguage": "en",
"isAccessibleForFree": true,
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://example.com/aeo-readiness"
},
"citation": [
"https://schema.org",
"https://developers.google.com/search/docs/appearance/structured-data/article"
],
"commentCount": 12,
"interactionStatistic": {
"@type": "InteractionCounter",
"interactionType": { "@type": "LikeAction" },
"userInteractionCount": 250
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"ratingCount": "134"
},
"about": {
"@type": "Thing",
"name": "Answer Engine Optimization"
}
}

For a product-based page, dummy schema for reference,

{
"@context": "https://schema.org/",
"@type": "Product",
"name": "SitecoreAI Content SDK Pro",
"description": "A powerful SDK for building AI-driven content components with Sitecore.",
"sku": "SDK-2026-PRO",
"mpn": "12345",
"brand": {
"@type": "Brand",
"name": "SitecoreAI"
},
"model": "Pro Edition",
"category": "Software Development Kit",
"image": [
"https://example.com/images/sdk-pro-cover.jpg",
"https://example.com/images/sdk-pro-screenshot1.jpg"
],
"url": "https://example.com/products/sitecoreai-sdk-pro",
"releaseDate": "2026-04-15",
"productionDate": "2026-03-01",
"material": "Digital software",
"color": "N/A",
"size": "N/A",
"weight": "500MB",
"audience": {
"@type": "Audience",
"audienceType": "Developers"
},
"isAccessoryOrSparePartFor": {
"@type": "Product",
"name": "SitecoreAI Platform"
},
"offers": {
"@type": "Offer",
"url": "https://example.com/products/sitecoreai-sdk-pro",
"priceCurrency": "USD",
"price": "499.00",
"priceValidUntil": "2026-12-31",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition",
"seller": {
"@type": "Organization",
"name": "SitecoreAI Store"
}
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.7",
"reviewCount": "89"
},
"review": [
{
"@type": "Review",
"author": {
"@type": "Person",
"name": "Jane Developer"
},
"datePublished": "2026-05-01",
"reviewBody": "The SDK is intuitive and integrates seamlessly with SitecoreAI.",
"name": "Excellent developer tool",
"reviewRating": {
"@type": "Rating",
"ratingValue": "5",
"bestRating": "5"
}
}
],
"additionalProperty": [
{
"@type": "PropertyValue",
"name": "License",
"value": "Enterprise"
},
{
"@type": "PropertyValue",
"name": "Support",
"value": "24/7"
}
]
}

As the article title suggests, this is a Pilot version of the app. Planning to implement additional features and share the repository public. I haven’t shared the logic used to calculate the AI readiness scores and JSON-LD generation as I need check more standard and established methods. Will update and share them in the coming days.

SitecoreAI – Content SDK – Components – Variants

Content SDK

Setting the context:

Content SDK which replaces JSS SDK for SitecoreAI based applications, comes with lots of features and updates that puts SitecoreAI alongside few other Headless SaaS CMS. Of course, SitecoreAI has the robust, strong, trustable core CMS that ranks it above other Headless, SaaS CMS, but few stuffs like simple, lift weight SDKs and marketplace apps (others call it integrations, just Apps, plugins or Extensions) were first available in other products.

Prior to Content SDK, JSS SDK was used in the FE Applications for development. It worked. But the problem was, it was mainly built with focus around Sitecore XP/XM Headless. They are not cloud native meaning JSS SDK couldn’t fully utilize the advantages of SitecoreAI.

Now, Content SDK was released a year ago, the first few versions were mainly focused on extracting and simplifying JSS functionalities. With recent releases, things got way smoother.

Component-Map:

Initially when I started exploring Content SDK, out of reflexes or muscle memory I started registering the components manually after every time I create one. Because that’s how we used to do it other products (Uniform/StoryBlok/Contentstack etc). But when I found some of my changes getting overwritten and new registrations getting added during build, I was a bit confused. When I explored further, found that there is this piece of command – sitecore-tools:generate-map in build, package.json

This registers the components automatically, no need for manual registration. A similar feature is not available in other systems.

Now, this gets better:

In some solutions, we prefer having the typescript types that are used only in a specific component be placed in the same folder as component, eg:

What this did was whenever I build the solution, map got generated along with the types.

Now, this will create an issue when we create (in code/sitecoreai), configure (in sitecoreai) and register (in code) variants for a component. So, to fix that, utilized the exclude property of component map in sitecore.cli.config

and voilà,

Moving on to Component Variants:

For creating a component or variants you can check the official sitecore documentation, I just wanted to add few important items or stuffs that not mentioned there.

  • While creating the component, to enable rendering variants, the component’s rendering parameter template must be inherited from Base Rendering Parameters template. This because this template in turn is inherited from IComponentVariant that has Experience Accelerator ComponentVariant drop link which is used for finding a particular component’s variant’s code behind file.
  • Once you create a Variant Definition for a component, based on the values of Allowed in templates, you will see the variants option in Page Builder.
  • Here comes the beauty of Content SDK, Content SDK allows you to define a component variant in a separate file under the same component folder and it automatically identifies it and registers it to the map when the app is built.

The Centerpiece:

Components and all its Component Variants must be uniformly rendered. By that I mean, Component’s default cannot be server side rendered while Component’s Variant A be rendered client side. This is because, if Component Default is rendered Server side and Variant in client side, it causes server/client function serialization mismatch. This mismatch will cause a mixed export object which Next.js will reject.

In my case, the cards-section component, default variant was server side rendered whereas the slider variant had to useRef hook so had to render on the client. (I didn’t work on any work arounds, as I wanted to mention the issue.)

Now, I will explain it further in SitecoreAI terms, in the current Content SDK component map model, rendering mode is decided per rendering key not per variant export. So, a rendering if it has default (Server side) and variant A (client side) in that same mapping will trigger the error mentioned above.

“In the current Content SDK component map model, rendering mode is decided per rendering key not per variant export. This means that if the default variant is server-side rendered but another variant needs to be client-side rendered (or vice versa), we’re forced to create that variant as a separate component.

To overcome that, we currently have to create the Variant A as a separate rendering that renders client side and register it separately.

I think it would be nice if components are mapped not just by per rendering key but by also considering their variants. So that they don’t have to be split into separate components manually.

Sitecore 2023 Contributions Summarized

All time stats:

2023 (as of Nov 26 – 2023) Stats Summary:

S.NoQuarterHighlightsBlogsLinkedIn PostsSession YouTube Links
1Dec,Jan,FebSitecore 10.3 Release. Explored the new features and blogged/presented session about them.https://pushpaganan.home.blog/2023/02/18/sitecore-item-as-a-resource-deep-dive-1-iaar-plugin/
Explored newly released Item as a Resource Plugin and it’s use case.

https://pushpaganan.home.blog/2023/02/25/sitecore-ways-to-configure-a-list-fields-source/
Came across this requirement where I have to configure a list field’s source dynamically when an item is created, blogged on what are the different ways we can configure a list field’s source in Sitecore
https://www.linkedin.com/posts/pushpaganan_sitecore-activity-7004498824614334465-ftUM?utm_source=share&utm_medium=member_desktop https://www.linkedin.com/posts/pushpaganan_sitecore-webhooks-activity-7008180154325696512-4-3z?utm_source=share&utm_medium=member_desktop https://www.linkedin.com/posts/pushpaganan_sitecore-item-as-a-resource-deep-dive-activity-7032778078745427968-EVFF?utm_source=share&utm_medium=member_desktop  Sitecore 10.3 & beyond with Pushpaganan @ayanpush​  
2Mar,April,MayPresented in SUGCON – Europe 2023 – Malaga on XM-Cloud

Explored XM Cloud and created a custom script for  syncing content from a XM Cloud environment with Local
https://pushpaganan.home.blog/2023/03/12/sitecore-experience-manager-cloud-introduction/
XM Cloud Introduction

https://pushpaganan.home.blog/2023/03/14/sitecore-xm-cloud-errors-during-setup-and-fixes-work-around/
There were already quite a few blogs on setup and installation so shared the errors I faced and their fixes while setting up XMC

https://pushpaganan.home.blog/2023/03/15/sitecore-xm-cloud-cli-sitecore-devex-extensibility-xmcloud-plugin/
Understood the potential of XM Cloud CLI Plugin which was newly released. Explored and shared it’s use case.

https://pushpaganan.home.blog/2023/04/05/sitecore-xm-cloud-sync-local/
A Powershell Script that automates the XM Cloud Sync from a target environment.

https://pushpaganan.home.blog/2023/05/20/sitecore-jss-next-js-routing/
Sitecore Next.Js Routing Mechanism.

https://pushpaganan.home.blog/2023/05/29/sitecore-custom-keyboard-shortcuts/
How we can create custom keyboard shortcuts on Sitecore and XM Cloud
https://www.linkedin.com/posts/pushpaganan_sugcon-sugcon-sitecore-activity-7045154853962010624-sma2?utm_source=share&utm_medium=member_desktop https://www.linkedin.com/posts/pushpaganan_thewayforward-xmcloud-sitecore-activity-7039291103128211456-74M2?utm_source=share&utm_medium=member_desktop https://www.linkedin.com/posts/pushpaganan_sitecore-experience-manager-cloud-introduction-activity-7041894122793627648-I43e?utm_source=share&utm_medium=member_desktop https://www.linkedin.com/posts/pushpaganan_sitecore-gartner-magicquadrant-activity-7048708620577890307-ufH3?utm_source=share&utm_medium=member_desktop https://www.linkedin.com/posts/pushpaganan_sitecore-jss-nextjs-routing-activity-7065669890090639360-MoVL?utm_source=share&utm_medium=member_desktop https://www.linkedin.com/posts/pushpaganan_sitecore-custom-keyboard-shortcuts-activity-7069605927363981312-PlHo?utm_source=share&utm_medium=member_desktopThe new Sitecore meets (or beats) the old Sitecore…  
3June,July,AugustUnderstood the importance of Cloud based Sitecore Composable Products.

Consciously decided to not write much about Sitecore XP/XM and to focus on composable products.

Explored other composable Products – CDP/Personalize/Connect  
https://pushpaganan.home.blog/2023/06/24/sitecore-customer-data-platform/
Sitecore CDP explored and shared their use case.

https://pushpaganan.home.blog/2023/06/24/sitecore-personalize-boxever-is-not-defined/
Errors and fixes while setting up Sitecore Personalize for the first time.

https://pushpaganan.home.blog/2023/08/19/getting-started-with-sitecore-connect-integrating-sitecore-with-teams/
Sitecore Connect – Getting started with Integrating Sitecore with Teams Use Case

https://pushpaganan.home.blog/2023/08/26/foodbot-sitecore-connect-a-recipe-with-a-custom-http-api-end-point/
Sitecore Connect – Building a Food Bot POC with Connect and a Custom API.
https://www.linkedin.com/posts/pushpaganan_sitecore-customer-data-platform-activity-7078453142463369216-UMeK?utm_source=share&utm_medium=member_desktop https://www.linkedin.com/posts/pushpaganan_getting-started-with-sitecore-connect-integrating-activity-7098804951262326784-zyb3 https://www.linkedin.com/posts/pushpaganan_foodbot-sitecore-connect-a-recipe-with-activity-7101302164345479168-HgSL?utm_source=share&utm_medium=member_desktop https://www.linkedin.com/posts/jasonstcyr_getting-started-with-sitecore-connect-integrating-activity-7102349305880928256-jvr9?utm_source=share&utm_medium=member_android 
4September,October,NovemberCustomizing Sitecore Webhook.

After getting few good feedback on Sitecore Connect Blog post, decided to present a session on Sitecore Connect in SUGPune  
https://pushpaganan.home.blog/2023/09/14/customizing-sitecore-webhooks-with-custom-event-and-custom-payload/
My Favorite, Sitecore Webhooks payload are more sitecore centric. Ways to customize sitecore webhook payload.

Need for Sitecore Connect in a Version less Composable World by Pushpaganan – SUG Pune
https://www.linkedin.com/posts/pushpaganan_customizing-sitecore-webhooks-with-custom-activity-7107903304763924480-xbTO?utm_source=share&utm_medium=member_android https://www.linkedin.com/posts/pushpaganan_sugpune-sitecore-connect-activity-7117891334983598081-JPDM?utm_source=share&utm_medium=member_desktopNeed for Sitecore Connect in a Version less Composable World by Pushpaganan  
Sitecore Contributions – 2023 – Pushpaganan

Customizing Sitecore Webhooks – With Custom Event and Custom Payload

Was asked in Sitecore Slack recently whether we can customize Sitecore Webhook Payload. I didn’t know if we could or how to customize them. Wanted to find an answer to that…..Found a way, thus this article.

Please note that as I did this just for exploring and self learning or as a POC kind of activity, I couldn’t completely develop this as a enterprise level solution to a requirement. Please update the code as per your need/coding standards.

Let’s get started.

Sitecore Webhook Payloads are way more Sitecore Centric and are (as it is) at times not fit to be posted to external systems.

When I explored Sitecore Webhook initially when it was released felt that the default payload is more Sitecore Centric meaning, it has only the Item ID, Publish Target, RecoveryID etc ???? PFB a sample payload for an Publish End event. I am not sure if all these fields are useful or even required while posting a payload to different system.

In order to make full use of Webhooks, this payload data must be customizable.

Say we need some configuration item belonging to a particular template whenever created and published, some of it’s field values needs to be posted to an external system. Or after a Sitecore Task Scheduler is successful and you have to post an item’s field value to an external system. These are scenarios when Sitecore Webhook come handy. But with OOTB implementation we may not be able to post those item’s field data or any other computed data. In such cases, customizing the webhook payload will be handy.

Initially, tried going through the \App_Config\Sitecore\CMS.Core\Sitecore.Webhooks.config and checked WebhookSubscriber and InitializeWebhooks from Kernel DLL. But didn’t find any useful.

When went through the Webhook Event Item, saw that it didn’t have any field except Event Name.

Just took a shot, thought of creating a custom event and triggering the event with custom properties hoping that will be used as payload when the event is triggered.

Step 1: Created your custom event and it’s event handler.

P.S: Here, instead of creating a custom event, you can create a event that subscribes to existing sitecore system events. So that these events will always be called after those system events. Custom properties can be added to these new events which will be used by Sitecore Webhook for payload.

Step 2: Create a Custom Folder inside Webhooks/Event Types. (So that you have a separation between sitecore system events and custom events)

Step 3: Trigger this event with Custom Payload. I just created a Controller Rendering with an action that triggers the event with custom payload.

Created properties – a dictionary with string as key and object as value. Included the custom payload.

(Webhooks weren’t triggering when you don’t use properties meaning payload which is not of Dictionary<string, object>. I got error initially and spent a lot of time troubleshooting when I used Event.RaiseEvent(events, new object[]{ “key”, “value” });)

Step 4: Create a Sitecore Webhook Handler that subscribes to our custom event.

Included this to a page for testing and loaded the page……Voila!

While exploring about Customizing Sitecore Webhook payload, I came across this article by Kristoffer Brinch Kjeldby and found it helpful. Please refer them if you want to customize the payload for any existing events.

Foodbot – Sitecore Connect – A Recipe with a Custom HTTP API End Point

This is a second part in the series of articles exploring Sitecore Connect.

Setting the article Context:

Prev. we made use of available apps/actions listed in Sitecore Connect to create a recipe. In this article, we will see how we can create a recipe using a Custom HTTP Endpoint.

To make it interesting, we will create a FoodBot. As MVP 1 release, we will create a feature where user can interact with a MS Teams Bot -> Workbot and get preparation steps for a recipe of their choice. This time recipe here means food.

What we are gonna do?

  • Create a recipe in Connect with a trigger from MS Teams Workbot. We will create a custom command with input parameter.
  • We will use the input parameter in next step to make a GET call to a custom API End Point. As the topic in discussion is Connect, we will use a public free API (Tasty API Documentation (apidojo) | RapidAPI)
  • Return a response.

And btw all this with no code.

TASTY:

Tasty is a free open source API. It can be accessed via Rapid API. It has several endpoints. One key end point is /recipes/list. It provides a data required to make a recipe.

Let’s get started.

  • Create a new recipe with a trigger – New Command from Workbot for Teams “getrecipe” in our case.
  • Define a input parameter. This is used to store the user input and it can be used in subsequent actions.
  • In the Actions, select an HTTP Action and setup the connection. For Connection you can use different available authentication modes – Oauth/Basic/Head Auth or you can create your custom Authentication.
  • For my case, Tasty API provided Header Based Authentication.
  • Use the Recipe Name – Item Name input parameter configured in the trigger as query parameter.
  • Setup the remaining like we did in the prev. article. And finally the recipe looks like below.
  • Test/Start the recipe. Over to Teams.

Thoughts on Connect and Development Trends:

  • Although, in an enterprise level this get recipe kind a Workbot won’t be required/used. The core idea I want to share via this article is, we would be required to expose contents via end point, rather than serving them as web page… We kind of already do that. With Layout Service/GraphQL etc. But we so far have exposed those end points to an application like a Front-End Head/Mobile App.
  • So, what’s the difference, we usually have a code logic that renders a page/interface to user. Here after that part may be handled by some application that offers Front End components as templates and we can connect them to the content exposed by these end points.
  • In fact, Sitecore XM Cloud Components is the best example of this.
  • XM Cloud Components is a Front End as a Service feature. That allows you to develop renderings – presentation blocks on the fly with contents flowing in from any API/GraphQL End Point.
  • Some additional info related to components can be found in our session in SUGCON EUROPE 2023

Getting Started with Sitecore Connect – Integrating Sitecore with Teams

Have read about Sitecore Connect early this year and got a sneak peak into it when a session on Sitecore Connect was presented by Ivan. Initially wasn’t much interested on it may be it’s because it was promoted more as a Low Code or No Code platform. Developers kind a hate that right? We don’t want to do just some configurations. (Configurations…Recipes whatever???)

Keeping aside my “developer” ego, recently when got an opportunity to explore Sitecore Connect, jumped right into it. Spent 12 hours of the last 36 hours on it. Tried to summarize what I learned in this article.

Why Sitecore Connect?

We are now in Composable trend. Where you can have separate product for each of your CX needs. You need a Headless CMS? You can have Sitecore XM/XP, XM Cloud, Contentful etc. You need a product for Marketing Automation that isn’t tightly coupled with your CMS? You can have Sitecore Send, HubSpot Marketing Automation . You need a separate search product for your websites that is again not tightly coupled with your CMS, you can have Algolia, Amazon CloudSearch or Sitecore Search. Similarly for….well you get the idea.

In a world, were we have multiple products handling different requirements in the same Digital Experience landscape, wouldn’t it be easier if we have a product that facilitates seamless connectivity among these modules. So that these modules can work in sync.

First, within Sitecore portfolio, a Connector that allows data transfer between Sitecore Products. Second, a connector that integrates a Sitecore Product with other applications.  Other applications include a CRM (Salesforce Marketing Cloud/Microsoft Dynamics 365 etc) or a Marketing Automation System or a Email/Messaging System etc.

What’s Sitecore Connect?

Well Sitecore Connect is one of the integration workbench announced by Sitecore in last symposium and officially launched on January 16 this year.

It was developed in partnership with Workato. Workato is a Automation platform for integration and workflow automation.

It’s a cloud based low/no code, drag-and-drop tool, aims to “solve some of the integration ‘tax’ of the composable DXP”.

Sitecore offers this as an app in their cloud portal – https://portal.sitecorecloud.io/

It’s a part of Sitecore Engagement Cloud,

Enough with the chit chat, let’s get into the components/features of the product.

Some Sitecore Connect Components/Terminologies

You can create a project for your requirement and each project consist of Recipes and Connections.

Recipes – Are like pipelines – DevOps pipelines or Marketing Automation Pipelines. Each recipes when turned on, will be configured to be triggered by a trigger event followed by set of actions/decisions and call functions.

Actions involve calling action in an app. There are several apps listed in connect.

Connections – Connection include setting up authentication with different apps.

Remember what I mentioned earlier – “First, within Sitecore portfolio, a Connector that allows data transfer between Sitecore Products. Second, a connector that integrates a Sitecore Product with other applications.”

Actions vary depending upon the app.

Now to integrating Sitecore XM/XP via WebHooks with Microsoft Teams using Sitecore Connect,

  • Sitecore WebHooks are new features that was released in 10.3. To know more about WebHooks check here.
  • Create a recipe with a starting point as a “Trigger from a webhook” and setup a webhook.
  • Create a  Webhook Event Handler in Sitecore. For Eg. Here I have created a Webhook Event Handler for a Sitecore item publish end event. So that when an event occurs in Sitecore and payload is posted to the configured Webhook.
  • When the payload is posted to the webhook, the recipe is triggered in Sitecore Connect.
  • In actions, I have selected Action in an app -> App – Teams,
  • Configure the connection -> Authenticate to teams with an account that has the necessary scope.
  • In this scenario, we will send a message via Workbot to a particular user. In order to do that you need the user’s team ID. You can get it by “Get user info by principal name or user ID”
  • Another cool stuff is we can use the payload data from previous actions in our current action.
  • Add Workbot app to your teams,

Now that everything is setup, start the recipe. Publish the item in Sitecore.

This may not be the best use case but it does serve the purpose. Ability to connect different systems seamlessly with low-code or NO CODE in this case. Moreover, we can create custom Webhook Handler in Sitecore for different requirements. When you do something in sitecore post a payload that can be configured as trigger in Sitecore Connect and then it can be used to plan any action in the available apps.

Sitecore – Personalize – Boxever is not defined

Recently, while trying to add an experience in Personalize for my application it wasn’t working.

Created a simple experience with OOTB component,

Included the right filter and page targeting

But still the experience wasn’t appearing the site. Initially thought this must be because of some organizational firewall. When I checked the experience experiment data, I could see a success status

  • For Personalize and CDP the integration procedure is similar. Meaning we will use the same GTM script for integrating Personalize with the web application. Only difference is we have to set the

“webPersonalization: “<boolean_or_object>”” key in the script.

  • Checked that, I have enabled that as well.
  • But still I was not able to see the experience in the web application.
  • Next option, Previewed the experience.
  • Voila, found where the issue at Variant HTML/CSS/JS – JavaScript Evaluation Error – ReferenceError: Boxever is not defined
  • Tried googling this, wasn’t able to find anything useful. While learning about CDP from various recent documents and old videos, I understood that Boxever library was replaced by Sitecore Engage JavaScript SDK.
  • Although I referred Engage Library as per Sitecore’s recent recommendation, I could clearly see some part of the change is still referring to Boxever.
  • I didn’t have any customized code apart from the GTM Script/Integration Script. So obv. It’s somewhere from Personalize part.
  • When checked in advanced edit JavaScript tab, I could still see some reference to Boxever JavaScript Legacy Library.
  • Updated this to refer Engage SDK,
  • Finally,

Sitecore – Customer Data Platform

Setting the context:

Recently, got an opportunity to explore Sitecore’s ‘CDP & Personalize’ – “Engagement Cloud” SaaS products. (Yea.. Content Cloud..Commerce Cloud…Enagement Cloud what’s this recent OBSESSION with word “CLOUD”?)

Very beginning when Sitecore bought Boxever, I checked it out (Around March 2021). Now that all the fuzz is down and lot of upgrades have been made to the product, thought I will get myself updated.

This post is more of a “Getting Started with CDP”.

So…What’s Sitecore CDP?

According to Sitecore.com,

“A Customer Data Platform is packaged software that creates a persistent, unified customer database that is accessible to other systems“.

In the XP world, we used to have the xConnect/xDb components right? Where we have modules to get the  behavioral data of a user/visitor – The Experience Profile/Experience Analytics/Lists/Segments/Reports part. They are not accessible to other systems OOTB. Of course there is XConnect API but most of the time you have write something on top of it to share the data with other systems. This is a bigger and way…way latest version of that. Consider it from a Global Enterprise perspective, where you have customers across globe, different apps for different channels for customers. (Online/Offline) and you have to collect, merge, process, segment and provide options to expose these data to other systems. Sitecore XP Marketing Applications modules isn’t robust enough to handle such scenarios.

Composability and Cloud first:

The Experience Profile/Analytics part can only capture/process/manipulate/be used for only the sites defined in your sitecore instance, Sitecore CDP can be integrated with any site directly. This means that you can run your marketing websites on any platform but still can use Sitecore CDP. Also, as the Experience Profile/Analytics and other such modules are a part of Sitecore XP, it needs XP to be installed and managed by us. Where as Sitecore CDP is “Cloud based” in doesn’t need to be installed/maintained. It can directly be consumed.

Alright I could hear you thinking, enough with the bla bla, SHOW ME THE MONEY!

*Source: Discover Sitecore

Data from customer touchpoints/Other Data warehouse can be ingested via Stream APIs/Batch APIs and can then later the data can be requested for manipulation via Interactive API. These customer data can then be exposed various inbuild models/external Amazon..Azure..or any other ML models for processing -> for segmenting, profiling, audience sync etc.

Zooming IN on the Integration Process,

*Source: Discover Sitecore

Please read Boxever.js as Engage.js. Will explain this later.

  • For integrating Sitecore CDP, one would be injecting “Engage.js” to the web application. This library requests an unique ID from Browser API, a cookie is set in the client.
  • From then, all the behavioral data like view a page, clicking on a button, registering/adding items to cart etc will be captured and sent to CDP via Events API.
  • To elaborate about Interactive API say we need a user’s marketing preference. This is a simple true or false attribute associated with the customer. When user makes changes to their marketing preference from any of the application(Web/Mobile/Front Office or stores) this data needs to be updated to customer data in CDP. For this purpose, Interactive API will be leveraged.

There are several approaches for integrating CDP with an web application,

  • Client-side integration using the Engage SDK script and a TMS
  • Client-side integration using the Engage SDK script
  • Integration using the Engage SDK package
  • Server-side integration using direct HTTP requests

The suitable approach depends upon the nature of the application(.NET Core Web App/ React/Angular/Next based app). The entire documentation on this can be found in this page. For my learning purpose I used the simplest approach – integrating using a Tag Management System – Google Tag Manager.

Integrating CDP with you Application using GTM

<script>
    // Initialize the engage variable
    var engage = undefined;

    // Create and inject the <script> tag into the HTML
    var s = document.createElement("script");
    s.type = "text/javascript";
    s.async = true;
    s.src = "https://d1mj578wat5n4o.cloudfront.net/sitecore-engage-v.1.3.0.min.js";
    var x = document.querySelector("script");
    x.parentNode.insertBefore(s, x);

    // Initialize the Engage SDK
    s.addEventListener("load", function () {
      var settings = {
        clientKey: "<client_key_PLACEHOLDER>",
        targetURL: "<stream_api_target_endpoint_PLACEHOLDER>",
        pointOfSale: "<point_of_sale_PLACEHOLDER>",
        cookieDomain: "<cookie_domain_PLACEHOLDER>",
        cookieExpiryDays: 365,
        forceServerCookieMode: false,
        includeUTMParameters: true,
        webPersonalization: "<boolean_or_object>"
    };

    window.Engage.init(settings).then(function (result) {
      engage = result;

      // Send a VIEW event
      var event = {
        channel: "<channel_PLACEHOLDER>",
        language: "<language_PLACEHOLDER>",
        currency: "<currency_PLACEHOLDER>",
        page: "<page_PLACEHOLDER>"
      };
     engage.pageView(event);
    });
  });
  • Create a POS in CDP
    • POS stands for Point Of Sale. This like creating multisite in a single sitecore instance. In real life, POS can be a customer service portal/ customer service mobile app or offline retail store.
    • Within CDP, POS is the central point. Where all customer behavioral data/application analytics will be grouped.
    • POS can be created in CDP Settings->Point of Sale->Create
  • While creating POS these are the 5 mandatory details that needs to be given.
  • Timeout here refers to the user’s browser session timeout.

Get the Google Container Code and inject it to your web application

I used my personal old sitecore instance that still runs on MVC. So adding it in the Main Layout.

And if everything goes well, now we will be able to see the data in CDP based on the user interaction to your app.

Cool!

Behind The Screen:

  • Remember earlier I mentioned that after we inject the Engage script, the script would call Stream API when the session loads. You can see this below.
  • This customer_ref can be queried in CDP.

That’s it with CDP for now, my next article is about an issue I faced while creating an experience. So to conclude this article I would like to share a small detail about the modules available in CDP and Personalize. Sitecore provides options for Sitecore CDP separately, Sitecore Personalize separately or Sitecore Smart Hub CDP. Felt that this would be good to know as what are the modules available in each  package. Experience comes in as a part of Personalize.

Sitecore – Custom Keyboard Shortcuts

Recently, I had to sort items repeatedly. Usually if I had to sort one or two items inside a folder, I would normally use Right Click->Sorting-> Sort ….

But this time I had to do this for than once and repeatedly. I am not sure if this sorting(based on my requirement) can be done with powershell or automated some other way. I didn’t explore that part.

I felt it would be helpful, if I could have some keyboard shortcuts. I was also not sure if sitecore has a default shortcut for sorting. (I didn’t check them either) I know only a 3-4 shortcuts.  May be it’s because I was more interested to know if I can create a custom keyboard shortcut and if yes how?

So…turns out we can create our own shortcuts.

Keyboard Map:

Under Development Tools -> Keyboard Map

Press the key/key-combination in the keyboard. Sitecore generates a code.

For Eg: CTRL + UP – c38

Switch to Core DB,

  • Navigate to the item/dialog to which you want to associate the keyboard code with and add the copied value to Key Code field.
  • For Eg: In /sitecore/content/Applications/Content Editor/Ribbons/Chunks/Rename/Rename you can see the Key Code 113 assigned.

Alternatively, you can add a new Key Map item under /sitecore/system/Settings/Key Map and map the key board code to the command.

This way you can map a keyboard shortcut to any custom command that’s created.

As it’s 2023 and we are working on XM Cloud as well, tried this in XM Cloud, it’s working in XMC as well.

Sitecore-JSS Next.js Routing

Recently explored Sitecore Headless Application Development using NextJS and found few concepts interesting and worth blogging…hence this article. Although I intend to write about routing specifically but I may end up sharing more.

Since Sitecore is our primary focus, I plan to share the features of NextJS first and then where/how they fit in Sitecore Headless Application (based on NextJS) world.

What’s Next.JS…why Next.JS and what does it offer that React doesn’t? (Keeping it short – so just the highlights)

  • Next.Js – React Framework for Production
  • So what’s React – React is a library for creating user interface. However, for a full fledge application we need more features like routing, authentication etc. These features can (have to) be implemented using other tools. Eg: For routing in React, one would be using an external routing package (possibly) ReactRouter. React mainly focuses on the presentation/view part of the application.
  • In Next.Js among many other features it offers, it’s shipped with key features like routing/authentication/Prerender (Server-Side Rendering SSR/ Static Site Generator SSG)/API Routing etc.

Planning to explore each of these in detail wrt Sitecore in coming days, starting with Routing. But before that,

In Sitecore world, this SSR/SSG has to be set while creating the headless application. For NextJS based Sitecore Headless Apps the default prerender is SSG. However this can be changed later or even better, some pages can be prerendered in SSG and remaining can be SSR. (Hybrid)

Pre-rendering: Generate the page's HTML is advance instead of them being generated in the client side.

Back to NextJS World -> Page Router

  • Nextjs basically uses file based routing. This means, when a file is created in pages directory by default a route is added. To a page with route – /contact-us/front-office simply create the relevant folder structure and corresponding js/tsx or jsx file.

Alright I get what you are thinking about, this may work out for some standalone next.js apps, but in case of a headless CMS where hundreds and thousands of pages are created on the run… How would this work out? Obviously, we can’t create a route (physical page/file) for each sitecore page.

Well…to be precise, we don’t have to setup any file/route in case of sitecore headless app. As this will be handled by the /src/pages/[[…path]].tsx file that’s created when you create a sitecore nextjs headless app.

If you notice, this file also has the logic for not found page. Remember when we used to patch a pipeline processor for custom 404. This can be handled by updating the logic in this file.

NextJS World: This page uses a concept called catch all route a type of dynamic routing offered by NextJs. We can create a catch all route under a particular page by adding a file [[…anyfilename]].js/tsx/jsx

This will store all the segments of url the comes after /blog and can be processed as required.

Sitecore World:

  • Based on the custom code by sitecore in getStaticPaths/getStaticProps, the path information is shared as a tokenized array.
  • P.S: I have specified SSG prerendering so we have GetStaticPaths(with GetStaticProps) which generates list of pages that should be statically generated using SitecoreSitemapFetcher. In case of SSR, [[…path]].tsx will have an implementation of GetServerSideProps

Image Source: https://doc.sitecore.com/xp/en/developers/hd/190/sitecore-headless-development/image/uuid-cd7c0afe-f8d8-2c65-ba4c-c4af0a97064f.svg

Now, back to NextJS World,

All these we explored was before Next.js 13.4. From Next.js 13.4 instead of Page Router, App Router is recommended. I don’t see Sitecore leveraged App Router yet (I may be wrong, I tried to find some supporting docs but I couldn’t find any) and moreover a recent Sitecore Next Js App I created has code that uses page router.

App Router:

  • Earlier we saw that NextJs provides file based routing ad for every new route(page) we need to create a file inside pages folder? With App router, we no longer need to have pages-only directory. Instead we have app folder
  • This helps us organize solution structure based on feature. (A Segregation similar to Helix – Feature module) called as Colocation in the NextJS world.
  • The main change that App Router brings in is the Server-centric routing as opposed to the client side routing used in page router.
"Unlike the pages directory which uses client-side routing, the App Router uses server-centric routing to align with Server Components and data fetching on the server. With server-centric routing, the client does not have to download a route map and the same request for Server Components can be used to look up routes. This optimization is useful for all applications but has a larger impact on applications with many routes."

More about App Router -> https://nextjs.org/docs/app/building-your-application/routing#server-centric-routing-with-client-side-navigation

  • Right now the existing page router will also work in Next.Js 13.4
Design a site like this with WordPress.com
Get started