Experience Sitecore ! | All posts by admin

Experience Sitecore !

More than 200 articles about the best DXP by Martin Miles

Sitecore XP vs XM Cloud full guide: which one to choose in 2025

 

1. Introduction

In the Sitecore world 2025, organizations face a pivotal choice between the Sitecore Experience Platform (XP) - the traditional all-in-one digital experience platform – and Sitecore XM Cloud, Sitecore's modern cloud-native SaaS CMS. This guide provides an expert breakdown of how these options compare across cost, maintenance, architecture, and capabilities, helping CTOs, architects, marketers, and senior developers make an informed decision. I aim to explain the total cost of ownership, hosting models, upgrade implications, development considerations, and special scenarios (such as greenfield vs. existing implementations, compliance needs, performance tuning, etc.) to cut through marketing fluff and fully evaluate trade-offs.

1. XP vs. XM Cloud at a Glance

  • High-Level Comparison Table

  • Summary of Differences Across Key Dimensions

2. Total Cost of Ownership and Maintenance

  • Licensing & Subscription Costs

  • Infrastructure & Operations

  • Upgrades & Lifecycle Costs

  • Personnel and Skills

  • Summary: Predictable Cost vs. Control

3. Upgrade and Lifecycle Management

  • XP Upgrade Timeline and Support Horizon

  • Evergreen SaaS Updates in XM Cloud

  • Content and Template Migration Compatibility

  • Compliance and DORA Lifecycle Implications

  • Planning Upgrade vs. Migration

4. Architecture and Hosting Models

  • Hosting Flexibility: XP vs XM Cloud

  • Headless Architecture in XM Cloud

  • Cloud-Native and CDN-First Approach

  • DevOps, Deployments, and Environment Management

  • Customization and Extensibility Limits

  • Hybrid Use Cases and Parallel Strategies

5. Greenfield Projects vs. Existing Implementations

  • 5.1 Greenfield: When to Choose XP or XM Cloud

    • Setup Speed and Development Stack

    • Features, Team Skills, and Cloud Strategy

  • 5.2 Existing XP Implementations: Upgrade or Migrate?

    • Feature Usage and xDB Analysis

    • Rebuilding vs. Migrating

    • Front-End, Forms, and Custom Integrations

    • Gradual Migration Options

    • Business Case and ROI Evaluation

6. Compliance and Geographic Hosting Considerations

  • GDPR and Data Residency

  • HIPAA, PCI DSS, and Regulated Data Use

  • Financial Sector: DORA and ICT Risk

  • China and Other Geo-Restricted Markets

  • Summary: When XP Wins on Localization and Data Control

7. Performance and Optimization Strategies

  • Out-of-the-Box Performance

  • Caching and CDN Integration

  • Scalability Approaches and Overheads

  • Personalization Performance Impacts

  • Deployment Reliability and Zero-Downtime Releases

  • Monitoring, Logging, and Site Resilience

  • Optimization Techniques and Real-World Examples

  • Total Cost of Optimization

8. Conclusion and Recommendations

  • XP: When It Still Makes Sense

  • XM Cloud: Future-Ready by Design

  • Choosing with Confidence: A Strategic Lens

  • Phased Adoption and Preparing for Change

 

2. XP vs. XM Cloud differences at a glance

Let's start with the table below that summarizes key differences between Sitecore XP and Sitecore XM Cloud:

Aspect Sitecore XP (Experience Platform) Sitecore XM Cloud (SaaS)
Hosting Model Self-managed on-premises or in your cloud (Azure/AWS VM, PaaS, containers) – full control of servers and configuration. Fully managed by Sitecore as a SaaS multi-tenant service. No direct server management; requires a separate front-end host (e.g. Vercel, Netlify) for site delivery.
Cost Structure Traditional license (perpetual still often met + annual maintenance) plus infrastructure and operations costs. You take cloud/on-prem hosting expenses and support staff. Subscription-based (annual SaaS fee tied to usage/traffic). Sitecore covers core infrastructure. Front-end hosting comes at an additional cost, you’ll pay a provider like Vercel/Netlify for the rendering host.
Upgrades Periodic manual upgrades are required, major upgrades come every ~1-2 years, plus regular patches. These can be large projects, incurring significant time/cost with no direct business feature gains. You control when to upgrade, but falling behind risks end-of-life support. Auto-updated – no manual upgrades at all. Sitecore continuously rolls out new features and fixes. This eliminates costly upgrade projects and ensures you’re always on the latest version. However, you still must accommodate changes in your solution as the platform evolves, for example, updating the rendering host with the latest headless SDKs.
Maintenance & Scaling You manage all infrastructure: provisioning servers, applying OS/Sitecore patches, scaling out for traffic, and monitoring performance. High operational overhead (DevOps, DBA, etc.) is on your team. Scaling requires adding instances or resources, often with lead time and cost. Maintenance offloaded to Sitecore – the SaaS platform handles OS updates, security patches, and scaling automatically. The content delivery occurs via Sitecore's global Experience Edge service, so scaling for traffic bursts is largely transparent. You still manage your front-end app’s scaling (which is solved easily via global hosting providers).
Architecture All-in-one DXP: the CMS, presentation (ASP.NET renderings), and customer data (xDB) live within the same single platform. Can operate in traditional coupled mode or hybrid headless with optional Headless (JSS) Services module. Headless & composable by design: XM Cloud provides content management and an API layer through GraphQL/Edge. No built-in rendering of web pages – a separate "head" (most likely a Next.js app) consumes the content. Embraces JAMstack principles for a fully decoupled front-end. Integration with other SaaS components (such as Personalize, Send, etc.) for marketing features is expected, known as the Composable DXP.
Development Model Typically .NET-centric. Websites are built with ASP.NET MVC or .NET Core (for headless JSS) running within Sitecore. Deep Sitecore knowledge (pipelines, config patches, deployment topology) is required. Smaller talent pool; Sitecore-specific training needed. Extensive backend extensibility, one can write custom processors and integrate deeply. Modern JS/React-centric. Front-end built in Next.js or another framework using Sitecore’s Headless SDK. Common web development skills such as React/TypeScript apply, making it easier to staff projects. Less low-level backend customization – you extend via APIs and webhooks rather than patching Sitecore’s core. Faster local setup by using Docker containers or through connected mode to a cloud instance directly.
Content Editing Rich client interfaces - Sitecore Content Editor and older Experience Editor for inline editing. Familiar to long-time Sitecore users, but can be clunky and slow. Full control of content taxonomy and presentation details, but legacy UI. New Sitecore Pages and Explorer interfaces for content authoring, which are more intuitive, single-page-app style authoring for pages and components. Legacy Content Editor is still available for now. Overall, authoring UX is improved and more streamlined in XM Cloud.
Out-of-the-Box Marketing Features Complete marketing suite: multi-session personalization, user tracking via xProfile/xDB, marketing automation campaigns, email via EXM, path analyzer, etc. All these are included under XP’s umbrella. However, they require significant configuration and infrastructure (for xConnect, processing servers, etc.), and because of that, many organizations underutilize these advanced capabilities. Content-focused: XM Cloud omits the built-in xDB. It offers mostly in-session personalization only (rules that react to the current visit context) and basic analytics. Features like marketing automation, CRM connectors, and email marketing are not included out-of-the-box - you’re expected to use separate SaaS products (such as Sitecore Personalize & CDP, Send, etc.) if you need those capabilities. This keeps the core platform lean but means a composable approach to marketing.
Personalization Depth Robust multi-session personalization: XP tracks each contact’s behavior across visits and builds a rich profile in xDB. You can target content based on historical data, profiles/personas, and engagement values. Great for long-tail personalization, but requires managing the xDB database and GDPR compliance for stored personal data. Session-scoped personalization: XM Cloud’s built-in engine can target content by current context (current page, referral campaign, geolocation, etc.), similar to XM on-prem, but does not remember the visitor once the session ends. For multi-session personalization, you must integrate Sitecore CDP & Personalize, which is sometimes bundled or available alongside XM Cloud. In practice, many XM Cloud adopters add Sitecore Personalize to match or exceed XP’s personalization power.
Compliance & Hosting Flexibility Full control over where and how the system runs. You can host in specific regions or private clouds to meet data residency, GDPR, HIPAA, DORA, or other regulatory needs. If needed, XP can run in a secure on-prem datacenter, within country borders, or even in globally disconnected environments. This flexibility can address strict compliance scenarios, though the effort is on you to secure and certify such an installation. Region selection for data is offered, but you cannot self-host XM Cloud. Sitecore runs it in their cloud (Azure or AWS) with region options to keep customer data in a chosen geography. Sitecore’s cloud is certified (ISO 27001, SOC2, etc.). However, if you have an extreme requirement like an air-gapped network or a country with no approved region, XM Cloud may not be viable.
Support Lifecycle Sitecore has committed to continuing XP/XM on-prem support for several years. For example, XP/XM 10.4 will have mainstream support until the end of 2027 and extended support until 2030. This gives existing XP users a runway to remain on-prem for now. However, older versions will hit end-of-life sooner, forcing upgrades to stay supported. Long-term, Sitecore’s strategic focus is on cloud offerings, so new features will tilt toward XM Cloud and composable products. As a SaaS product, XM Cloud is continuously supported and updated by Sitecore. Subscribers are always on a supported version by definition. Sitecore’s roadmap for new capabilities is heavily invested here, so XM Cloud users will see the lion’s share of innovation going forward.

Table: High-level comparison of Sitecore XP vs. Sitecore XM Cloud in 2025.

As the table suggests, XM Cloud represents a shift to a cloud-native, headless, and service-based paradigm. Meanwhile, XP offers a do-it-yourself, all-in-one environment with maximal control and integrated features (at the cost of complexity). The following sections dive deeper into specific considerations: cost of ownership, greenfield vs. migration scenarios, compliance constraints, and optimization strategies for performance and deployment.

 

3. Total cost of ownership and maintenance

Licensing & Subscription Costs: One of the first factors to evaluate is cost. Sitecore XP traditionally involves a sizeable license fee, often perpetual or long-term, plus annual maintenance fees. If you already own an XP license, you might only be paying maintenance annually. In contrast, Sitecore XM Cloud is sold as a subscription SaaS product - you essentially pay for a recurring subscription that includes the software and its managed hosting. The XM Cloud subscription cost is generally usage-based, simplified to factor in traffic, number of Content Management environments, etc., which can be a double-edged sword: if your sites see very high traffic, the SaaS fees might scale up, but for moderate usage, you pay only for what you need. XP’s costs, on the other hand, are more fixed in terms of licensing, but infrastructure costs are on you - cloud VMs, SQL licenses, content delivery servers, etc., all that adds to the TCO.

Infrastructure & Operations: With XP, you bear the cost of infrastructure and IT operations. This means provisioning servers (or Azure App Services), managing SQL databases, search servers (Solr), CD servers behind load balancers, plus the manpower to monitor and support them. You might need skilled infrastructure/DevOps personnel or a managed cloud contract. By contrast, XM Cloud shifts most of that burden to Sitecore. The subscription includes the managed Sitecore Cloud portal and hosting of the core CMs and Experience Edge. You don’t pay separately for SQL or Solr – those are hidden behind the actual SaaS product. Operational tasks like OS patches, security updates, scaling infrastructure, and performance tuning at the server level are handled by Sitecore. This can dramatically reduce the maintenance labor on your side and thus lower the operational cost by eliminating the need to manage and maintain your own infrastructure.

However, note that XM Cloud doesn’t include the front-end delivery environment – you still need to host the actual website application (the “head”) on a platform of your choice. For example, if you build a Next.js site, you might host it on Vercel, Netlify, etc. That hosting cost is separate and must be added to your TCO calculations. In an XP scenario, your "front-end" and content delivery are part of the same hosting cost for your CD servers. In XM Cloud, the CMS is hosted by Sitecore within an included subscription, but the rendering host is not. The upside is that front-end hosting, especially static/JAMstack (SSG) apps, can be very cheap and scales with usage. Many find the cost of Vercel to be relatively low compared to keeping multiple high-spec Sitecore CD servers running 24/7.

Upgrades & Lifecycle Costs: Perhaps the biggest cost saver for XM Cloud is the elimination of version upgrade effort. With XP, every few years you face a significant upgrade effort – planning, regression testing, updating custom code, and sometimes content migrations – just to stay on a supported version. These projects incur not only services cost but also opportunity costs - time that could be spent building new features. As an example, a typical enterprise XP upgrade (say from 9.x to 10.x) could take months of work. XM Cloud goes away with this - Sitecore handles all upgrades in the background, delivering improvements continuously. For the customer, this simply means "no more Sitecore upgrades"which brings huge savings in money and time. You’ll always say on the latest version without dedicating effort and budget to get there.

From a lifecycle perspective, Sitecore has committed to supporting XP for several more years - XP 10.4 mainstream support until the end of 2027, and extended to 2030. So you won’t be forced off XP immediately. However, continuing to use XP means you likely will need to upgrade to 10.4 if you haven’t yet, to enjoy that support window, which itself is a near-term cost if you are on an older version. In contrast, XM Cloud’s evergreen nature means the concept of end-of-life is moot – you’re always current. The cost implication is that while you save on periodic upgrade projects, you do need to invest continuously in keeping your solution compatible by testing your integration and front-end when Sitecore updates the backend. Fortunately, backward compatibility in XM Cloud is maintained carefully, and changes are incremental.

Personnel and Skills: Cost of ownership also ties to the team required. Running XP often demands Sitecore-specialized developers, DevOps, server admins, and possibly managed services contracts, which can be costly. XM Cloud shifts the required skill profile: you’ll need front-end developers and perhaps cloud architects familiar with modern deployment, but you might reduce the need for full-time Sitecore ops experts. As noted earlier, the pool of JavaScript/Next.js developers is way larger and often less expensive than the niche pool of Sitecore backend developers. This can lower staffing costs or allow your existing team to focus on front-end innovation rather than low-level CMS tweaks.

In summary, XM Cloud tends to have a lower operational cost and a more predictable subscription model, whereas XP might have a lower software cost if you already own licenses but will incur higher maintenance effort. When calculating TCO, consider a multi-year horizon: XM Cloud’s subscription plus front-end hosting vs. XP’s license and maintenance plus the cumulative cost of VMs, support contracts, and an eventual upgrade. Many organizations find that when factoring in the soft costs (downtime, upgrade labor, performance tuning), XM Cloud delivers savings. But every case is unique – if your XP environment is stable, paid for, and lightly maintained, and your organization isn’t in a position to invest in re-development, the pure dollar savings of XM Cloud might not be realized until further down the road.

 4. Upgrade and Lifecycle Management

Upgrades have been the pain for many Sitecore teams historically. With XP, you control if and when to upgrade, but you must upgrade eventually to stay supported, and those projects can be major undertakings. Sitecore XP/XM platforms 10.4 are the "last" of on-prem releases as of today, and Sitecore has pledged continued support, up to 2030, with extended support, which means orgs can comfortably stay on XP 10.4 for the next few years with regular support. If you’re on an earlier version (e.g., 9.3 or 10.1), you will have to upgrade to at least 10.4 to stay within that window, which means a near-term effort anyway. Some companies are choosing to do that upgrade, then evaluate moving to XM Cloud later, while others are considering leaping straight to XM Cloud instead of executing another on-prem upgrade.

XM Cloud’s model is a huge change - you avoid the cycle of "wait for new version -> plan upgrade -> execute -> troubleshoot". From a lifecycle management standpoint, this is a relief: your platform is always current and fully supported. Sitecore delivers updates in a backward-compatible way and typically provides notice of any breaking changes. As a customer, you’ll want to have a process to validate your solution against new releases, but you won’t need to allocate large budgets for these updates.

One thing to consider is data and content migration in the context of moving to XM Cloud. If you are currently on XP and decide to replatform to XM Cloud, that migration project essentially stands in place of an upgrade project. Content can be serialized and migrated, and most customers can bring over all their content, media, and templates into XM Cloud relatively intact, meaning Sitecore has ensured backward compatibility in the content schema. But as we’ll discuss below, your custom code and front-end are not portable as-is. This is less about the platform upgrade and more about rebuilding on a new architecture.

Another lifecycle aspect is vendor support and roadmap. Sitecore’s roadmap for on-prem XP beyond version 10.4 is expected to be mostly maintenance and minor improvements, whereas XM Cloud and the composable SaaS products will get the bulk of innovation - AI-driven authoring assistance, new integrations, etc. If having the latest and greatest features is important, XM Cloud aligns with that path. If your priority is a stable, unchanging platform, XP can offer that at the cost of eventually aging technology.

Finally, consider how compliance regulations like DORA impact the lifecycle. For financial services in the EU, DORA requires that ICT providers (like Sitecore, if you use XM Cloud) adhere to strong resilience and incident reporting. Sitecore is not directly under DORA as a non-financial entity, but they have updated agreements to help customers comply. For an XP on-prem installation, you, as the operator, would bear the burden of meeting operational resilience standards. That includes doing regular disaster recovery drills, ensuring you can recover from incidents, etc. In a sense, letting Sitecore handle that via XM Cloud could simplify compliance - they state they offer "robust security measures to ensure resilience and availability" and will support customers’ DORA obligations. However, some organizations may prefer the control of managing their environment to meet specific internal policies. It’s a trade-off between trusting the vendor’s managed service vs. doing it yourself under your own compliance regime.

Bottom line on upgrades: If you are tired of the upgrade treadmill, XM Cloud is extremely attractive – it ends the cycle of expensive upgrades and ensures you’re always up-to-date. If, on the other hand, you like having full control of when to change your system (like some enterprises freeze tech changes for long periods), XP allows you to stay static despite being unsupported after a point. Many see the writing on the wall that by 2025 and beyond, continuously updated SaaS is the norm, and planning for that model (with proper testing processes) is wiser than clinging to a static version. Sitecore has given XP a generous support timeline, so there’s no immediate panic to switch, but the advantages of not having to plan another upgrade are compelling to most.


5. Architecture and Hosting Models

The architectural differences between XP and XM Cloud are fundamental. Sitecore XP is a monolithic application in the sense that all its services - content management, content delivery, processing, tracking - work together as a single product suite running in a single environment. They can certainly be scaled out individually (multiple CD servers, separate roles), but it remains one big platform under your control. Sitecore XM Cloud is a cloud-native SaaS that embraces a decoupled architecture: the content backend and the presentation frontend are completely separate by design.

Hosting Flexibility (XP): With XP, you have numerous hosting options. You can deploy on-premises on your own hardware, in a private cloud, or on public cloud IaaS. Some run XP on Azure PaaS with Sitecore Managed Cloud platform-as-a-service hosting of XP, or even containerize it on Kubernetes. Single-tenant is the norm – your Sitecore installation is dedicated to you, even if managed by a third party. This flexibility is a double-edged sword: you can satisfy unique requirements (custom networking, specific region, or even specific servers for compliance, integration with legacy systems, etc.), but you also have to manage all the complexity that comes with it. If you need to, for example, deploy a content delivery instance in China or in a DMZ environment, XP lets you do that.

Hosting Model (XM Cloud): XM Cloud is only offered as SaaS by Sitecore – you cannot host XM Cloud yourself. It runs in the Sitecore cloud environment, leveraging Azure and AWS under the hood. It’s a multi-tenant (many customers on the same SaaS platform, logically separated). You get an organization and project space in the Sitecore Cloud Portal where you can create environments, typically production, staging, and development. Sitecore handles provisioning those, and you simply deploy your code and content. There is no concept of installing Sitecore on your server - instead, you deploy your serialization packages and front-end builds to their service. The front-end rendering host, however, is your responsibility to host. The typical pattern is to use a JAMstack approach: for example, host the Next.js app on a platform like Vercel. In fact, Sitecore specifically encourages using Vercel or Netlify for XM Cloud front-ends, noting that these platforms are specifically designed for high-performance websites and integrate very well. Some companies choose to host the front-end themselves, for example, on an internal Kubernetes cluster or Azure App Service, but Sitecore guidance is to leverage modern cloud hosting for that purpose, achieving the best results.

Implications for Cloud-Native Services: Because XM Cloud decouples the roles, you gain the ability to use cloud-native edge networks out of the box. With XP, if you wanted to use an edge CDN or a service like Vercel’s edge functions, you had to configure that on top of Sitecore, often in a limited way. In XM Cloud, the Sitecore Experience Edge service gives globally replicated content APIs, and your front-end can be deployed globally as well. This means things like SSR (Server-Side Rendering) can happen at edge nodes close to users, and static content can be cached on CDNs easily. In XP’s traditional model, the content delivery server itself often lived in one region, or a couple of regional data centers you set up, so global users might have higher latency unless you implemented your own CDN caching layer. XM Cloud largely solves global delivery by design.

Content Delivery Differences: In XP, content delivery is handled by Sitecore’s own ASP.NET application at the CD server running the site. In XM Cloud, content delivery is headless - the CMS does not directly serve end-user pages. Instead, it exposes content via GraphQL APIs, and a separate rendering host application generates the pages. This means if you choose XM Cloud, you are committing to a headless architecture for your sites. The benefit here is flexibility and performance. The trade-off is that assembly effort is required - you have to build a front-end application to consume the content. In XP, if you used something like Sitecore SXA or MVC, a lot of the presentation came out of the box. In XM Cloud, Sitecore provides starter kits for Next.js and other systems, but you will be building the presentation layer with a front-end framework, not with Sitecore’s layout engine. This is a key consideration: organizations comfortable with modern front-end development will see this as liberating; organizations that liked Sitecore’s all-in-one approach to layout and rendering will have to adapt.

DevOps and Environment Management: In XP, you might have multiple environments (dev, QA, prod), each as separate Sitecore instances you manage. With XM Cloud, Sitecore provides environment slots for you. For example, a typical XM Cloud subscription might include 3 environments (production, and two non-prod like UAT and integration). These are easily spun up via the portal. The deployment process is built-in: you connect a source repository (GitHub or Azure DevOps) to the Sitecore Deploy App, and it can automatically build and deploy your code to the XM Cloud environments. This is a more streamlined DevOps experience compared to manually deploying items and code to an XP server. It even de facto supports blue-green deployments for zero-downtime releases when the platform can keep the previous instance running while swapping in the new one.

For a technical team, this means less time setting up build/release pipelines from scratch - Sitecore provides a lot of that out of the box in XM Cloud. For XP, you typically need to create CI/CD scripts or use tools like Octopus Deploy to deploy Sitecore packages, and coordinate things like content serialization, etc., which is more effort.

Extensibility and Customization: In a traditional XP solution, developers can deeply customize the system – pipeline processors, custom Sitecore jobs, and low-level tweaks to how the CMS behaves. With XM Cloud, because it’s a managed SaaS, you should not modify core pipeline code on the server. Customization is achieved either through high-level configuration or by writing code in the front-end or external services. For example, if you had a complex content cleansing pipeline on item save in XP, in XM Cloud, you might implement that via a webhook or by a scheduled external function that uses the GraphQL content API to enforce rules. You also currently cannot use some XP modules or custom Solr indexes in XM Cloud. This means heavy customizations might need re-architecture. The advantage is that you are constrained to more upgrade-safe approaches, but the disadvantage is less freedom to bend the platform to unique needs. This is an architectural philosophy shift: XM Cloud aims for configuration over customization to maintain stability in a multi-tenant cloud.

Hybrid Possibilities: It’s worth noting that some organizations consider a hybrid approach - keeping an on-prem XP for certain sites or functions while starting to progressively build new experiences on XM Cloud. Sitecore's composable lineup is designed to allow mixing: for instance, you could continue using XP for its xDB-driven personalization on an existing site, but launch a new microsite on XM Cloud + Sitecore Personalize and perhaps have both share the same Sitecore CDP for customer data. This is complex, but it highlights that choosing XM Cloud doesn’t necessarily mean abandoning everything at once. That said, running two parallel CMS platforms has its own cost and is usually a temporary state.

In summary, architecturally, XM Cloud is aligned with modern cloud architecture principles - multi-tenant SaaS, globally distributed delivery, microservices, content as a service, personalization as a separate service, etc., whereas XP is a single-tenant application architecture that you tailor to your environment. If your organization values complete control over the hosting environment and data flow, XP offers that, you can even access the database directly, etc., which you absolutely cannot do with XM Cloud. If instead you value simplicity, scalability, and cloud-first design, XM Cloud clearly leads. One key question: Do you require on-premises or specific-region hosting that Sitecore doesn’t support? If yes, that’s a strong case for XP, or at least XM on Managed Cloud, which still gives region control. For example, if you need to host in mainland China for a China site (due to ICP license rules), XM Cloud hosted on Western infrastructure will face significant performance challenges in China and potentially legal barriers, whereas XP could be stood up in China for example on Azure China or Alibaba, to comply. I will talk you through compliance and geographic requirements below.

Choose XM Cloud when you want to offload ops, speed launches, and lock in predictable costs and continuous updates. Stay on XP or self-hosted XM if you need full control over data residency due to the specific compliance/regulations requirements for your organization, have heavy legacy code, or require advanced multi-session personalization today. Either way, your path should match your team’s skills, your compliance needs, and your growth plans.


6. Greenfield Projects vs. Existing Implementations


The decision process can differ significantly if you’re starting a brand-new project (aka greenfield) versus if you have an existing Sitecore XP solution. Let’s address both scenarios:

6.1 Greenfield Projects – When to Choose XM Cloud or XP?

For new digital experience initiatives, the general industry momentum and Sitecore’s own strategy favor XM Cloud. If you are not weighed down by legacy, XM Cloud often makes sense because you can architect from scratch with modern best practices and won’t have to redo things later to keep up with Sitecore’s cloud direction. Key considerations:

  • Time to Market & Initial Setup: XM Cloud can be provisioned quickly due to no need to install Sitecore or set up servers. For a new project, this means you get a working CMS environment in days, not weeks. You can also leverage starter templates, such as Sitecore’s Next.js starter kit, to jumpstart development. If speed is critical, this agility is valuable. XP, by contrast, would require setting up at least a CMS and CD server, installing the software, configuring scaling, etc. - a slower ramp-up.

  • Future-Proofing: A new project built on XP in 2025 might risk becoming technical debt sooner. Sitecore’s major innovations (e.g., new AI content features, deeper integration of Content Hub, etc.) will likely be cloud-first. Adopting XM Cloud means you’ll automatically get those enhancements. With XP, you might find in a couple of years that the capabilities lag behind unless you integrate additional SaaS components anyway. Starting on XM Cloud sets you on the vendor’s forward-looking path from day one.

  • Team Skill Set: Starting a greenfield on XM Cloud is ideal if your development team (or your implementation partner) has strong React/Next.js skills and is comfortable with headless CMS concepts. Many agencies and new developers prefer working with the JAMstack approach as it aligns with modern development practices. If, hypothetically, your team were mostly back-end .NET developers with no modern front-end experience, they might have a learning curve. However, given industry trends, most teams have adapted or can pick up Next.js fairly quickly. Sitecore XP development with MVC and Razor might actually be harder to ramp up for new developers who lack a Sitecore background, whereas XM Cloud development can be more approachable since it uses familiar web tech and just calls an API for content. So, for new projects, assessing your technology comfort is important. In almost all cases, though, I would advocate building new experiences with headless architecture to avoid being stuck in older paradigms.

  • Organization Strategy: If your organization has a cloud-first mandate or is embracing SaaS for other systems (CRM, commerce, etc.), starting on XM Cloud fits well. If, instead, there is still a preference for on-prem control (some government or defense projects, for example, might not be ready to put content in a SaaS), then XP could be chosen to satisfy that policy. But in 2025, even regulated industries are increasingly allowing SaaS for CMS after due diligence, because CMS content is often not highly sensitive data (with exceptions). It’s more common to see resistance to cloud for things like customer data, but note, XP itself stores customer data (xDB), whereas XM Cloud (without CDP) does not store much personal data by default. In a way, XM Cloud can be easier to get through security review than XP because it’s mostly content-focused (pages, text, media) rather than PII.

In summary, for new projects, XM Cloud is usually the recommended choice unless you have a very unique reason to deploy and manage everything yourself. It offers faster setup, easier scaling as you grow, and avoids locking you into legacy architecture. One might still choose XP for greenfield if, for example, the project is an internal application that must run on an internal network with no external cloud dependencies, or if the feature set of XP aligns perfectly without needing any of Sitecore’s composable add-ons, and you want to avoid a multi-system solution. But those cases are increasingly rare. Most new digital experience builds want a modern, performant, and low-maintenance foundation, which XM Cloud provides.

6.2 Existing Sitecore Implementations – Stay on XP or Move to XM Cloud?

If you already have a Sitecore XP or XM solution running, the question becomes when or whether to migrate to XM Cloud. This is a complex decision with technical and business angles:

Assess Feature Usage: A critical first step is to determine how much of the XP platform you are actually using. Many Sitecore XP customers purchased the platform for its potential (personalization, xDB analytics, etc.), but over time, ended up using it mostly as a robust CMS, with minimal use of the fancy marketing features. It’s noted that very few organizations have the operational capacity to make full use of XP’s personalization capabilities, not to mention marketing automation. If you find that you are not leveraging xConnect/xDB (no custom profiles, no multi-session personalization rules, no marketing automation campaigns running), effectively, you might be using the XM subset of features already. In that case, moving to XM Cloud will not strip your solution of capabilities you actually use - it will likely be a smoother transition functionally. On the other hand, if you heavily depend on, say, Sitecore Marketing Automation for personalized email campaigns, or you have dozens of personas with tailored experiences on the site based on past behavior, you need to plan how those will be re-implemented. XM Cloud alone won’t provide those; you’d need to bring in Sitecore CDP & Personalize, Sitecore Send (for email), etc., as part of the migration. That introduces additional cost for separate subscriptions and effort to integrate. The upside is that those composable tools are more advanced in their domains, for instance, Sitecore Personalize can do real-time, AI-driven personalization across channels, which could outperform what you built on XP, but it takes work to configure.

Migration Effort – Front-end Rebuild: It must be stated plainly: moving from XP to XM Cloud is not an in-place upgrade; it is essentially a re-implementation: a whole new frontend must be established on a new technologyThis is crucial to set expectations with stakeholders. If your existing site was built with MVC and Razor views in Sitecore, those renderings will not run on XM Cloud’s Next.js front-end. You will need to rewrite the presentation layer. Content can be migrated, and your content and templates are intact on the new side, which is a relief, but all the code that rendered that content in XP (layouts, rendering, controllers, etc.) must be redone in the new stack. If you have a large, complex site, this is a non-trivial effort.

On the bright side, you can reuse assets: HTML markup and CSS can largely be carried over into the new front-end, also any client-side JS logic can often be reused. It’s the server-side C# logic that must be translated into the React/Next.js world. Many find that this is an opportunity to clean up and modernize. Maybe your site’s UI could benefit from a refresh - some clients time the migration with a minor redesign so that rewriting the front-end yields a better UX as well. If you recently did a heavy investment in a new XP-based site (e.g., a big redesign last year on XP), the thought of rebuilding it so soon may be unwelcome. In that case, sticking with XP a bit longer to get the value out of that investment is understandable. If your site is due for a redesign or technology refresh anyway, that’s an ideal time to combine it with a move to XM Cloud.

What if you already built your XP site in a headless/hybrid way? For example, some XP projects in recent years used Sitecore JSS with React, essentially treating XP as a headless content source. Such a project is much easier to migrate - in fact, your front-end code (React app) could probably connect to XM Cloud with minimal changes. Just point to the new GraphQL endpoint and adjust API keys. If you’re in that fortunate situation, the migration becomes more about moving content and testing rather than rewriting everything. Essentially, you’d be swapping the content backend from XP to XM Cloud and perhaps replacing XP-specific services (like if you used xDB data, you’d swap to CDP).

Integration and Customization Migration: Look at any integrations your XP solution has - say, CRM integration, eCommerce integration, search providers, etc. If those were done via direct access to XP databases or internal APIs, they’ll all need to be redone to use XM Cloud’s APIs. If you used something like Sitecore xConnect to push data to CRM, in XM Cloud, you might instead use a combination of Sitecore Connect or direct API calls to CDP. Also, any custom modules (perhaps you built custom workflow actions, or you extended the Experience Editor with custom buttons) must be evaluated. Some may not be possible in XM Cloud yet. For instance, Sitecore Forms were not initially supported in XM Cloud - a workaround was required for forms in headless apps. These gaps are closing as Sitecore invests in XM Cloud, for example, forms support was added later, but it underscores that a migration requires a thorough gap analysis.

Cost-Benefit Analysis: From a business perspective, you must weigh the cost of staying on XP vs. migrating to XM Cloud. Staying on XP is not "free" - you will likely need to upgrade to keep support (cost), you continue to run servers (cost), and you may be missing out on performance or productivity gains (opportunity cost). Migrating has an upfront cost of rebuilding and retraining, but promises savings and improvements after. One recommended approach is to build a business case enumerating these factors. For example, if moving to XM Cloud will eliminate $X of hosting costs annually and $Y of upgrade costs every few years, and perhaps increase conversion by Z% due to better performance, can those justify the migration project expense in ROI terms? Often, after a few years, the migration pays for itself just in savings. It’s not always purely financial; agility and future readiness are part of the value.

Organizational Readiness: Change management is also important. Your content authors will have a new interface (though not drastically different, and likely more user-friendly). Your IT team’s responsibilities shift - some roles (server admin) might be less needed, while others (front-end DevOps) become key. You may need to train developers on Next.js and familiarize them with XM Cloud tooling (CLI, serialization via Git, etc.). If your team is not ready, consider investing in training or engaging with a Sitecore partner who has done XM Cloud projects. Some organizations pilot XM Cloud on a smaller project first (migrate a microsite or lesser-trafficked site) to build experience, then tackle the main site. This can de-risk the process.

Gradual Migration vs. Big Bang: You do have the option to move in phases. You could start by downgrading XP to XM, turning off xConnect on your existing instance, and essentially running XP as if it were XM with only in-session personalization. This could simplify your current environment (no xDB) and get authors used to less personalization. Then you could move that to XM Cloud. Or, you could migrate one site at a time if your XP instance hosts multiple sites. In some cases, organizations keep XP running for a period for certain functions (like serving personalization to known users) while launching a new site on XM Cloud for anonymous or new audiences, and then gradually phase out XP. These approaches add complexity but reduce risk by avoiding an all-or-nothing switch on day one.

When does it make sense to stay on XP? After all this, there are valid reasons some will stay on XP in 2025:

  • Regulatory Constraints: If you absolutely cannot use a SaaS for CMS due to data control requirements, say for some government agencies or in highly sensitive content scenarios, then XP or perhaps XM in a self-managed mode is the way to go. You maintain full control and can deploy in hardened environments as needed.

  • Full Use of XP Features: If you are one of the few that deeply use XP’s marketing suite and it’s running well, you might not want to break what's working. For example, if you have a mature personalization program leveraging historical profiles and automated campaigns that drive real ROI, you might decide to stick with XP until Sitecore’s composable equivalents prove they can meet or exceed that functionality with acceptable cost. In parallel, you might start testing Personalize or CDP to see if a switch is feasible later.

  • Short-term Horizon or Alternative Plans: If your organization is, say, 1-2 years away from a broader digital transformation or considering alternate platforms, you might not undertake a migration to XM Cloud now. For instance, some companies on XP are evaluating not just XM Cloud but also competitors or more lightweight CMS options. If you haven’t decided on the long-term platform, you may prefer to keep XP running "as-is" (with maybe a minimal upgrade) as a stop-gap until a larger replatform decision is made. XM Cloud is one path, but some XP customers could even decide to move to a completely different CMS, though that also is a rebuild. It’s outside our scope, but it’s worth acknowledging that XP customers should evaluate all options – in other words, moving off XP doesn’t only mean XM Cloud; it could mean a competitor’s SaaS. Of course, as a Sitecore guide, we focus on XM Cloud as the intended upgrade path.

  • Budget Constraints in the Near Term: If the migration cost cannot be justified or funded this year, you might delay until budget allows. In the meantime, ensuring you’re on a supported XP version and maybe optimizing that environment is reasonable.

When does it make sense to move to XM Cloud from XP? Generally:

  • When you realize your team is spending more time "keeping the lights on" with XP (patches, Azure costs, troubleshooting scaling issues, etc.) than on building new digital value. XM Cloud frees you from a lot of that maintenance toil.

  • When site performance or deployment pain is holding back your digital efforts, and you see that a headless, cloud-native architecture will alleviate those, which it often does, as we’ll cover in optimization.

  • When the cost of Sitecore XP (license + infra) compared to the value you get is being questioned, and moving to XM Cloud either reduces cost or increases value (for example, giving marketers a faster way to launch pages, which can translate to business revenue gains).

  • If your organization has adopted a composable stack approach – for instance, you already use a separate commerce engine, a separate DAM (Content Hub or others), maybe a separate analytics tool – then XP’s all-in-one value is less important, and XM Cloud will integrate better with a composable ecosystem.

  • If you’re looking to modernize the solution, maybe your XP implementation is 5-6 years old, design is stale, and technical debt is high; it might be easier to start fresh on XM Cloud than to upgrade and refactor an aging XP codebase.

One more angle: XM Cloud vs. XP "as XM". Some customers on XP have the option to downgrade their license to XM (content-only) and possibly stick with self-managed XM, which is XP without xDB. This can save license costs while still running the instance yourself. However, that approach gives up the tracking features but keeps the hosting burden. It’s a half-measure that some use if they want to stop running xDB but aren’t ready to go SaaS. In deciding XM Cloud vs staying on XP, consider if running XP just as a CMS is worth it compared to XM Cloud – likely not, because all the maintenance remains, but you’re not leveraging XP’s unique features. In such a scenario, XM Cloud is a better target to eliminate the maintenance as well.

Conclusion for existing implementations: Evaluate what you use, what you gain, and what you’ll spend in a migration. If your XP implementation is underused (typical case: using it as an expensive CMS), the argument to migrate is strong – you can likely cut costs and improve performance by shedding the xDB weight and moving to XM Cloud. If your XP implementation is delivering on its promise and deeply embedded in your marketing operations, plan a migration more cautiously - perhaps wait until Sitecore’s composable tools mature further or do a pilot. But keep an eye on the support timeline; even the best XP 10.4 implementation will face end of mainstream support by 2027. For many, the question is not if to move to XM Cloud or a similar SaaS model, but when - doing it proactively, on your terms, is better than being forced later under time pressure.


7. Compliance and Geographic Hosting Considerations
Every organization must consider regulatory requirements, and the CMS platform choice can be influenced by how well XP or XM Cloud meets those needs. I have discussed several common compliance and localization factors in a separate blog post.


8. Performance and Optimization Strategies on XP vs. XM Cloud

 One of the most tangible differences teams experience is in site performance, scalability, and the effort needed to optimize each platform. Both XP and XM Cloud can deliver high-performance experiences, but the approaches differ.

Out-of-the-Box Performance

Sitecore XP: In its traditional mode, XP generates pages server-side for each request unless heavily cached. The performance of your site is tied to the power of your content delivery servers and how well the code and caching are implemented. XP sites can be optimized to be fast, but it requires tuning: item caching, output caching for components, preloading data, etc. Even then, achieving near-instant page loads globally is challenging because the content has to be fetched from the server, which might be far from the user. Many XP implementations struggled to achieve top-tier Google Lighthouse or Core Web Vitals scores due to the inherent overhead of server-side assembly and the weight of the Sitecore rendering pipeline. Getting legacy architectures to match the performance of static sites is extremely difficult.

Sitecore XM Cloud: Performance is a strong point here because of the headless JAMstack approach. Websites built on XM Cloud are typically either static, pre-generated, or server-side rendered at Edge, both of which can drastically reduce latency to users. For example, with Next.js, you can pre-build pages (Static Site Generation) so that they are just HTML files served via CDN, yielding extremely fast first-byte times. Or you use Incremental Static Regeneration (ISR) to update content periodically while still serving cached pages. Even for dynamic content, SSR on a platform like Vercel runs on a global edge network. The result is that an XM Cloud-based site can be as snappy as a static website for most users. It’s common to see improved performance and scalability immediately by moving to a headless architecture - many teams report that after moving to a Next.js + XM Cloud setup, page load times and Lighthouse scores improve dramatically.

Caching and Content Delivery Networks (CDN)

XP Caching: XP supports output caching at the Sitecore rendering level where you can cache renderings by varying criteria, and has a robust object caching for items, media, etc. Using a CDN like Cloudflare/Akamai in front of XP can offload static assets (images, CSS, JS), but caching full HTML pages on the CDN is harder if personalization or login-specific content is involved since pages aren’t one-size-fits-all). Some XP deployments did set up whole-page CDN caching for public pages and used cache-busting or short TTLs to balance freshness. But doing so requires careful configuration to avoid serving the wrong personalized content to users.

XM Cloud + CDN: Here, the CDN (or edge) is integral. When you deploy your front-end on, say, Vercel, it automatically serves content via their CDN nodes around the world. If you pre-render pages, they are essentially static and cached indefinitely until revalidated. Out-of-the-box personalization in XM Cloud is largely in-session, meaning a cached page can be the same for all users, and then personalized bits can be swapped in after load (for instance, via client-side rendering of a personalized component). This strategy means you don’t forego caching for personalization – you just handle it differently with either edge logic or client logic. Additionally, XM Cloud’s Experience Edge caches content data globally, so the API calls themselves are fast. The result: high cache hit ratios and use of edge computing are standard with XM Cloud solutions. You might still fine-tune cache headers and revalidation logic (Next.js provides good controls for ISR and stale-while-revalidate patterns), but overall, achieving global low-latency delivery is simpler.

Scalability

XP Scalability: XP typically scales vertically or horizontally by adding more CD instances behind load balancers. It can handle a high load if properly scaled out, but it requires you to provision enough servers for peak load or use auto-scaling on cloud VMs. There’s also the scaling of the xConnect collection role to consider if you track many interactions – the xDB processing can become a bottleneck under heavy traffic with personalization. Many XP users have experienced that to handle spike traffic for a big one-off event or campaign, they need to spin up additional CD servers and ensure the caching is warmed, etc. That incurs cost for those peak times. Also, session state management and such need to be configured (sticky sessions or a distributed session state server) if using personalization per session.

XM Cloud Scalability: The content management and Edge APIs of XM Cloud are scaled by Sitecore automatically – they run in a cloud that can scale out to meet API demand, and Sitecore handles this as part of the service. Your front-end on Vercel or Netlify scales virtually infinitely - these services deploy your site across countless edge nodes. The result is that handling a spike in traffic is usually seamless: the CDN serves most content without hitting the origin; if many users hit uncached pages, the edge functions scale out. You don’t wake up at 2 am to add servers – it’s handled. There are limits (like API rate limits), but they are quite high, and you can engage Sitecore if you expect an extraordinary load, as they can provision accordingly. In short, scalability is a solved problem in the XM Cloud model: you pay for what you use, but you rarely worry about collapsing under load. Anecdotally, if a marketing team does a huge product launch, an XP setup might require careful load testing and pre-scaling; an XM Cloud setup, if built right, just flows that traffic through global CDNs.

One consideration: in XM Cloud, if you have heavy server-side compute logic in the rendering (like complex data mashups in getServerSideProps in Next), you’ll want to ensure your hosting platform can handle it. But generally, those computations are lightweight compared to what XP’s server did, generating full pages with personalization rules.

Personalization and Performance Trade-offs

XP Personalization: In XP, the more you personalize, the more cache fragmentation you get - every unique combination of personalization rules can cause a cache miss and trigger fresh page generation. This often forced teams to limit personalization to small regions or use "don’t vary by user" on most components. Also, tracking every visitor interaction had a performance cost on the xConnect/shard databases. Many XP sites for performance reasons ended up turning off or limiting xDB tracking on high-traffic pages, or doing personalization only on a subset of pages.

XM Cloud Personalization: With XM Cloud’s embedded in-session personalization, which, under the hood, leverages a lightweight CDP edge instance, personalization is applied at request time but for that session only. For example, you can have a component that shows one variant for visitors coming from Google Ads vs another variant for others - this check can be done on the server (Next middleware or Sitecore’s Edge returns the variant), but the result can still be edge-cached for that session. If using Static Generation, personalization might be applied client-side. Sitecore provides a Personalize JS SDK for XM Cloud that can swap components after page load based on session rules. This means you don’t bust the CDN cache for every user scenario - you might serve the general page and then immediately personalize it in the browser. The result is you keep the fast delivery for everyone, with a slight delay for personalized content loading asynchronously.

If you integrate the full Sitecore Personalize (the SaaS), personalization runs via client-side or edge decision-making, separate from page generation. That tool is built for scale; it can handle high volumes of events and decisions at the cost of some complexity. The user experience can still be very performant because Personalize can respond in tens of milliseconds with a decision, which can be done at Edge or client. Plus, Personalize allows experimenting with different performance vs. personalization trade-offs, like using web experiments that load after initial page vs. pre-personalizing content.

In short, XM Cloud allows high performance and personalization, but requires a different implementation approach (client/edge dynamic behavior vs. server-side rendering per user). XP allowed convenient server-side conditional rendering, but beyond simple rules, it could slow things down or reduce caching.

It’s telling that many XP customers never fully used the multi-session personalization because of the operational overhead; they effectively treated XP like XM. Now with XM Cloud plus Sitecore Personalize, those who truly need advanced personalization can have it without burdening the content delivery pipeline for every request – it’s offloaded to a specialized service optimized for that, leaving the main site free to be cached.

One must plan this carefully, though: initial implementations of XM Cloud might just use in-session rules and feel less powerful than XP’s historical personalization. To exceed XP, you’d include Sitecore Personalize, which opens up things like AI-driven segments, but you have to wire it up (the tracker snippet, etc.). From a performance standpoint, the best practice is to keep personalized content lean and use asynchronous loading for heavy personalization where possible so that the baseline site performance remains great.

Deployment, CI/CD, and Reliability

XP Deployments: In XP, deploying code or items could be stressful. Typically, you’d have maintenance windows for deploying new code, especially if it involved database changes. Content freezes often occurred during deployments to avoid conflicts. Some organizations achieved continuous deployment with XP via techniques like slot swaps if on Azure PaaS or by spinning up parallel environments, but it’s not trivial. Often, deployments incurred some downtime or at least required cache warming after, causing a slow response for a period. Also, a failed deployment could require rollback scripts, adding to the risk. DevOps for XP is doable, especially with containers and scripted pipelines introduced in later versions, but it’s a heavy application to deploy - a full XM/XP instance has many services (IDs, reporting DB, etc.) that all have to be in the correct state.

XM Cloud Deployments: XM Cloud was built with modern DevOps in mind. As mentioned, it supports Blue/Green deployment – you can deploy your new code to a staging slot while production keeps running, then switch traffic over when ready. This achieves zero downtime releases, a big win for marketing teams that demand high uptime. The deployment of content changes (like template changes or new items) is done via Sitecore Content Serialization and source control, which can be automated. Many XM Cloud users set up continuous integration such that any commit triggers a build and deploy to a test environment, etc. Sitecore’s built-in pipeline means you don’t have to script the entire release yourself - it will handle packaging the content and code. Additionally, since the front-end is separate, you often deploy that even more frequently, and those deploys are typically instantaneous to end-users because static files get versioned and are atomically published on CDNs.

Reliability: Outages can happen on any platform, but XM Cloud’s architecture and Sitecore’s SLA are geared to high availability. Your content authors work on an Editing host, which is separate from Edge delivery. If Edge were to have an issue, worst case, your site’s content API is down, Sitecore would work to restore it quickly under their SLA, but your editing might still be okay, or vice versa. In XP, if your server goes down, both editing and delivery could be offline unless you built redundancy. With XM Cloud, redundancy is built into the service (multiple instances, failovers, etc.). Also, backups are handled by Sitecore with geo-redundancy as mentioned. On XP, you have to ensure your backup/restore strategy is solid. Many XP incidents have been due to things like a deploy glitch or a missed config causing a site outage – those are less likely on XM Cloud, where infrastructure is consistent and deploys are tested via automation.

One factor is content delivery of XM Cloud is read-only from the perspective of content: authors publish to Edge, but end-users don’t change content on Edge. This separation of concerns increases reliability - the delivery endpoints aren’t doing heavy transactions or content writes, they are mostly serving cached data. XP content delivery sometimes had to handle things like writing personalization data or form submits into xDB, which could impact performance and reliability if xDB had issues. In XM Cloud, if you collect user data, it likely goes to an external system like a separate API or CDP, isolating any issues.

Monitoring and Debugging: With XP, you’d monitor via tools like Application Insights, custom logs, etc., in your own environment. With XM Cloud, Sitecore provides in-app logging and monitoring tools accessible from the portal. You can see logs of your CM instance easily. And for front-end, services like Vercel give real-time logs and metrics. So you get a good view of system health across the stack. Sitecore’s Ops team is also watching the infrastructure. This means you potentially catch issues faster, or Sitecore might alert you to anomalies. To contrast: on XP, if a search indexing service stopped, your team had to notice and fix it; on XM Cloud, if something in the managed service fails, Sitecore will be working to fix it often before you even notice, as part of their service reliability obligations.

Specific Optimization Techniques

To give concrete examples, here are some optimization strategies side-by-side:

  • Use of CDN: XP - use a CDN for media and set caching headers for static files; consider HTML caching for anonymous pages with short TTL. XM Cloud - CDN is inherent. Make sure to enable HTTP/2 or HTTP/3, and utilize image optimization on the front-end. Next.js has Image Optimization, which works great with Vercel’s CDN and leverages global edge caching for all content.

  • Caching strategy: XP – tune Sitecore’s output cache on renderings (e.g., cache renderings that don’t need to vary per user, use Sitecore’s cache clearing events on publish), increase item cache sizes for heavy traffic, maybe use a cache aside for expensive data (like results of a complex search query). Possibly pre-render some pages to static files if extreme performance is needed, as some have scripted Sitecore to output flat HTML for certain pages. XM Cloud - use Next.js incremental static regeneration for pages that can be cached, which automatically handles revalidating content after publish. Use Next’s API routes or middleware to handle any dynamic segments at Edge. If personalization rules are simple (by geolocation, login status), consider using edge middleware to modify responses on the fly without hitting the origin.

  • Scaling for peak: XP - pre-scale by adding CDs and enabling autoscale rules, warm up caches, maybe shorten cache expiration so content updates propagate, but be careful not to overload DB. XM Cloud - mostly auto. If expecting a viral spike, you could increase concurrency limits via Sitecore support or ensure the Edge is primed (perhaps pre-fetch or run a script to hit important pages so they’re cached globally). And ensure your front-end hosting plan supports concurrency. Enterprise tiers of Vercel handle massive concurrency, for example.

  • Database performance: XP - ensure SQL is on high-performance tier, maintain indexes, clean up analytics db to keep it slim if you don’t use historical data. Possibly offload analytics to xConnect Cloud or a data warehouse if needed. XM Cloud - the database is managed by Sitecore (in fact, Azure SQL). Not much you do directly, but since XM Cloud doesn’t accumulate interaction data by default, the DB load is mainly content reads/writes, which scale well. You still should organize content well (very large content trees can slow queries in either platform).

  • Personalization & Testing: XP - limit number of personalized components per page for performance, batch changes to profile scores to reduce overhead, use content profiling sparingly. Maybe run personalization rules on the CD server that has more resources, not on the edge, if you had multiple regions (with XP, if you deployed separate instances per region, each runs personalization independently). XM Cloud – take advantage of Sitecore Personalize’s ability to do heavy lifting outside the page request. For example, run segmentation nightly in CDP rather than computing on the fly. Use client-side experiment scripts for A/B tests, which utilize CDN edge networks to distribute variants quickly. Essentially, shift intensive personalization computations to pre-compute or client side, keeping the initial page load path as light as possible.

In terms of real-world outcomes, expect that an XM Cloud solution can achieve sub-second time-to-first-byte globally, very high throughput because most hits don’t touch the origin CMS, and handle usage spikes without breaking a sweat. In contrast, an XP solution might handle typical loads fine but needs careful babysitting to ensure similar metrics under duress, and often falls back to degraded mode (e.g., turning off personalization during high load, or relying on CDN cached pages that might not reflect the latest content if publishing frequently).

Cost of Optimization

It’s worth noting the cost implications of these performance strategies:

  • With XP, scaling up for performance means more servers or higher Azure bills. Idle capacity can cost you in slow periods. Also, high performance might demand a CDN subscription and possibly third-party monitoring tools, extra costs.

  • With XM Cloud, performance is largely built-in. You might pay a higher tier on Vercel for more edge function memory or a larger CDN usage, but you’re paying for actual usage (which corresponds with benefiting from that usage). The cost scales more directly with traffic. And you typically won’t need to invest in as much custom optimization labor. Development on Next.js is impressively fast compared to pure .NET development in terms of delivering features. That agility includes performance improvements - implementing a lazy-loading image or code-splitting in Next.js is straightforward and yields immediate performance gains, whereas optimizing an MVC site might involve more custom work.

Reliability and uptime are also part of performance. XM Cloud’s reliable deployment and infrastructure reduce the chance of outages from deployments. In XP, some teams schedule deployments at midnight Sunday and hope nothing goes wrong to avoid impacting users, as that is a performance consideration too. If you have to deploy during off-hours only, your ability to fix issues or update content quickly is hampered. XM Cloud’s zero-downtime deploys mean you can push improvements any time, which can be critical if there’s a high-priority content or code change.


9. Conclusion and Recommendations


Choosing between Sitecore XP and Sitecore XM Cloud in 2025 ultimately comes down to aligning the platform with your business priorities, technical requirements, and long-term digital strategy. Both options can deliver world-class digital experiences, but they do so in very different ways:

  • Sitecore XP offers full control, a rich integrated feature set, and proven capabilities as an all-in-one DXP – at the cost of higher maintenance, heavier infrastructure, and a more monolithic approach. It shines in scenarios where you need to retain data/control on-premises, or where you are leveraging all of its built-in marketing features under one roof. If you have an established XP solution that meets your needs and you can manage the upkeep and upcoming upgrades, XP remains a viable choice in the near term, especially given continued support until 2027+. Certain regulatory or localization needs may necessitate XP, for example, in China deployment or an isolated network. Just keep in mind that sticking with XP means accepting periodic upgrades and that new Sitecore innovations will be slower to reach you.

  • Sitecore XM Cloud represents the modern, cloud-first direction – reducing total cost of ownership through managed services, boosting agility with continuous updates, and enabling top-notch performance via headless architecture. It is best for organizations that want to focus on delivering content and customer experiences rather than managing servers. If you are starting fresh, XM Cloud is likely the better investment for the future. If you are on XP and finding that infrastructure and upgrades are eating into your budget or slowing you down, moving to XM Cloud can refocus your efforts on actual customer-facing improvements. For businesses that prioritize speed, scalability, and the ability to integrate best-of-breed services, XM Cloud is an excellent fit. It does require accepting a SaaS model and building up modern development skills, but the payoff is a more nimble digital platform.

When to choose XP:

  • You require a self-hosted environment for compliance or policy reasons that XM Cloud cannot meet, like specific in-country hosting or no external cloud allowed.

  • You extensively use XP’s multi-session personalization, marketing automation, and other xConnect-driven features, and transitioning those to composable alternatives is not feasible in the short term.

  • Your team and infrastructure are already optimized for XP, and the system is stable, with an upgrade to 10.4 planned and no major growth challenges – essentially, "if it isn’t broken" and you don’t urgently need what XM Cloud offers, you may continue with XP while planning for the longer-term future.

  • You need unlimited customization of the CMS core - for example, you have deep custom integrations that hook into Sitecore pipelines or data layers that would be hard to re-implement with XM Cloud’s constraints.

When to choose XM Cloud:

  • You want to minimize infrastructure and upgrade overhead – say you have a small IT team or want to reallocate your developers from maintenance to innovation. The automatic upgrades and managed hosting will benefit you greatly.

  • Site performance, global reach, and rapid deployment are top priorities – for instance, if your marketing team is pushing daily updates or campaign launches across regions, XM Cloud’s architecture will support that with fewer hiccups.

  • You are undertaking a major redesign or replatform anyway – an ideal time to switch to XM Cloud and build with the latest tech rather than refactoring an older XP solution.

  • Your digital strategy is “composable” – you might already be using or plan to use products like Sitecore Content Hub, Sitecore Personalize, or even non-Sitecore services. XM Cloud will integrate smoothly via APIs, whereas XP might feel comparatively siloed or require connectors.

  • You have a greenfield project and want to start on the right footing for the next 5-10 years. Adopting XM Cloud ensures the platform itself won’t become outdated in that period, and you’ll get continuous improvements.

A balanced, experience-driven perspective: Many seasoned Sitecore architects or Sitecore MVPs like myself advise evaluating how much "platform" you really need. In the past, some chose XP for safety since it had everything out of the box, but ended up not using half of it. With budgets tighter and digital experience needs evolving faster, it often makes sense to choose a leaner, more flexible setup, which is XM Cloud plus only the additional services you truly need. As one real-world consideration, if you can count the number of XP features you actively use on one hand, it’s a strong signal that XM Cloud or even XM on-prem would be more cost-effective. Sitecore itself notes that without xConnect, XM has a smaller footprint and TCO than XP. That logic extends to XM Cloud, which is essentially XM plus the SaaS benefits.

On the other hand, if your organization has squeezed substantial value from XP’s integrated suite – say you have marketing teams running automated campaigns and personalization that directly drive revenue – then you shouldn’t jump off XP until you’re confident you can reproduce or enhance that capability in the new model. It might mean a phase where you introduce Sitecore CDP/Personalize alongside XP (that is possible) to gradually transition without losing functionality.

Prepare for change: If you do decide to move to XM Cloud, approach it methodically. Plan the migration or build with a clear scope, engage experienced Sitecore partners or experts who have done it, and consider doing a pilot or proof-of-concept first. This will surface any challenges early (like missing features or integration points) and allow your team to learn XM Cloud’s nuances. Also, budget for the learning curve – maybe get training for your developers on Next.js and Sitecore Headless. The good news is that many have done this before, and the community has produced guidance and tools such as scripts to migrate content or patterns to implement common XP features in XM Cloud. Leverage those resources to avoid reinventing the wheel.

Final thought: The direction of the market is clear - cloud-native, composable DXP is the future, and Sitecore XM Cloud is a centerpiece of that strategy. However, Sitecore acknowledges that each customer’s journey is unique. They are supporting XP for years to come precisely because they know a forced march to the cloud is not feasible for everyone overnight. So, evaluate your own readiness and needs. You might choose to run XP and XM Cloud in parallel for a time, or move fully to XM Cloud now, or stay on XP a bit longer, but with a roadmap to evolve. What’s important is to make an informed, conscious choice rather than simply defaulting to one or the other. Hopefully, this guide has illuminated the concrete differences in costs, effort, capabilities, and optimizations so you can make that choice with clarity.

No matter which path you choose, success will hinge on execution: an optimally tuned XP can still deliver excellent experiences, and a poorly implemented XM Cloud site could underwhelm. The platform is an enabler, but the vision and strategy you apply are what create standout digital experiences. Align the choice to your strategy: if agility, scalability, and continuous improvement are paramount, XM Cloud aligns well; if complete control and one-stop capabilities are paramount, XP can still serve. Either way, ensure you have the right skills and partners to get the most out of the platform.

In closing, for most organizations in 2025, Sitecore XM Cloud will be the logical choice moving forward, with Sitecore XP remaining a reliable but eventually legacy option. Adopting XM Cloud sets you on a course to leverage Sitecore’s evolving innovations without the operational drag – an appealing proposition for those looking to accelerate their digital maturity. Evaluate carefully, plan thoughtfully, and you’ll make the choice that best empowers your digital experience goals.

 

SUGCON Europe 2025 Takeaways

SUGCON Europe 2025 in Antwerp, Belgium first week of April was packed with energy insightful sessions, inspiring community content, and the always-welcome hallway chats and late-night bar banter that make these events unforgettable. There were plenty of important announcements from Sitecore’s keynotes and sessions. These updates carry serious weight for future work with Sitecore platforms - and they shouldn’t be overlooked.

Let's take a look at them one be one.

As per Dave O’Flanagan, the CEO of Sitecore, Sitecore Stream is a capability layer rather than a specific product. It orchestrates the life behind every AI-powered product in Sitecore and facilitates content creation, optimization, and personalization across both traditional and cloud-native setups. Its purpose is to streamline workflows through intelligent automation and suggestions, all while remaining flexible for various implementation needs. Sitecore Stream has become an important collaboration tool and even beyond. For example, they are currently experimenting with MCP (Model Context Protocol) integration that standardizes two-way communication between AI assistants and external apps, tools, and data sources. As artificial intelligence became central for Sitecore, the company was called an AI-first organization for the first time ever. Looking at the velocity of new features and changes, we believe that statement.

Besides the AI investments, Sitecore announces strategiс partnerships further ahead:

  • both Vercel and Netlify provide premium hosting services for the headless application, the best in their breed
  • CI Hub is industry-standard in-app connectivity software, that brings further more composable integrations and connections
  • Microsoft, as an existing partner, expands with innovations and collaborations over AI and Azure services
  • TransPerfect is an ultimate translation service that supports all the languages globally and has the support for Sitecore XM Cloud

Sitecore XM/XP version 10.5 is around the corner, expected to be released somewhere around Symposium 2025, and brings lots of features, among them:

  • even more AI integrations (as we know Stream already supports self-hosted platforms starting from version 10.2) with deeper content interactions, extended branding support via chat and tools, etc.
  • wider integration with other compostable products
  • continued stability and support

Sitecore DXPs remain crucial products for Sitecore and will gain new features. Thanks to Stream, the AI adoption is within reach without the need for a cloud migration, so that existing projects can begin leveraging AI features and gaining value immediately.

In order to have Stream operable on self-hosted/PaaS platforms you must have access to the Sitecore Cloud Portal, plus a Stream subscription, that's in addition to the XM/XP license you already have. There is Sitecore.AiClient.config file that defines the connection string, and brand kit id, along with the reference path. Currently, the only capability offered for non-cloud DXPs is brand-aware content generation, where Stream suggests versions aligned with the brand’s tone and structure. Multiple variations can be created, allowing editors to choose the most appropriate one directly from the Content Editor. Here's the roadmap:

Sitecore Tream roadmap

Sitecore Marketplace was the first ever announced publically as the first milestone was reached. It takes the strongest power of the Sitecore ecosystem back to track - the community with its crowdsourcing effort at a scale. Marketplace will let developers create either internal apps to circulate exclusively within their organizations or release public apps on free, freemium, or paid models, subject to pre-publishing moderation by Sitecore.

Currently, Marketplace only supports XM Cloud and is available with the Early Access Program. Developers can rely on specified "touchpoints" in the portal and Pages Builder app for the extension, whether it is a Cloud Portal App, Navigation or context panel integration, or even a field-level extension, such as a custom field. There is also an SDK that helps build marketplace apps. With further milestones, it becomes publicly available and will expand to the rest of SaaS products, such as Content Hub, Personalize, and others.

Sitecore always used to be a content-centric vendor and this time they introduced XM Cloud Content which is based on the learnings from Content Hub One and represents probably the most significant shift. This new backend will ultimately serve as the foundation for storing and delivering all content within XM Cloud, purely SaaS. Once live, this architectural evolution will make it possible to phase out the traditional "XM" layer and its underlying Docker-based services entirely.

XM Cloud Content lets us get rid of:

  • the hierarchical tree-like data structure into a more flexible relation-based data organization
  • all the publishing issues, with immediate publishing by changing the "published" flag
  • inheritance-based model, in favor of composition, offering better flexibility for content modeling from "fragments of schema"
  • legacy versioning embedded into a content item. The new Content system allows "external" versioning since once it gets published content becomes immutable

We've been shown the new system in action, from content structure modeling to consumption, and what was impressive - the immediate system responsiveness. Content consumption is rapid and works through with GraphQL, more to say the system suggests the query structure, making it even faster.

There also was announced new Content SDK for XM Cloud, but it has nothing to do with the above XM Cloud Content, so please do not be confused.

Content SDK is effectively a slim subset of JSS SDK exclusively for modern XM Cloud development, without having legacy code for rudimental features, that do not exist in XM Cloud (XP Forms, REST API content consumption, chrome editing mode, etc). In addition, the overall size and complexity was drastically reduced, namely:
- less included packages: 6 now against 14 as in JSS SDK
- less files: 65% reduction!
- less code: 54% of unused code has been removed
- faster page load: counted as 200ms
- overall size reduction by a shocking 89%

JSS to Content SDK

The best part is that XM Cloud Content SDK is already available along with its source code. As for the original JSS, it won't go away and will stay developed further for supporting Sitecore XM and XP implementations. 

Worth mentioning large improvements to the XM Cloud Starter Kits with exciting expectations of the App Router introduction along with optimization of middleware.

Last but not least, there were significant documentation improvements. Given the overwhelming number of headless SDKs (JSS, Content, .NET Core, etc), the documentation required some order and consistency, which is now achieved (proof).

Separately worth mentioning Content Hub changes. If you occasionally monitor Sitecore's changelog (that's where the company highlights all the new features and fixes), you may have noticed that Content Hub announcements disproportionately dominate that page - there were plenty of recent additions and improvements into CLI/SDKs/APIs of Content Hub. Along with media delivery and Experience Edge enhancements, these changes are massive!

Due to its nature, Content Hub appears to be the best beneficiary of AI and Sitecore Stream introduction. It also essentially benefits from the introduction of Marketplace:

Sitecore’s Content Hub is evolving—moving from trusted integrations to flexible, composable extensibility, unlocking:

This SUGCON event has sent a clear message: Sitecore is evolving, and doing it rapidly. It hears back from the community, learns from the mistakes, both own and competitors', and leverages its own strength. The future seems to be bright and we're almost there.

Rendering Parameters vs. Rendering Variants - when should use one or another

Do you know how to identify when you should create a rendering variant for a component, and when you can simplify effort by setting rendering parameters? Below is the answer and it’s pretty straightforward.

To address let's first take a look at both options and options and identify their key differences.

Rendering Parameters allow you to have additional control over a component/rendering by passing additional parameters into it. Key-value-pair is the most simplistic form, but of course, you can use any advanced form of input by leveraging rendering parameters templates, but regardless of the chosen way the result will be the same - you pass some additional parameters into a component. Based on those params a component can do certain things, for example, show/hide specific blocks or use more advanced styling tricks. Important to keep in mind - that all the parameters are stored within a holding page. Remember that you should inherit Base Rendering Parameters template to have full support in Pages Builder.

parameters


Rendering Variants (aka. Headless Variants) feel more advanced compared to params. The principle difference is that a variant allows you to return principally different HTML output and do way more complicated manipulations over the HTML structure. You should use common sense when choosing variants and leverage them in cases where the same component may present various look and feel options: for example, a promo block with two images having a headless variant of these same images positionally swapped. Achieving the same with rendering parameters would require bringing ugly presentation logic into the components code along with code duplications. Using variants allows us to achieve the same result way more elegantly. Note that, Variants originate from SXA, therefore when you bring a legacy JSS site to XM Cloud without converting it to SXA - this option isn't available.

variants



Both Rendering Variants and Rendering Parameters assume you use the same component that receives the same datasource items (or none datasource at all). You should never leverage datasource items to control the presentation or behavior of components - they are purposed exclusively for storing the content, as it comes from their name.

Hope that clarifies the use cases and removes ambiguity.

Reviewing my 2024 Sitecore MVP contributions

Sitecore Technology MVP 2024 Sitecore Technology MVP 2023 Sitecore Technology MVP 2022 Sitecore Technology MVP 2021

Sitecore Technology MVP 2020 Sitecore Technology MVP 2019 Sitecore Technology MVP 2018 Sitecore Technology MVP 2017

The Sitecore MVP program is designed to recognize individuals who have demonstrated advanced knowledge of the Sitecore platform and a commitment to sharing knowledge and technical expertise with community partners, customers, and prospects over the past year. The program is open to anyone who is passionate about Sitecore and has a desire to contribute to the community.

Over the past application year starting from December 1st, 2023, I have been actively involved in the Sitecore community, contributing in a number of ways.

Sitecore Blogs 

  1. This year I have written 18 blog posts at the Perficient site on various topics related to Sitecore, including my Crash Course to Next.Js with TypeScript and GraphQL, top-notch findings about XM Cloud and other composable products, best practices, tips and tricks, and case studies. Listing them all by the bullets would make this post too long, therefore instead I leave the link to the entire list of them, shown reverse chronologically.
  2. I’ve been also posting on my very own blog platform, which already contains more than 200 posts about Sitecore accumulated over the past years.
  3. Also, I occasionally create video recordings/walkthrough and upload them to my YouTube channel.

Sitecore User Groups 

  1. Organized three Los Angeles Sitecore User Groups (#19, #20, and #21). This user group has ~480 members!
  2. Last fall I established and organized the most wanted user group of the year – Sitecore Headless Development UserGroup educating its 410+ members. This one is very special since headless development has become the new normal of delivering sites with Sitecore, while so many professionals feel left behind unable to catch up with the fast-emerging tech. I put it as my personal mission to run it twice per quarter helping the community learn and grow “headlessly” and that is one of my commitments to it. It became the most run and the most attended/reviewed event of all Sitecore user groups with eight events organized over this year (#1 and #2) (#3, #4, #5, #6, #7, #8, #9, #10) along with event #11 scheduled for December 12th. All the recordings are publicly available on YouTube, and also referenced from the individual event pages.
  3. Presented my innovative approach to the Content Migration for XM Cloud solutions.
  4. Another user group presentation narrates all the new features happening with Next.Js 15, breaking API changes and what it all means for Sitecore.

GitHub

  • Sifon project keeps maintained and receives new features. Thus Sifon got support for Sitecore 10.4 platforms.
  • I keep Awesome Sitecore project up and actual. This repository has plenty of stars on GitHub and is an integral part of a big Awesome Lists family, if you haven’t heard of Awesome Lists and its significance I highly recommend reading these articles – first and the second.
  • There are also a few less significant repositories among my contributions that are still meaningful and helpful.

Sitecore Mentor Program 

  • Got two mentees in 2024, supported them over the course of a year, also delivered them both full-scaled XM Cloud training along with the certification.
  • One of my past year mentees was recognized as Sitecore MVP in 2024, resulting from an Exclusive Mentorship Agreement, proving my mentoring approach was successful.

MVP Program

  • I participate in most of the webinars and MVP Lunches (often in both time zones per event).
  • I think MVP Summit is the best perk of the MVP Program, so never miss it out. This year I’ve learned a lot and also provided feedback to the product teams, as usual.
  • I participate in several streams of the Early Access Program, sharing insights with the product team ahead of GA dates.
  • In the past, I have participated in a very honorable activity helping to review the first-time applicants for the MVP Program which is the first line of the evaluation and we carefully match every first-time applicant against high Sitecore MVP standards. This year I am taking part in reviewing as well.

Sitecore Learning

I collaborated with the Sitecore Learning team for the past 2-3 years, and this year was not an exception: 

  • I was invited by Sitecore Learning to make an excellent detailed review of a new feature - XM Cloud Forms Builder for Tips & Tricks series. 

Sitecore Telegram 

  • I am making Telegram a premium-level channel for delivering Sitecore news and materials. Telegram has a unique set of features that no other software can offer, and I am leveraging these advantages for more convenience to my subscribers.
  • Started in 2017 as a single channel, it was expanding rapidly and has now reached a milestone of 1,100 subscribers!
  • Growth did not stop but escalated further beyond Sitecore going composable with having a dedicated channel for almost any composable product. Here all they are:

Support Tickets

  • CS0514702 (Content Hub)
  • CS0462816 (SPE for XM Cloud)
  • CS0518934 (Forms Builder)

Other Contributions

  • I created Sitecore MVP section in the Wikipedia, explaining MVP Program, its significance for Sitecore and the overall process of determining the winners.
  • I am very active on my LinkedIn (with 7K+ followers) and Twitter aka X (with almost ~1.2K subscribers), multiple posts per week, sometimes a few a day.
  • With my dedication to Sitecore's new flagship product, XM Cloud, it was no wonder I just launched a new XM Cloud Daily series of tips and tricks on social media (this actually started in December 2024, so it falls on a new application period).
  • That comes in addition to the existing series on LinkedIn - Headless Tips & Tricks, where I share the insights and nuances of modern headless development with Sitecore

 The above is what I memorized about my annual contributions so far. Wishing all decent applicants to join this elite club for the coming year!

XM Cloud content migration: connecting external database

Historically when performing content migration with Sitecore we used to deal with database backups. In a modern SaaS world, we do not have the luxury of neither managing cloud database backups, nor the corresponding UI for doing this. Therefore, we must find an alternative approach.

Technical Challenge

Let’s assume we have a legacy Sitecore website, in my case that was XP 9.3 and we’ve been provided with only a master database backup having all the content. The objective is to perform content migration from this master database into a new and shiny XM Cloud environment(s).

Without having direct access to the cloud, we can only operate locally. In theory, there could be a few potential ways of doing this:

  1. Set up a legacy XP of the desired version with the legacy content database already attached/restored to it. Then try to attach (or restore) a vanilla XM Cloud database to a local SQL Server as a recipient database in order to perform content migration into it. Unfortunately, the given approach would not work since SQL Server version incompatibility between XM Cloud and XP 9.3. Even if that was possible, running XP 9.3 with the XM Cloud database won’t work as Xз 9.3 neither knows about XM Cloud schema nor is capable of handling Items as Resource required feature which was invented later in XP 10.1. Therefore – this option is not possible.

  2. Can we go the other way around by using the old database along with XM Cloud? This is not documented, but let’s assess it:

    1. Definitely won’t work in the cloud since we’re not given any control of DBs and their maintenance or backups.

    2. In a local environment, XM Cloud only works in Docker containers and it is not possible to use it with an external SQL Server where we have a legacy database. But what if we try to plug that legacy database inside of the local SQL Container? Sadly, there are no documented ways of achieving that.

  3. Keep two independent instances side by side (legacy XP and XM Cloud in containers) and use an external tool to connect both of them in order to migrate the content. In theory that is possible but carries on few drawbacks.
    1. The tool of choice is Razl, but this tool is not free, requires a paid license, and does not have a free trial to ever test this out.
    2. Connecting to a containerized environment may not be easy and require some additional preps
    3. You may need to have a high-spec computer (or at least two mid-level machines connected to the same network) to have both instances running side by side.

After some consideration, the second approach seems to be reasonable to try so let’s give it a chance and conduct a PoC.

Proof of Concept: local XM Cloud with external content database

Utilize the second approach we’re going to try attaching the given external legacy database to XM Cloud running in a local containerized setup. That will allow using a built-in UI for mass-migrating the content between the databases (as pictured below) along with the Sitecore PowerShell script for finalizing and fine-tuning the migrated content.

Control Panel

Step 1: Ensurу SQL Server port is externally exposed

We are connecting the external SQL Server Management studio through a port of the SQL Server container that is exposed externally in order to make it possible. Luckily, that has been done for us already, just make sure docker-compose has:

ports:
      - "14330:1433"

Step 2: Spin up an XM Cloud containers and confirm XM Cloud works fine for you

Nothing extraordinary here, as easy as running .\init.ps1 followed by .\up.ps1.

Step 3: Connect SQL Management Studio to SQL Server running in a container.

After you sound up containers, run SQL Management Studio and connect to SQL Server running in SQL container through an exposed port 14330, as we did at step 1:

Connection parameters

Step 4: Restore the legacy database

If you have a Data-Tier “backpack” file you may want to do an extra step and convert it into a binary backup for that particular version used by XMCloud before restoring. This step is optional, but in case you want to restore the backup more than once (which is likely to happen), it would make sense to take a binary backup as soon as you restore the data-tier “backpack” first time ever. Data-tier backups process much slower than binaries, so that will definitely save time in the future.

Once connected, let’s enable contained database authentication. This step is mandatory, otherwise, that would not be possible to restore a database:

EXEC sys.sp_configure N'contained database authentication', N'1'
go
exec ('RECONFIGURE WITH OVERRIDE')
go

One more challenge ahead: when performing backup and restore operations, SQL Server shows up a path local to the server engine, and not the host machine. That means, our backup should exist “inside” of SQL container. Luckily, w have this also covered. Make sure docker-compose.override.yml contains:

mssql:
volumes:
      - type: bind
source: .\docker\data\sql
target:c:\data

That means, one can locate legacy database backups into .\docker\data\sql folder of a host machine and it will magically appear within C:\datafolder when using SQL Management Studio database backup restore tool which you can perform now.

Important! Restore legacy database using the “magic name” in a format Sitecore.<DB_NAME_SUFFIX>, further down below I will be using the value RR as DB_NAME_SUFFIX.

Once got restored database in SQL Server Management Studio under the name Sitecore.RR we need to plug this database to the system. There is a naming convention hidden from our eyes within CM containers.

Step 5: Configure connection strings

Unlike in XM/XP – there is no documented way to plug an external database. The way connection strings are mapped to the actual system is cumbersome, it uses some “magic” hidden within the container itself and obfuscated from our eyes. It only tool to reach it experimental way. Here are the steps to reproduce:

  • Add environmental variable to docker-compose record for CM:

    • Sitecore_ConnectionStrings_RR: Data Source=${SQL_SERVER};Initial Catalog=${SQL_DATABASE_PREFIX}.RR;User ID=${SQL_SA_LOGIN};Password=${SQL_SA_PASSWORD}
  • Add a new connection string record. To do so you’ll need to create a connection strings file within your customization project as .\src\platform\<SITENAME>\App_Config\ConnectionStrings.config with the content of the connection strings file from the CM container with the addition of a new string:

Please note the difference in the suffix format of both above records, that is totally fine. CM container still processes that correctly.

Step 6: Reinstantiating CM container

Simply restarting a CM container is not sufficient. You must remove it and re-create it, just killing/stopping is not sufficient.

For example, the below command will work for that purpose:

docker-compose restart cm

… not will this one:

docker-compose kill cm

The reason is that CM will not update environmental variables from docker-compose file upon restart. Do this instead:

docker-compose kill cm
docker-compose rm cm --force
docker-compose up cm -d

Step 7: Validating

  1. Inspecting CM container for environmental variables will show you this new connection string, as added:

    1. "Env": [
                  "Sitecore_ConnectionStrings_RR=Data Source=mssql;Initial Catalog=Sitecore.RR;User ID=sa;Password=6I7X5b0r2fbO2MQfwKH"
  2. Inspecting connection string config (located at C:\inetpub\wwwroot\App_Config\ConnectionStrings.config on CM container) contains the newly added connection string.

Step 8: Register new database with XM Cloud

It can be done the below config patch that does this job. Save it as docker\deploy\platfo.rm\App_Config\Include\ZZZ\z.rr.config for test and later do not forget to include it in a platform customization project, so that it gets shipped with each deployment
<?xml version="1.0" encoding="UTF-8"?>
<configuration
	xmlns:patch="www.sitecore.net/.../">
	<sitecore>
		<eventingdefaultProvider="sitecore">
			<eventQueueProvider>
				<eventQueuename="rr"patch:after="evertQueue[@name='web']"type="Sitecore.Data.Eventing.$(database)EventQueue, Sitecore.Kernel">
					<paramref="dataApis/dataApi[@name='$(database)']"param1="$(name)"/>
					<paramref="PropertyStoreProvider/store[@name='$(name)']"/>
				</eventQueue>
			</eventQueueProvider>
		</eventing>
		<PropertyStoreProvider>
			<storename="rr"patch:after="store[@name='master']"prefix="rr"getValueWithoutPrefix="true"singleInstance="true"type="Sitecore.Data.Properties.$(database)PropertyStore, Sitecore.Kernel">
				<paramref="dataApis/dataApi[@name='$(database)']"param1="$(name)"/>
				<paramresolve="true"type="Sitecore.Abstractions.BaseEventManager, Sitecore.Kernel"/>
				<paramresolve="true"type="Sitecore.Abstractions.BaseCacheManager, Sitecore.Kernel"/>
			</store>
		</PropertyStoreProvider>
		<databases>
			<databaseid="rr"patch:after="database[@id='master']"singleInstance="true"type="Sitecore.Data.DefaultDatabase, Sitecore.Kernel">
				<paramdesc="name">$(id)
				</param>
				<icon>Images/database_master.png</icon>
				<securityEnabled>true</securityEnabled>
				<dataProvidershint="list:AddDataProvider">
					<dataProviderref="dataProviders/main"param1="$(id)">
						<disableGroup>publishing</disableGroup>
						<prefetchhint="raw:AddPrefetch">
							<sc.includefile="/App_Config/Prefetch/Common.config"/>
							<sc.includefile="/App_Config/Prefetch/Webdb.config"/>
						</prefetch>
					</dataProvider>
				</dataProviders>
				<!-- <proxiesEnabled>false</proxiesEnabled> -->
				<archiveshint="raw:AddArchive">
					<archivename="archive"/>
					<archivename="recyclebin"/>
				</archives>
				<cacheSizeshint="setting">
					<data>100MB</data>
					<items>50MB</items>
					<paths>2500KB</paths>
					<itempaths>50MB</itempaths>
					<standardValues>2500KB</standardValues>
				</cacheSizes>
			</database>
		</databases>
	</sitecore>
</configuration>

Step 9: Enabling Sitecore PowerShell Extension

Next, we’d want to enable PowerShell, if that is not yet done. You won’t be able to migrate the content using SPE without performing this step.

<?xml version="1.0" encoding="utf-8"?>
<configuration
	xmlns:patch="http://www.sitecore.net/xmlconfig/"
	xmlns:role="http://www.sitecore.net/xmlconfig/role/"
	xmlns:set="http://www.sitecore.net/xmlconfig/set/">
	<sitecorerole:require="XMCloud">
		<powershell>
			<userAccountControl>
				<tokens>
					<tokenname="Default"elevationAction="Block"/>
					<tokenname="Console"expiration="00:55:00"elevationAction="Allow"patch:instead="*[@name='Console']"/>
					<tokenname="ISE"expiration="00:55:00"elevationAction="Allow"patch:instead="*[@name='ISE']"/>
					<tokenname="ItemSave"expiration="00:55:00"elevationAction="Allow"patch:instead="*[@name='ItemSave']"/>
				</tokens>
			</userAccountControl>
		</powershell>
	</sitecore>
</configuration>

Include the above code into a platform customization project as .\docker\deploy\platform\App_Config\Include\ZZZ\z.SPE.config. If everything is done correctly, you can run SPE commands, as below:

SPE results

The Result

After all the above steps are done correctly, you will be able to utilize the legacy content database along with your new shiny local XM Cloud instance:
Result in Sitecore Content Editor
Now you can copy items between databases just by using built-in Sitecore UI preserving their IDs and version history. You can also copy items with SPE from one database to another which are both visible to the SPE engine.

.NET Core Renderings for XM Cloud finally gets some love

That is not a secret – Sitecore always used to prioritize Next.Js framework as the first-class citizen for XM Cloud. All the best and finest features tend to find their way to a given framework in the first place. However, recently, there has been much activity around the .NET Core Rendering Framework which makes a lot of sense given most of us, Sitecore tech professionals, originate from the Microsoft and .NET background. More excitement – that is done on .NET 8, which is the latest LST runtime!

Starter Kit

ASP.NET Core framework was with us for a while, periodically receiving some minor updates and fixes. But let’s be honest: having an SDK on its own is one thing, but receiving a decent starter kit on top of that framework is what makes us developers actually create at scale. And that moment has just occurred – without any loud fanfare, XMC ASP.NET Core Starter Kit went public. Please be aware that this is only a PRE-RELEASE version and has its own temporal shortcomings, I gave it a try and want to share my findings with you.

What are these shortcomings? Just a few:

  • FEaaS and BYOC components are not yet supported, therefore you also cannot use Form since it leverages those
  • System.Text.Json serializer is more strict than Newtonsoft which was removed in favor of a built-in solution, thus some components may fail
  • SITECORE_EDGE_CONTEXT_ID variable is not supported

Everything else seems to work the same. There are also some expectations of XM Cloud supporting .NET Rendering at a built-in editing host at some time later in the same manner that works today along with JSS applications, but I do not work for Sitecore and can only make assumptions and guesses without any certainty to it.

First Impression

I forked the repo and cloned the forked code into my computer. Let’s take a look at what we have got there.

VS Code

  • the code varies from what we used to see from XM Cloud Foundation Head starter kit, and that’s understood
  • at the root folder we still have xmcloud.build.jsonsitecore.json and folders – .config and .sitecore
  • xmcloud.build.json is required for cloud deploy, but does not have renderingHosts root section required for editing host(s), as I explained above
  • there is headapps folder to keep the solution file along with .NET projects subfolder(s), currently just a single one – aspnet-core-starter
  • there is also local-containers folder that contains docker-compose files, .env, docker files, scripts, Traefik, and the rest of the container assets we got used to
  • another difference – authoring folder contains serialization settings and items as well as .NET framework project for CM customizations
  • however, there are no init.ps1 and up.ps1 files, but that is easy to create yourself by stealing and modifying those from XM Cloud Foundation Head

With that in mind, we can start investigating. There is a ReadMe document explaining how to deploy this codebase, but before going ahead with it I of course decided to:

Run Local Containers

There are no instructions on container setup, only for cloud deployment, but after spending a few years with Foundation Head, the very first thing that naturally comes into my mind is running this starter kit in local Docker containers. Why not?

There are a couple of things one should do first before spinning up containers.

1. Modify settings in .ENV file – at least these two:

# Enter the value for SQL Server admin password:
SQL_SA_PASSWORD=SA_PASSWORD
# Provide a folder storing a Sitecore license file:
HOST_LICENSE_FOLDER=C:\Projects
 
2. We need to generate Traefik SSL Certificates. To do so let’s create .\local-containers\init.ps1 script with the below content:
    [CmdletBinding(DefaultParameterSetName = "no-arguments")]
    Param()
    $ErrorActionPreference = "Stop";
    
    # duplicates in Up.ps1 scrips
    $envContent = Get-Content .env -Encoding UTF8
    $xmCloudHost = $envContent | Where-Object {$_ -imatch "^CM_HOST=.+"}
    $renderingHost = $envContent | Where-Object {$_ -imatch "^RENDERING_HOST=.+"}
    $xmCloudHost = $xmCloudHost.Split("=")[1]
    $renderingHost = $renderingHost.Split("=")[1]
    
    Push-Location docker\traefik\certs
    try{
        $mkcert = ".\mkcert.exe"
        if($null -ne(Get-Command mkcert.exe -ErrorAction SilentlyContinue)){
            # mkcert installed in PATH
            $mkcert = "mkcert"
        }elseif(-not(Test-Path$mkcert)){
            Write-Host "Downloading and installing mkcert certificate tool..." -ForegroundColor Green
            Invoke-WebRequest "https://github.com/FiloSottile/mkcert/releases/download/v1.4.1/mkcert-v1.4.1-windows-amd64.exe" -UseBasicParsing -OutFile mkcert.exe
            if((Get-FileHash mkcert.exe).Hash -ne "1BE92F598145F61CA67DD9F5C687DFEC17953548D013715FF54067B34D7C3246"){
                Remove-Item mkcert.exe -Force
                throw "Invalid mkcert.exe file"
            }
        }
        Write-Host "Generating Traefik TLS certificate..." -ForegroundColor Green
        & $mkcert -install
        & $mkcert "$xmCloudHost"
        & $mkcert "$renderingHost"
    }
    catch{
        Write-Error "An error occurred while attempting to generate TLS certificate: $_"
    }
    finally{
        Pop-Location
    }

    Write-Host "Adding Windows host"
    Add-HostsEntry "$renderingHost"
    Add-HostsEntry "$xmCloudHost"

    Write-Host "Done!" -ForegroundColor Green
 

And then execute this script:

Certs

There is no up.ps1 script, so instead let’s run docker-compose directly: docker compose up -d

You may notice some new images show up, and you also see a new container: aspnet-core-starter

Docker

If everything is configured correctly, the script will execute successfully. Run Sitecore from its default hostname, as configured in .env file: https://xmcloudcm.localhost/sitecore

From there you will see no significant changes. Containers just work well! Sitecore has no content to interact with the head application. I will add the content from the template but let’s make the could deployment first.

Deploy to the Cloud

ReadMe document suggests an inconvenient way of cloud deployment:

1. Create a repository from this template.

2. Log into the Sitecore Deploy Portal.

3. Create a new project using the ‘bring your code’ option, and select the repository you created in step 1.

For the majority of us, who are on the Sitecore Partner side, there are only six environments available grouped into two projects. These allocations are priceless and are carefully shared between all XM Cloud enthusiasts and aspirants who are learning a new platform. We cannot simply “create a new project” because we don’t have that spare project, so in order to create one we have to delete the existing one. Deleting a project requires deleting all (three) of its environments in the first place, which is half of the sandbox capacity, carrying valuable work in progress for many individuals.

That is why I decided to use CLI instead. Luckily it works exactly the same as it does with Next.Js starter kits, and from .\.config\dotnet-tools.json you may see that it uses that same version. You deploy the root folder holding xmcloud.build.json file as a working directory, so there are no changes in execution.

Eventually, once deployed we navigate to XM cloud. I decided to follow the ReadMe and create a Basic site from Skate Park template. Basically, I am following steps 4-18 from the ReadMe file.

 

As a side exercise, you will need to remove a Navigation component from a Header partial item, located at /sitecore/content/Basic/Basic/Presentation/Partial Designs/Header. Basic site will break in the debugger if you do not delete currently incompatible rendering that has a serialization issue.

Building Dev Tunnel in Visual Studio

Next, let’s open and build the solution in the Visual Studio IDE, which refers to .\headapps\aspnet-core-starter.sln file. You may see it related to three Sitecore dependencies from Sitecore.AspNetCore.SDK.LayoutService.Client:

  • Transient: Sitecore.AspNetCore.SDK.LayoutService.Client.Interfaces.ISitecoreLayoutClient
  • Singleton: Sitecore.AspNetCore.SDK.LayoutService.Client.Serialization.ISitecoreLayoutSerialize
  • Singleton: Sitecore.AspNetCore.SDK.LayoutService.Client.Serialization.Converter.IFieldParser

Modify .\headapps\aspnet-core-starter\appsettings.json with the setting values collected from the previous steps. You will end up with something looking as:

Appsettings.json

Now let’s create a Dev Tunnel in VisualStudio:

Dev Tunnel

There will be at least two security prompts:

Dev Tunnel Authorize Github Dev Tunnel Authorize Notice

If everything goes well, a confirmation message pops up:

Dev Tunnel Created

Now you will be able to run and debug your code in Visual Studio:

Debugger Works

Make a note of the dev tunnel URL, so that we can use it to configure Rendering Host, as described at step 27 of ReadMe. You will end up with something as below:

Rendering Hosts

So far so good. You can now run the website by URL and in Experience Editor. Running in Page will however not work yet due to the below error:

No Pages Without Publish

To explain that, Experience Editor runs as a part of CM and pulls content from a GraphQL endpoint on that same CM. Pages instead is a standalone separate application, so it does not have access neither to the endpoint nor to the Rendering Hosts settings item. It only has access to Experience Edge so we must publish first. Make sure you publish the entire Site Collection. Once complete, Page works perfectly well and displays the site:

Pages Work 1 Pages Work 2

To explain what happens above: Pages app (which is a SaaS-run editor) pulls Experience Edge for the settings of the rendering editing host (which runs in a debuggable dev tunnel from Visual Studio) and renders HTML right there with the layout data and content pulled from Experience Edge.

Deploy Rendering Host to Cloud

Without much thinking, I decided to deploy the rendering host as Azure Web App, with the assumption that the .NET 8 application would be best supported in its native cloud.

Web App Configure

After the Web App is created, add the required environmental variables. The modern SITECORE_EDGE_CONTEXT_ID variable is not yet supported with .NET Core SDK, so we should go the older way:

Azure App Settings

A pleasant bonus of GitHub integration is that Azure creates GitHub Actions workflow with the default functional build and deployment. There is almost nothing to change,  I only made a single fix replacing this run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp with a hardcoded path since this variable contains space from “Program Files” part and is incorrectly tokenized breaking the build. After this fix, GitHub actions got built the right way and I started receiving green status:

Github Actions

… and the published site shows up from the Azure Web App powered rendering host:

Published Site

Finally, we can get rid of Dev Tunnel, replacing it with the actual “published site” hostnames:

Getting Rid Of Dev Tunnel

After republishing the Rendering Host item to Edge, we can stop the debugger and close Visual Studio. Both Experience Editor and Pages app are now working with an editing host served by the Azure Web App.

Verdict

Of course, that would be much anticipated for XM Cloud to have built-in .NET editing host capabilities same way as JSS does. But even without it, I applaud to Sitecore development team for making and keeping working on this starter kit as that is a big milestone for all of us within the .NET Community!

With this kit, we can now start building XM Cloud powered .NET app at a faster pace. I believe all the missing features will find their way to the product, and maybe later there will be some (semi)official SSG support for .NET, something like  Statiq. That will allow deployments to a wider set of hosting, such as Azure Static Web Apps, Netlify, and even Vercel which does not support .NET as of today.

Full guide to enabling Headless Multisite Add-On for your XM Cloud solution

Sitecore Headless Next.Js SDK recently brought the feature that makes it possible to have multiple websites from Sitecore content tree being served by the same rendering hoist JSS application. It uses Next.js Middleware to serve the correct Sitecore site based on the incoming hostname.

Why and When to Use the Multisite Add-on

The Multisite Add-on is particularly useful in scenarios where multiple sites share common components or when there is a need to centralize the rendering logic. It simplifies deployment pipelines and reduces infrastructure complexity, making it ideal for enterprises managing a portfolio of websites under a unified architecture. This approach saves resources and ensures a consistent user experience across all sites.

How it works

The application fetches site information at build-time, not at runtime (for performance reasons). Every request invokes all Next.js middleware. Because new site additions are NOT frequent, fetching site information at runtime (while technically possible) is not the best solution due to the potential impact on visitor performance. You can automate this process using a webhook to trigger automatic redeployments of your Next.js app on publish.

Sitecore provides a relatively complicated diagram of how it works (pictured below), but if you do not get it from the first look, do not worry as you’ll get the understanding after reading this article.

Uuid 8601bf89 50ab 5913 42ed 4773b05ab2c3[1]

Technical Implementation

There are a few steps one must encounter to make it work. Let’s start with the local environment.

Since multisite refers to different sites, we need to configure hostnames. The Main site operates on main.localhost hostname, and it is already configured as below:

.\.env
    RENDERING_HOST=main.localhost
.\docker-compose.override.yml
    PUBLIC_URL: "https://${RENDERING_HOST}"

For the sake of the experiment, we plan to create a second website served by second.localhost locally. To do so, let’s add a new environmental variable to the root .env file (SECOND_HOST=second.localhost) and introduce some changes to init.ps1 script:

$renderingHost = $envContent | Where-Object{$_ -imatch "^RENDERING_HOST=.+"}
$secondHost = $envContent | Where-Object{$_ -imatch "^SECOND_HOST=.+"}
$renderingHost = $renderingHost.Split("=")[1]
$secondHost = $secondHost .Split("=")[1]

down below the file we also want to create SSL certificate for this domain by adding a line at the bottom:

& $mkcert -install
# & $mkcert "*.localhost"
& $mkcert"$xmCloudHost"
& $mkcert"$renderingHost"
& $mkcert"$secondHost"

For Traefic to pick up the generated certificate and route traffic as needed, we need to add two more lines at the end of .\docker\traefik\config\dynamic\certs_config.yaml file:

tls:
certificates:
    - certFile:C:\etc\traefik\certs\xmcloudcm.localhost.pem
keyFile:C:\etc\traefik\certs\xmcloudcm.localhost-key.pem
    - certFile:C:\etc\traefik\certs\main.localhost.pem
keyFile:C:\etc\traefik\certs\main.localhost-key.pem
    - certFile:C:\etc\traefik\certs\second.localhost.pem
keyFile:C:\etc\traefik\certs\second.localhost-key.pem

If you try initializing and running – it may seem to work at first glance. But navigating to second.localhost in the browser will lead to an infinite redirect loop. Inspecting the cause I realized that occurs due to CORS issue, namely that second.localhost does not have CORS configured. Typically, when configuring the rendering host from docker-compose.override.yml we provide PUBLIC_URL environmental variable into the rendering host container, however, that is a single value and we cannot pass multiple.

Here’s the more descriptive StackOverflow post I created to address a given issue

To resolve it, we must provide the second host in the below syntax as well as define CORS rules as labels into the rendering host, as below:

labels:
  - "traefik.enable=true"
  - "traefik.http.routers.rendering-secure.entrypoints=websecure"
  - "traefik.http.routers.rendering-secure.rule=Host(`${RENDERING_HOST}`,`${SECOND_HOST}`)"
  - "traefik.http.routers.rendering-secure.tls=true"
# Add CORS headers to fix CORS issues in Experience Editor with Next.js 12.2 and newer
  - "traefik.http.middlewares.rendering-headers.headers.accesscontrolallowmethods=GET,POST,OPTIONS"
  - "traefik.http.middlewares.rendering-headers.headers.accesscontrolalloworiginlist=https://${CM_HOST}, https://${SECOND_HOST}"
  - "traefik.http.routers.rendering-secure.middlewares=rendering-headers"

Once the above is done, you can run the PowerShell prompt, initialize, and spin up Sitecore containers, as normal, by executing init.ps1 and up.ps1 scripts.

Configuring Sitecore

Wait until Sitecore spins up, navigate to a site collection, right-click it, and add another website calling it Second running on a hostname second.localhost.

Make sure second site uses the same exact application name as main, you can configure that from /sitecore/content/Site Collection/Second/Settings item, App Name field. That ensures the purpose of this exercise is for both sites to reuse the same rendering host application.

You should also make sure to match the values of the Predefined application rendering host fields of /sitecore/content/Site Collection/Second/Settings/Site Grouping/Second and /sitecore/content/Site Collection/Main/Settings/Site Grouping/Main items.

Another important field here is Hostname, make sure to set these fields for both websites:

Hostname

 

Now you are good to edit Home item of Second site. Multisite middleware does not affect the editing mode of Sitecore, so from there, you’ll see no difference.

Troubleshooting

If you’ve done everything right, but second.localhost resolves to the Main website, let’s troubleshoot. The very first location to check is .\src\temp\config.js file. This file contains sites variable with the array of sites and related hostnames to be used for the site resolution. The important fact is that a given file is generated at the build time, not runtime.

So, you open it up and see an empty array (config.sites = process.env.SITES || '[]') that means you just need to initialize the build, for example by simply removing and recreating the rendering host container:

docker-compose kill rendering
docker-compose rm rendering -f
docker-compose up rendering -d

Also, before running the above, it helps to check SXA Site Manager, which is available under the PowerShell Toolbox in Sitecore Desktop. You must see both sites and relevant hostnames there and in the correct order – make sure to move them as high as possible, as this site chain works by “first come – first served” principle.

Multisite

After rendering host gets recreated (it may take a while for both build and spinning up steps), check the site’s definition at .\src\temp\config.js again. It should look as below:

config.sites = process.env.SITES || '[{"name":"second","hostName":"second.localhost","language":""},{"name":"main","hostName":"main.localhost","language":""}]'

The amount of SXA client site records must match the records from SXA Site Manager. Now, running second.localhost in the browser should show you rendered home page of the second site.

Another technique of troubleshooting is to inspect middleware logs. To do so, create .env.local file at the rendering host app root (if does not exist yet) and add the debugging parameter:

DEBUG=sitecore-jss:multisite

Now, rendering host container logs will expose you the insights into how multisite middleware processes your requests and resolves site contexts, and sets site cookies. Below is a sample (and correct) output of the log:

sitecore-jss:multisite multisite middleware start: { pathname: '/', language: 'en', hostname: 'second.localhost' } +8h
sitecore-jss:multisite multisite middleware end in 7ms: {
  rewritePath: '/_site_second/',
  siteName: 'second',
  headers: {
  set-cookie: 'sc_site=second; Path=/',
  x-middleware-rewrite: 'https://localhost:3000/_site_second',
  x-sc-rewrite: '/_site_second/'
},
  cookies: ResponseCookies {"sc_site":{"name":"sc_site","value":"second","path":"/"}}
} +7ms

The above log is crucial to understanding how multisite middleware works internally. The internal request comes rewrites as <https://localhost:3000/_site_second where ‘second‘ is a tokenized site name parameter. If .\src\main\src\temp\config.js file contains the corresponding site record, site gets resolved and sc_site cookie is set.

If you still have the issues of showing up the Second website that resolves to Main website despite the multisite middleware log outputs correct site resolution, that may be likely caused by conflicting with other middleware processors.  This would be your number one thing to check especially if you have multiple custom middleware. Miltisie middleware is especially sensitive to the execution order, as it sets cookies. In my case, that problem was because Sitecore Personalize Engage SDK was registered through middleware and also programmed to set its own cookie, and somehow configured with multisite middleware.

In that case, you have to play with order constant within each conflicting middleware (they are all located under .\src\lib\middleware\plugins folder) with the following restart of a rendering host.

Resources Sharing

Since the multisite add-on leverages the same rendering host app for the multiple sites that use it, all the components and layouts TSX markups, middleware, and the rest of the resources become automatically available for the second site. However, that is not true by default for the Sitecore resources. We must assign at least one website that will share its assets, such as renderings, partials, layouts, etc across the entire Site Collection. Luckily, that is pretty easy to do at the site collection level:

Site Collection

For the sake of an experiment, let’s make Second website to use Page Designs from the Main site. After the above sharing permission, they are automatically available at /sitecore/content/Site Collection/Second/Presentation/Page Designs item.

Configuring the cloud

Once we make the multisite add-on function well, let’s make the same work in the cloud.

  1. First of all, check all the changes to the code repository, and trigger the deployment, either from Deploy App, CLI, or your preferred CI/CD
  2. After your changes arrive at XM Cloud environment – let’s bring the required changes to Vercel, starting with defining the hostnames for the sites:Vercel
  3. After you define the hostnames in Vercel, change the hostname under Site Grouping item for this particular cloud environment to match the above hostname configured earlier in Vercel.
  4. Save changes and smart publish Site Collection. Publishing takes some time, so please stay patient.
  5. Finally, you must also do Vercel full re-deployment, to force regenerating \src\temp\config.js file with the hostnames from Experience Edge published at the previous step

Testing

If everything is done right in the previous steps, you can access the published Second website from Vercel by its hostname, in our case that would be https://dev-second.vercel.app. Make sure all the shared partial layouts are seen as expected.

When testing 404 and 500 you will see that these are shared between both sites automatically, but you cannot configure them individually per site. This occurs because both are located at .\src\pages\404.tsx and .\src\pages\500.tsx of the same rendering host app and use different internal mechanics rather than generic content served from Sitecore throughout .\src\pages\[[...path]].tsx route. These error pages however could be multi-lingual, if needed.

Hope you find this article useful!

Sitecore 10.4 is out and here’s all you need to know about it

That was a decent gap since 1.5 years ago Sitecore previously released a feature-full version of their XM/XP platform, namely 10.3 was released on December 1st of 2022. That is why I was very excited to look through the newest release of the vendor’s self-hosted platforms and familiarize myself with its changes.

First and foremost, the 10.4 platforms could be exclusively obtained from a new download page which has moved to its new home at Sitecore Developer Portal. I recommend bookmarking that for the current and all future releases.

Release Notes

There is a list of impressive 200 changes and improvements coming along with official Release Notes. I recommend going through it especially paying attention to the Deprecated and Removed sections.

So, what’s New?

From the important features and changes, I’d focus on a few:

  • XM to XM Cloud Migration Tool for migrating content, media, and users from a source XM instance to an XM Cloud environment. This tool provides an aid for the routine and sometimes recurring back-end migrations, so our customers/partners can focus on migrating and developing new front-end sites.
  • xDB to CDP Migration Tool for transferring site visitor contact facets to Sitecore’s CDP and Personalize products, and also via Sitecore Connect to external systems. This provides the ability to interwork with or eventually adopt other SaaS-based innovations.
  • New /sitecore/admin/duplicates.aspx admin folder page addressing the change in media duplication behavior (now, the blobs are in fact also duplicated) – run it upon the migration to 10.4 in order to change the media items accordingly.
  • Added a new Codeless Schema Extension module, enabling business users to extend the xConnect schema without requiring code development. If that one was available earlier – it could significantly boost xDB usage by marketers. It will be generally available in mid-May 2024.
  • Improved accessibility to help content authors with disabilities.
  • Sitecore Client Content Reader role allows access into CM without the risk of breaking something – it was a frequently requested feature.
  • It is now possible to extract data from xDB and transform the schema for external analytics tools such as Power BI.
  • GraphQL is enabled by default on the CM container instance in the local dev – which totally makes sense to me.
  • Underlying dependencies updated to the latest – SQL Server 2022, latest Azure Kubernetes Service, Solr 8.11, etc.

Containers

Spinning up Sitecore in local Docker containers used to be the easiest way of starting up. However, the most important fact you have to consider for a containerized setup is that base images are only available for ltsc2022 platform, at least for now. If you are a lucky one using a Windows 11 machine – you get the best possible performance running Sitecore in Process isolation mode. Otherwise, you may struggle with Hyper-V compatibility issues.

The other thing I noticed is that SitecoreDockerTools is simply set to pull the latest version which is 10.3.40 at the time of writing.

Also, Traefik image remains on one of the older versions (not versions 3.x of Traefik, but 2.9.8 which was even older before – v2.2.0) that do not support ltsc2022 and therefore still uses Hyper-V isolation. You can however fix that manually to have each and every image running fast in Process isolation mode. As always, it helps a lot to examine the list of available published images as your own exercise as some were standardized.

Compared to previous versions, this one seems to be lightweight, with no helpful PowerShell scripts for up & down containers (so we use docker-compose directly) as well as clean-up scripts and others. As before, it supports all three default topologies – XP0, XM1, and XP1.

Sitecore Gallery Tips:

  • Tip 1: Sitecore Gallery has recently moved from MyGet https://sitecore.myget.org/F/sc-powershell/api/v2 to Sitecore hosted NuGet https://nuget.sitecore.com/resources/v2.
  • Tip 2: don’t forget to update the PackageManagement and PowerShellGet modules from PSGallery if needed, as below:
Install-Module -Name PackageManagement -Repository PSGallery -Force -AllowClobber
Install-Module -Name PowerShellGet -Repository PSGallery -Force -AllowClobber

Containers

If for some reason you cannot or are unwilling to use containers, there are other options: SIA and manual installations from a zip archive. Over the past years, I have created a tool called Sifon that is effectively better than SIA, because it can also install all the prerequisites, such as Solr and SQL Server of the required versions, along with downloading the necessary resources from the developer portal. I will add the support for 10.4 in the next few days or a week.

10.4 dashboard

Upon the installation, you will see the Sitecore Dashboard:

Sitecore 10.4 Dashboard

Version 10.4 now operates 010422 revision:

Version 10.4

SXA

This crucial module comes in the correspondent version 10.4 along with a newer 7.0 version of the Sitecore PowerShell Extensions module. The biggest news about this module is that it now supports Tailwind, in the same way as XM Cloud does:

Tailwind

Conclusion

In general, time will prove what I expect this version to be – the most mature version of Sitecore, working faster and more reliably with the updated underlying JavaScript-dependent libraries. I am impatiently waiting for the hot things such as AI integrations and the delayed feature set promised to appear later the month in May 2024 to explore and share about.

Cypress: a new generation of end-to-end testing

What is Cypress

Cypress is a modern JavaScript-based end-to-end (e2e) testing framework designed to automate web testing by running tests directly in the browser. Cypress has become a popular tool for web applications due to a number of distinctive advantages such as user-friendly interface, fast test execution, ease of debugging, ease of writing tests, etc.

Those who have already had any experience with this testing framework probably know about its advantages, which make it possible to ensure that projects are covered with high-quality and reliable autotests. Cypress has well-developed documentation, one of the best across the industry, with helpful recommendations for beginners, which is constantly being improved, as well as an extensive user community. However, despite the convenience, simplicity, and quick start, when we talk about Cypress tests, we still mean the code. In this regard, to work effectively with the persona behind Cypress requires not only an understanding of software testing as such but also the basics of programming, being more or less confident with JavaScript/TypeScript.

Why Cypress

Typically, to test your applications, you’ll need to take the following steps:

  • Launch the application
  • Wait until the server starts
  • Conduct manual testing of the application (clicking the buttons, entering random text in input fields, or submit a form)
  • Validate the result of your test being correct (such as changes in title, part of the text, etc.)
  • Repeat these steps again after simple code changes.

Repeating these steps over and over again becomes tedious and takes up too much of your time and energy. What if we could automate this testing process? Thanks to this, you can focus on more important things and not waste time testing the UI over and over again.

This is where Cypress comes into play. When using Cypress the only thing you need to do is:

  • Write the code for your test (clicking a button, entering text in input fields, etc.)
  • Start the server
  • Run or rerun the test

That’s it! The Cypress library cares about all the testing for you. It not only tells you if all your tests passed or not, but it also points to which test failed and why exactly.

How about Selenium

Wait, but we already have Selenium, is it still actual?

Selenium remained The King of automated testing for more than a decade. I remember myself back in 2015 creating a powerful UI wrapper for Selenium WebDriver to automate and simplify its operations for non-technical users. The application is named Onero and is still available along with its source code. But when it comes to Cypress – it already offers powerful UI straight out of the box, and much more useful tools and integrations – just keep reading to find this below.

Cypress is the next generation web testing platform. It was developed based on Mocha and is a JavaScript-based end-to-end testing framework. That’s how it is different to Selenium which is a testing framework used for web browser automation. Selenium WebDriver controls the browser locally or remotely and is used to test UI automation.

The principal difference is that Cypress runs directly in browser, while Selenium is external to a browser and controls it via WebDriver. That alone makes Cypress much perfectly handling async operations and waits, which were all the time issues for Selenium and required clumsy scaffolding around related error handling.

With that in mind, let’s compare Cypress vs. Selenium line by line:

With that in mind, let’s compare Cypress vs. Selenium line by line:

Cypress Selenium
Types of testing Front end with APIs, end-to-end End-to-end, doesn’t support API testing
Supported languages JavaScript/Typescript Multiple languages are supported, such as Java, JavaScript, Perl, PHP, Python, Ruby, C#, etc.
Audience Developers as well as testers Automation engineers, testers
Ease of Use For those familiar with JavaScript, it will be an easy walk. Otherwise, it will be a bit tricky. It is still developer-friendly being designed keeping developers in mind. It also has a super helpful feature called “travel back in time.” As it supports multiple languages, people can quickly start writing tests, but it’s more time-consuming than Cypress as you have to learn specific syntax.
Speed It has a different architecture that doesn’t utilize a web driver and therefore is faster, also Cypress is written with JavaScript which is native to browsers where it executes. Because of its architecture, it’s hard to create simple, quick tests. However, the platform itself is fast, and you can run many tests at scale, in parallel, and cross-browser.
Ease of Setup Just run the following command: npm install Cypress –save-dev. It requires no other component installation (unlike web driver) as Selenium does, you don’t even have to have a browser as it can use Electron. Also, everything is well-bundled. As it has two component bindings and a web driver. Installation is more complicated and time-consuming.
Integrations & Plugins It has less integrations which is compensated by a rich set of plugins. Perfectly runs in Docker containers and supports GitHub Actions. It integrates with CI, CD, visual testing, cloud vendors, and reporting tools.
Supported Browsers Supports all Chromium-based browsers (Chrome, Edge, Brave) and Firefox. All browsers: Chrome, Opera, Firefox, Edge, Internet Explorer, etc along with the “scriptable headless” browser – PhantomJs.
Documentation Helpful code samples and excellent documentation in general Average documentation.
Online Community & support A growing community, but smaller then Selenium gained over a decade. It has a mature online community.

Selenium is aimed more at QA automation specialists, while Cypress is aimed merely at developers to improve TDD efficiency. Selenium was introduced in 2004, so it has more ecosystem support than Cypress, which was developed in 2015 and continues to expand.

Installation and first run

You need to have Node.js and as Cypress is shipped with npm module.

npm -i init
npm install cypress -- save -dev

Along with Cypress itself, you will likely want to install XPath plugin, otherwise, you’re limited to only CSS locators.

npm install -D cypress-xpath

Once ready, you may run it:

npx cypress open

From there you'll see two screens: E2E Testing and Components Testing

Main Screen

Most of the time you will likely be dealing with E2E testing. That’s where you choose your desired browser and execute your tests:

E2e

By default you’ll find a live documentation in a form of a bunch of helpful pre-written tests exposing best of Cypress API in action. Feel free to modify, copy and paste as per your needs.

Tests

Here’s how Cypress executes tests from the UI on an example of sample test run:

Sample Run

But of course, in a basic most scenario you can run it from console, You can even pass a specific test spec file to execute:

npx cypress run --spec .\cypress\e2e\JumpStart\JumpStart.cy.js

Regardless of the execution mode, results will stay persistent:

From Console

Component Testing

This feature was recently added and stayed long time in preview. Now once it is out of beta, let’s take a look at what Component Testing is.

Instead of working with the entire application, with component testing you can simply connect a component in isolation. This will save you time by downloading only the parts you’re interested in, and will allow you to test much faster. Or you can test different properties of the same component and see how they display. This can be very useful in situations where small changes affect a large part of the application.

Component

In addition to initializing the settings, Cypress will create several support files, one of the most important is component.ts, located in the cypress/support folder.

import { mount } from 'cypress/react18'

declare global {
    namespace Cypress {
    interface Chainable {
        mount: typeof mount
    }
    }
}

Cypress.Commands.add('mount', mount)

// Example of usage:
// cy.mount(MyComponent)

This file contains the component mount function for the framework being used. Cypress supports React, Angular, Svelte, Vue, and even frameworks like Next.js and Nuxt.

Cypress features

  1. Time travel
  2. Debuggability
  3. Automatic waits (built-in waits)
  4. Consistence results
  5. Screenshots and videos
  6. Cross browser testing – locally or remotely

I want to focus on some of these features.

Time Travel. This is an impressive feature that allows you to see the current state of your application at any time while it is being tested.

Debuggability. Your Cypress test code runs in the same run loop as your application. This means you have access to the code running on the page, as well as the things the browser makes available to you, like document, window, and debugger. You can also leverage .debug() function to quickly inspect any part of your app right while running a test. Just attach it to any Cypress chain of commands to have a look at the system’s state at that moment:

it('allows debugging like a pro', ()=>{
    cy.visit('/location/page')
    cy.get('[data-id="selector"]').debug()
})

Automatic waits. Aa a key advantage over Selenium, Cypress is smart to know how fast an element is animating and will wait for it to stop animating before acting against it. It will also automatically wait until an element becomes visible, becomes enabled, or when another element is no longer covering it.

Consistence results. Due to its architecture and runtime nuances, Cypress fully controls the entire automation process from top to bottom, which puts it in the unique position of being able to understand everything happening in and outside of the browser. This means Cypress is capable of delivering more consistent results than any other external testing tool.

Screenshots and videos. Cypress can work on screenshots and videos. One can capture both the complete page and particular element screenshot with the screenshot command in Cypress. Cypress also has the in-built feature to capture the screenshots of failed tests. To capture a screenshot of a particular scenario, we use the command screenshot.

describe('Test with a screenshot', function(){
    it("Test case 1", function(){
        //navigate URL
        cy.visit("https://microsoft.com/windows")

        //complete page screenshot with filename - CompletePage
        cy.screenshot('CompletePage')

        //screenshot of the particular element
        cy.get(':nth-child(3) > section').screenshot()
    });
});

Produced screenshots appear inside the screenshots folder (in the plugins folder) of the project, but that’s configurable from the globals.

Cypress video capturing executes for tests. Enable it from cypress.config.ts:

import{ defineConfig } from 'cypress'

export default defineConfig({
    video: true,
})

Please refer to the official documentation that explains how to use screenshots and videos with Cypress.

GitHub Actions Integration

Cypress nicely allows to run tests in Cypress using GitHub Actions.

To do this on the GitHub Action server, you first need to install everything necessary. We also need to determine when we want to run tests (for example, run them on demand or every time new code is introduced). This is how we gradually define what GitHub Actions will look like. In GitHub Actions, these plans are called “workflows”. Workflow files are located under .github/workflows folder. Each file is a YAML with a set of rules configuring what and how will get executed:

name: e2e-tests

on:[push]

jobs:
    cypress-run:
    runs-on: ubuntu-latest
    steps:
        - name: Checkout
        uses: actions/checkout@v3
        - name: Cypress run
        uses: cypress-io/github-action@v5
        with:
            start: npm start
    

Let’s look at what’s going on in this file. In the first line, we give the action a name. It can be anything, but it is better to be descriptive.

In the first line, we give the action a name. In the second line, we define the event on which this script should be executed. There are many different events, such as push, pull_request, schedule, or workflow_dispatch (that allows you to trigger an action manually).

The third line specifies the task or tasks to be performed. Here we must determine what needs to be done. If we were starting from scratch, this is where we would run npm install to install all the dependencies, run the application, and run tests on it. But, as you can see, we are not starting from scratch, but using predefined actions – instead of doing that, we can re-use previously created macros. For example, cypress-io/github-action@v5 will run npm install, correctly cache Cypress (so installation will be faster next time), start the application with npm start, and run npx cypress run. And all this with just four lines in a YAML file.

Run Cypress in containers

In modern automated testing, setting up and maintaining a test environment can often be a time-consuming task, especially when working with multiple dependencies and their configurations, different operating systems, libraries, tools, and versions. Often one may encounter dependency conflicts, inconsistency of environments, limitations in scalability and error reproduction, etc., which ultimately leads to unpredictability and unreliability of testing results.

Using Docker greatly helps prevent most of these problems from occurring and the good news is that you can do that. In particular, using Cypress in Docker can be useful because:

  1. It ensures that Cypress autotests run in an isolated test environment. In this case, the tests are essentially independent of what is outside the container, which ensures the reliability and uninterrupted operation of the tests every time they are launched.
  2. For running it locally, this means the absence of Node.js, Cypress, any exotic browser on the host computer – that won’t become an obstacle. This not just allows to run Cypress locally on different host computers but also deploy them in CI/CD pipelines and to cloud services by ensuring uniformity and consistency in the test environment. When moving a Docker image from one server to another, containers with the application itself and tests will work the same regardless of the operating system used, the presence of Node.js, Cypress, browsers, etc. This ensures that Cypress autotests are reproducible and the results of running them predictable across different underlying systems.
  3. Docker allows you to quickly deploy the necessary environment for running Cypress autotests, and therefore you do not need to install operating system dependencies, the necessary browsers, and test frameworks each time.
  4. Speeds up the testing process by reducing the total time for test runs. This is achieved through scaling, i.e. increasing the number of containers, running Cypress autotests in different containers in parallel, parallel cross-browser testing capabilities using Docker Compose, etc.

The official images of Cypress

Today, the public Docker Hub image repository, as well as the corresponding cypress-docker-images repository on GitHub, hosts 4 official Cypress Docker images:

Limitations of Cypress

Nothing is ideal on Earth, so Cypress also has some limitations mostly caused by its unique architecture:

  1. One cannot use Cypress to drive two browsers at the same time
  2. It doesn’t provide support for multi-tabs
  3. Cypress only supports JavaScript for creating test cases
  4. Cypress doesn’t provide support for browsers like Safari and IE at the moment
  5. Reading or writing data into files is difficult
  6. Limited support for iFrames

Conclusion

Testing is a key step in the development process as it ensures that your application works correctly. Some programmers prefer to manually test their programs because writing tests requires a significant amount of time and energy. Fortunately, Cypress has solved this problem by allowing the developer to write tests in a short amount of time.

Storybook

You may have never heard of Storybook or maybe that was just a glimpse leaving you a feeling Storybook is such an unnecessary tool – in that case, this article is for you. Previously, I could share this opinion, but since I played with Storybook in action when building the XM Cloud starter kit with Next.Js, it changed.

Storybook

Why

With the advent of responsive design, the uniqueness of user interfaces has increased significantly – with the majority of them having bespoke nuances. New requirements have emerged for devices, browser interfaces, accessibility, and performance. We started using JavaScript frameworks, adding different types of rendering to our applications (CSR, SSR, SSG, and ISR) and breaking the monolith into micro-frontends. Ultimately, all this complicated the front end and created the need for new approaches to application development and testing.

The results of a 2020 study showed that 77% of developers consider current development to be more complex than 10 years ago. Despite advances in JavaScript tools, professionals continue to face more complex challenges. The component-based approach used in React, Vue, and Angular helps break complex user interfaces into simple components, but it’s not always enough. As the application grows, the number of components increases; in serious projects, there can be hundreds of them, which gives thousands of permutations. To even further complicate matters, interfaces are difficult to debug because they are entangled in business logic, interactive states, and application context.

This is where Storybook comes to the rescue.

What Storybook is

Storybook is a tool for the rapid development of UI components. It allows you to view a library of components and track the status of each of them. With StoryBook, one can develop components separately from the application, making it easier to reuse and test UI components.

Storybook promotes the Component-Driven Development (CDD) approach, where every part of the user interface is a component. These are the basic building blocks of an application. Each of them is developed, tested, and documented separately from the others, which simplifies the process of developing and maintaining the application as a whole.

A component is an independent fragment of the application interface. In Sitecore, in most cases, a component is equal to a rendering, for example, CTA, input, badge, and so on. If we understand the principles of CDD and know how to apply this approach in development, we can use components as the basis for creating applications. Ideally, they should be designed independently from each other and be reusable in other parts of the application. You can approach creating components in different ways: start with smaller ones and gradually combine them into larger ones, and vice versa. You can create them both within the application itself and in a separate project – in the form of a library of components.

With Storybook’s powerful functionality, you can view your interfaces the same way users do. It provides the ability to run automated tests, analyze various interface states, work with mock data, create documentation, and even conduct code reviews. All these tasks are performed within the framework of the so-called Story, which allows you to effectively use Storybook for development.

What is a Story

This is the basic unit of Storybook design and allows you to demonstrate different states of a component to test its appearance and behavior. Each component can have multiple stories, and each one can be treated as a separate test case to test the functionality of the component.

You write stories for specific states of UI components and then use them to demonstrate the appearance during development, testing, and documentation.

Using the Storybook control panel, you can edit each of the story function arguments in real time. This allows your team to dynamically change components in Storybook to test and validate different edge cases.

Storybook explained

Storybook Capabilities

Creating documentation

Storybook provides the ability to create documentation along with components, making the process more convenient. With its help, you can generate automatic documentation based on code comments, as well as create separate pages with examples of use and descriptions of component properties. This allows you to maintain up-to-date and detailed documentation that will be useful not only for developers but also for designers, testers, and users.

User Interface Testing

Another good use of Storybook – UI Tests identify visual changes to interfaces. For example, if you use Chromatic, the service takes a snapshot of each story in a cloud browser environment. Each time you push the code, Chromatic creates a new set of snapshots to compare existing snapshots with those from previous builds. The list of visual changes is displayed on the build page in the web application so that you can check if these changes are intentional. If they are not, that may be a bug or glitch to be corrected.

Accessibility Compliance

As The State of Frontend 2022 study found, respondents pay high attention to accessibility, with 63% predicting this trend will gain more popularity in the coming years. Accessibility in Storybook can be tested using the storybook-addon-a11y. Upon the installation, the “Accessibility” tab will appear, for you to see the results of the current audit.

Mocking the data

When developing components for Storybook, one should consider realistic data to demonstrate the capabilities of the components and simulate a real-life use case. For this purpose, mock data is often taken, that is, fictitious data that has a structure and data types similar to real ones but does not carry real information. In Storybook, you can use various libraries to create mock data, and you can also create your own mocks for each story. If a component itself needs to perform network calls pulling data, you can use the msw library.

Simulating context and API

Storybook addons can help you simulate different component usage scenarios, such as API requests or different context values. This will allow you to quickly test components in realistic scenarios. If your component uses a provider to pass data, you can use a decorator that wraps the history and provides a cloaked version of the provider. This is especially useful if you are using Redux or context.

Real-life advantages

Wasting resources on the user journey

Building a landing page may seem to be a simple exercise, especially in a development mode when you see changes appear in the browser immediately. However, the majority of cases are not that straightforward. Imagine a site with a backend entirely responsible for routing – and one may need to login first, answer the security questions, and then navigate through the complex menu structure. Say you only need to “change the color of a button” on the final screen of the application, then the developer needs to launch the application in its initial state, login, get to the desired screen, fill out all the forms along the way, and only after that check whether the new style has been applied to the button.

If the changes have not been applied, the entire sequence of actions must be repeated. Storybook solves this problem. With it, a developer can open any application screen and instantly see how it looks, taking into account the applied styles and the desired state. This allows you to significantly speed up the process of developing and testing components since they can be tested and verified independently of the backend and other parts of the application.

Development without having actual data

Often the UI development takes place before the API is ready from the backend developers. Storybook allows you to create components that stub data that will be retrieved from the real API in the future. This allows us to prototype and test the user interface, regardless of the presence or readiness of the backend, and use mock data to demonstrate components.

Frequently changing UI

On a project, we often encounter changes in layout design, and it is very important for us to quickly adapt our components to these changes. Storybook allows you to quickly create and compare different versions of components, helping you save time and make your development process more efficient.

Infrastructural issues

The team may encounter problems when a partner’s test environment or dependencies stop working, which leads to delays and lost productivity. However, with Storybook, it is possible to continue developing components in isolation and not wait for service to recover. Storybook also helps to quickly switch between your application versions and test components in different contexts. This significantly reduces downtime and increases productivity.

Knowledge transfer

In large projects, onboarding may take a lot of time and resources. Storybook allows new developers to quickly become familiar with components and how they work, understand the structure of the project, and start working on specific components without having to learn everything from scratch. This makes the development process easier and more intuitive, even for those not familiar with a particular framework.

Application build takes a long time

Webpack is a powerful tool for building JavaScript applications. However, when developing large applications, building a project can take a long time. Storybook automatically compiles and assembles components whenever changes occur. This way, developers quickly receive updated versions of components without a need to rebuild the entire project. In addition, Storybook supports additional plugins and extensions for Webpack, to improve performance and optimize project build time.

Installation

First, install Storybook using the following commands:

cd nextjs-app-folder
npx storybook@latest init

 

Once installed, execute it:

npm run storybook

This will run Storybook locally, by default on por 6066, but if the port is occupied – it will pick an alternative one.

Storybook

Storybook is released under the MIT license, you can access its source code in the GitHub repository.

Making it with Sitecore

When developing headless projects with Sitecore, everything stays in the same manner. As part of our mono repository, we set up Storybook with Next.js so that front-end developers don’t have to run an instance of Sitecore to do their part of the development work.

Upon installation, you’ll find a .storybook folder at the root of your Next.Js application (also used as a rendering host) which contains configuration and customization files for your Storybook setup. This folder is crucial for tailoring Storybook to your specific needs, such as setting up addons, and Webpack configurations, and defining the overall behavior of Storybook in your project.

  1. main.js(or main.ts): this is the core configuration file for Storybook. It includes settings for loading stories, adding add-ons, and custom Webpack configurations. You can specify the locations of your story files, add an array of addons you’re using, and customize the Webpack and Babel configs as needed.
  2. preview.js(or preview.tsx): used to customize the rendering of your stories. You can globally add decorators and parameters here, affecting all stories. This file is often used for setting up global contexts like themes, internationalization, and configuring the layout or backgrounds for your stories.

02

One of the best integrations (found from Jeff L’Heureux) allows you to use your own Sitecore context mock and also any placeholder to use any of your components (see the lines below decorators).

import React from 'react';
import {LayoutServicePageState, SitecoreContext} from '@sitecore-jss/sitecore-jss-nextjs';
import {componentBuilder} from 'temp/componentBuilder';
import type { Preview } from '@storybook/react';
import 'src/assets/main.scss';
export const mockLayoutData = {
  sitecore: {
    context: {
      pageEditing: false,
      pageState: LayoutServicePageState.Normal,
},
    setContext: () =>{
    // nothing
},
    route: null,
},
};
const preview: Preview = {
  parameters: {
    actions: { argTypesRegex: '^on[A-Z].*'},
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/,
      },
    },
},
  decorators: [
    (Story) =>(
      <SitecoreContext
              componentFactory={componentBuilder.getComponentFactory({ isEditing: mockLayoutData.sitecore.context.pageEditing})}
              layoutData={mockLayoutData}
      >
        <Story />
      </SitecoreContext>
    ),
  ],
};

export default preview;

It is important to understand that getServerSide/getStaticProps are not executed when using Storybook. You are responsible for providing all the required data needed as well as context, so you need to wrap your story or component.

Component level fetching works nicely with Sitecore headless components using MSW – you can just mock fetch API to return the required data from inside of the story file.

Useful tips for running Storybook for Headless Sitecore

  • use next-router-mock to mock the Nextjs router in Storybook (or upgrade to version 7 with the @storybook/nextjs)
  • exclude stories from the componentFactory / componentBuilder file.
  • make sure to run npm run bootstrap before starting storybook or adding it to the package.json, something like: "prestorybook": "npm-run-all --serial bootstrap" – when the storybook script is invoked, this prestorybook will automatically run just before, using a default NPM feature.

Conclusion

The Storybook integration into a Sitecore headless project will require you to invest some time digging into it, but offers numerous benefits, including improved component visualization, and isolation for development and testing.