﻿#### 

Previously, in the [Running custom next.js editing host in Sitecore XM Cloud](https://www.brimit.com/blog/running-custom-next-js-editing-host-in-sitecore-xm-cloud) article, I wrote about running a custom editing host app in XM Cloud. In this article I want to share my experience deploying and running a custom headless Sitecore solution, which issues I faced and how I solved them.

Let’s define what I have at the beginning:

- Sitecore 10.2 XM
- JSS 19.0
- SXA 10.2
- JSS next.js rendering host app of version 19.0
- Sitecore Content Serialization as a system for serializing, sharing, and deploying content items, as well as keeping them in version control.
- Helix based .NET solution
- Hosting in Azure Kubernetes Services

The main goal of all I will describe in this article is to measure the time that I need to move our project form AKS to Sitecore XM Cloud. Once I hadn’t had any experience with XM cloud before, I started from reading documentation. Finally, comparing a [starting kit solution](https://github.com/sitecorelabs/xmcloud-foundation-head) with what I have, I identified the following:

1. I need to update references for my project. Almost all Sitecore assemblies have to be replaced with *Sitecore.XmCloud*:

| &lt;?xml version="1.0" encoding="utf-8"?&gt;<br>
            &lt;Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;<br>
              &lt;PropertyGroup&gt;<br>
                &lt;PlatformVersion&gt;1.\*&lt;/PlatformVersion&gt;<br>
                &lt;SitecoreVersion&gt;10.2.0&lt;/SitecoreVersion&gt;<br>
              &lt;/PropertyGroup&gt;<br>
              &lt;ItemGroup&gt;<br>
                &lt;PackageReference Update="Sitecore.Nexus" Version="$(SitecoreVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.Kernel" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.Mvc" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.ContentSearch" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.ContentSearch.Linq" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.ContentSearch.ContentExtraction" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.ExperienceForms.Client" Version="$(SitecoreVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.LayoutService" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.LayoutService.Mvc" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.Assemblies" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.XA.Foundation.Sitecore.XmCloudExtensions" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.Assemblies.SitecoreHeadlessServicesServer" Version="19.\*" /&gt;<br>
                &lt;PackageReference Update="RichardSzalay.Helix.Publishing.WebRoot" Version="1.5.6" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.XA.Feature.Search" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.XA.Foundation.Abstractions" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.XA.Feature.SiteMetadata" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.Services.Core" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.XA.Foundation.Search" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.ExperienceForms.Mvc" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.JavaScriptServices.Configuration" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Sitecore.XmCloud.JavaScriptServices.ViewEngine" Version="$(PlatformVersion)" /&gt;<br>
                &lt;PackageReference Update="Microsoft.AspNet.Mvc" Version="5.2.7" /&gt;<br>
              &lt;/ItemGroup&gt;<br>
            &lt;/Project&gt;<br>
            } |
| --- |

I have replaced all assemblies that I have found a corresponding *Sitecore.XmCloud* assembly for. And I have updated the dependencies in *.csproj* files. But in general, I don’t think it is required to replace them because we don’t include any Sitecore libraries into the final package, but from my point of view it allows us to make sure that our core is compilable in XM Cloud. 

2. We have to [upgrade the Sitecore Command Line Interface to version 5](https://doc.sitecore.com/xp/en/developers/102/developer-tools/upgrade-the-sitecore-command-line-interface-to-version-5.html) and add  [XM Cloud plugin](https://doc.sitecore.com/xmc/en/developers/xm-cloud/install-the-xm-cloud-plugin.html):

![Sitecore CLI](https://www.brimit.com/-/media/project/brimit/blog/2022/rh-in-aks/cli.png)

3. we need to add the *xmcloud.build.json* in the root of our solution. This article describes which parameters we have in the configuration: 

| {<br>
                "deployItems": {<br>
                    "modules": [<br>
                        "Foundation.\*",<br>
                        "Feature.\*",<br>
                        "Project.\*"<br>
                    ]<br>
                },<br>
                "buildTargets": [<br>
                  "./DemoCloud.sln"<br>
                ],<br>
                "renderingHosts": {<br>
                    "global": {<br>
                        "path": "./src/Project/Demo/nextjs",<br>
                        "nodeVersion": "14.15.3",<br>
                        "jssDeploymentSecret":"dd5d764c4776459e92e1233b8cde0ab5",<br>
                        "enabled": true,<br>
                        "type": "sxa"<br>
                    }<br>
                }<br>
            } |
| --- |

Where,

- **deployItems** - Allows you to define what serialization item modules you want to deploy. It is similar to the serialization configuration defined in the sitecore.json file. Useful to limit what you deploy when working locally.
- **buildTargets** - Allows you to define which projects and solutions to build.
- **renderingHosts** - Allows you to configure the location for the rendering hosts and the sites they map to. I wrote about this parameter in more detail in [this](https://www.brimit.com/blog/running-custom-next-js-editing-host-in-sitecore-xm-cloud) article.

I would like to pay attention to **buildTargets** parameter because it, actually, defines what will be built. In our solution we were using a “build” project. It is a project which referrer all Helix based projects (Foundations, Features and Projects) and publish them to the target folder. Even if we build a solution file, it raises a build of this project and we get all libraries published into the target. It works perfectly with docker build but, unfortunately, it doesn’t work with XM Cloud at all. Of course, we can define each project in the buildTargets array, but it is something that I definitely don’t want to do. 

I found another way to solve the issue. Maybe it is not the best solution, but it works for me. 

- I have refactored all *.csproj* files to enable auto publish on build:

| &lt;!-- Begin Publish on Build --&gt;<br>
              &lt;PropertyGroup&gt;<br>
                &lt;DisableFastUpToDateCheck&gt;true&lt;/DisableFastUpToDateCheck&gt;<br>
                &lt;PublishProfile&gt;Local&lt;/PublishProfile&gt;<br>
              &lt;/PropertyGroup&gt;<br>
              &lt;PropertyGroup&gt;<br>
                &lt;AutoPublish Condition="'$(AutoPublish)' == '' and '$(Configuration)' == 'Debug' and '$(BuildingInsideVisualStudio)' == 'true' and '$(PublishProfile)' != ''"&gt;true&lt;/AutoPublish&gt;<br>
                &lt;AutoPublishDependsOn Condition="'$(AutoPublish)' == 'true'"&gt;<br>
                  $(AutoPublishDependsOn);<br>
                  WebPublish<br>
                &lt;/AutoPublishDependsOn&gt;<br>
              &lt;/PropertyGroup&gt;<br>
              &lt;Target Name="AutoPublish" AfterTargets="Build" DependsOnTargets="$(AutoPublishDependsOn)"&gt;<br>
              &lt;/Target&gt;<br>
              &lt;!-- End Publish on Build --&gt; |
| --- |

- I have added *Local.pubxml* to the *Properties\PublishProfiles\* with the following content for local testing purposes. This pablish profile will be overridden by XM Cloud anyway:

| &lt;Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;<br>
              &lt;PropertyGroup&gt;<br>
                &lt;WebPublishMethod&gt;FileSystem&lt;/WebPublishMethod&gt;<br>
                &lt;PublishProvider&gt;FileSystem&lt;/PublishProvider&gt;<br>
                &lt;LastUsedBuildConfiguration&gt;Debug&lt;/LastUsedBuildConfiguration&gt;<br>
                &lt;LastUsedPlatform&gt;Any CPU&lt;/LastUsedPlatform&gt;<br>
                &lt;SiteUrlToLaunchAfterPublish /&gt;<br>
                &lt;LaunchSiteAfterPublish&gt;True&lt;/LaunchSiteAfterPublish&gt;<br>
                &lt;ExcludeApp\_Data&gt;False&lt;/ExcludeApp\_Data&gt;<br>
                &lt;publishUrl&gt;..\..\..\..\docker\deploy\platform&lt;/publishUrl&gt;<br>
                &lt;DeleteExistingFiles&gt;False&lt;/DeleteExistingFiles&gt;<br>
              &lt;/PropertyGroup&gt;<br>
            &lt;/Project&gt; |
| --- |

- I have added for each project {PROJECT-NAME}.wpp.targets file specify what need to be included into the target folder:

| &lt;?xml version="1.0" encoding="utf-8"?&gt;<br>
            &lt;!--<br>
              A .wpp.targets file can be used to configure web application publishing.<br>
              https://docs.microsoft.com/en-us/aspnet/web-forms/overview/deployment/advanced-enterprise-web-deployment/excluding-files-and-folders-from-deployment<br>
            --&gt;<br>
            &lt;Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;<br>
              &lt;!--<br>
                Use the SitecoreAssemblies ItemGroup provided by the Sitecore.Assemblies.Platform<br>
                package in order to prevent built-in Sitecore assemblies from publishing.<br>
                https://doc.sitecore.com/developers/93/sitecore-experience-manager/en/sitecore-assembly-list-nuget-packages.html<br>
            <br>
                Delay executing this target until after Compile in order to<br>
                ensure the NuGet package targets have been evaluated.<br>
              --&gt;<br>
              &lt;Target Name="ExcludeSitecoreAssemblies" AfterTargets="Compile"&gt;<br>
                &lt;ItemGroup&gt;<br>
                  &lt;ExcludeFromPackageFiles Include="@(SitecoreAssemblies -&gt; 'bin\%(Filename)%(Extension)')" /&gt;<br>
                  &lt;ExcludeFromPackageFiles Include="@(SitecoreAssemblies -&gt; 'bin\%(Filename).pdb')" /&gt;<br>
                  &lt;ExcludeFromPackageFiles Include="@(SitecoreAssemblies -&gt; 'bin\%(Filename).xml')" /&gt;<br>
                &lt;/ItemGroup&gt;<br>
              &lt;/Target&gt;<br>
            &lt;/Project&gt; |
| --- |

To make the exclusions above working, your project should have a reference to the Sitecore.XmCloud.Assemblies assembly. 

When I finished all the refactoring above, I was able to successfully run my project in XM Cloud. For my small project it took around 2 hours which I think was a pretty good result.

###### More from author

[##### Running custom next.js editing host in Sitecore XM Cloud
September 29, 2022](https://www.brimit.com/blog/running-custom-next-js-editing-host-in-sitecore-xm-cloud)[##### Running node.js based rendering host in Sitecore Managed Cloud
August 3, 2022](https://www.brimit.com/blog/running-node-js-based-rendering-host-in-sitecore-managed-cloud)[##### Running node.js based rendering host in AKS
June 17, 2022](https://www.brimit.com/blog/running-node-js-based-rendering-host-in-aks)

###### Author

[!\[artsiom-photo\](https://www.brimit.com/-/jssmedia/feature/blogs/authors/artsiom-200.jpg?h=202&amp;iar=0&amp;w=200&amp;hash=41797D2540DF6EB6FDF558360F6F62B8)
Artsem Prashkovich
Sitecore MVP/ Solution Architect](https://www.brimit.com/blog/author?authors=Artsem%20Prashkovich)

###### More by category

[#Events](https://www.brimit.com/blog?categories=#Events)[#How-to](https://www.brimit.com/blog?categories=#How-to)[#News](https://www.brimit.com/blog?categories=#News)[#Guides](https://www.brimit.com/blog?categories=#Guides)

###### More by platform

[DXP](https://www.brimit.com/blog?platforms=DXP)[Sales and marketing automation](https://www.brimit.com/blog?platforms=Sales%20and%20marketing%20automation)[Application innovation](https://www.brimit.com/blog?platforms=Application%20innovation)

#### More on Sitecore

[!\[How Vercel Will Help You Save Effort When Deploying Sophisticated Sitecore Projects\](https://www.brimit.com/-/jssmedia/project/brimit/blog/2024/vercel_cover-image.png)
#Guides#How-toDXPE-commerce
##### How Vercel Will Help You Save Effort When Deploying Sophisticated Sitecore Projects
Optimize and accelerate the development and deployment of complex multisite Sitecore projects.
Alexei Vershalovich on July 17, 2024](https://www.brimit.com/blog/how-vercel-will-help-you-save-effort-when-deploying-sophisticated-sitecore-projects)

[!\[Training Up Tomorrow's Sitecore MVPs: a Mentoring Success Story\](https://www.brimit.com/-/jssmedia/project/brimit/blog/2023/sitecore-mentoring---cover-image.png)
#How-toDXP
##### Training Up Tomorrow's Sitecore MVPs: a Mentoring Success Story
How to participate in the Sitecore Mentor program and help younger colleagues jump-start a career in Sitecore development.
Sergey Baranov on October 2, 2023](https://www.brimit.com/blog/training-up-tomorrows-sitecore-mvps)

[!\[Going Headless. Part 2: When a Headless CMS Is Your Best Bet (if you have Sitecore)\](https://www.brimit.com/-/jssmedia/project/brimit/blog/2022/headless/adobestock_456986731.jpg)
#How-toDXPE-commerce
##### Going Headless. Part 2: When a Headless CMS Is Your Best Bet (if you have Sitecore)
Discover how a headless CMS can benefit organizations that use Sitecore.
Daniil Raschupkin, Palina Trokhautsava on September 15, 2022](https://www.brimit.com/blog/going-headless-part-2-when-a-headless-cms-is-your-best-bet-if-you-have-sitecore)

![](https://bat.bing.net/action/0?ti=187017043&amp;tm=gtm002&amp;Ver=2&amp;mid=73a7249b-146f-4d7f-8b29-94b29aa01d94&amp;bo=2&amp;gtm_tag_source=1&amp;pi=0&amp;lg=en-US&amp;sw=800&amp;sh=600&amp;sc=24&amp;nwd=1&amp;tl=Deploy%20custom%20headless%20Sitecore%20solution%20in%20Sitecore%20XM%20Cloud&amp;kw=Sitecore,XM,Cloud,JSS,Backend,Serialization&amp;p=https%3A%2F%2Fwww.brimit.com%2Fblog%2Fdeploy-custom-headless-sitecore-solution-in-sitecore-xm-cloud&amp;r=&amp;lt=305&amp;evt=pageLoad&amp;sv=2&amp;asc=D&amp;cdb=AQAY&amp;rn=46287)