There are number of manuals of how to get started with ASP.NET Core Rendering SDK for Sitecore, so this post will just summarize everything up and, maybe, specify some hidden points that may be not obvious for newcomers.
Headless CMS concept
Let’s start with reminding that headless approach slightly differs from the regular. It allows to move markup generation to a lightweight application (Rendering host) out of Sitecore instance. This allows developers to use modern technologies such as ASP.NET Core, Next.js, React, Angular or Vue.js to work with Sitecore and use familiar tools to develop and debug their code. This also reduce number of deployments to Sitecore instance, saving huge amount of time for it’s restart after each deploy.
To achieve this, Sitecore provides needed data thru specific endpoints as well as SDKs to work with them from rendering host applications.
Overview of key parts
Sitecore part
To start you journey you obviously need a Sitecore instance. There are two options that you have: regular instance (v10.2+) with installed Headless Services module or Sitecore XM Cloud instance (which is basically the same but with headless services out of the box). It will be a good decision to use official container deployment of Sitecore XM Cloud. I don’t think that it is something special here as there are a lot of manuals available around this topic.
Rendering host
Rendering host it’s an actual application (website) you’re going to create and work with as a developer. As said earlier, rendering host is responsible for user requests processing and it communicates with Sitecore internally thru available endpoints to get needed data. All communication appears over HTTP using REST or GraphQL techniques to request data and receive JSON from Sitecore in response. As you might understand, any technology may be used to create rendering host, but Sitecore provides SDKs for ASP.NET Core and Javascript (Next.js, React, Angular, Vue.js). So, Sitecore may be approximately considered as Data layer in 3-layer architecture, while Rendering host responsible for Business and Presentation layers.
For example: user requests a page from your site. Rendering host will get it, optionally preprocess, form the request to Sitecore’s Layout Service, retrieve the response in JSON which will contain context information (item, fields, presentation details, datasources, etc) and render HTML with Rendering Engine based on this data.
Changes in basic concepts
Data Access and services
There are no direct access to Sitecore Databases from Rendering Host. In fact, Rendering Host not even know about core, master or web. So, it’s not possible to write something like Sitecore.Context.Database.GetItem(<ITEM_ID>) or even Sitecore.Globalization.Translate.Text(“Text”) on Rendering Host side anymore. You should pass all needed data to renderings with datasource (see Changes in presentation details) or use services to retrieve needed data.
Changes in configuration (Apps)
In traditional Sitecore CMS you had to configure site instance when you starting a new one. Aside with <site> definitions headless approach requires to define App by adding <app> entry to sitecore-javaScriptServices-apps node. This change only needed when you want to edit your pages with Experience Editor.
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<javaScriptServices>
<apps>
<app name="exampleApp"
sitecorePath="/sitecore/content/ExampleApp"
inherits="defaults"
/>
</apps>
</javaScriptServices>
</sitecore>
</configuration>
In the /App_Config/Sitecore/JavaScriptServices/Sitecore.JavaScriptServices.Apps.config file, in the defaults configuration patch, you can inspect any default values for some of the available attributes. Additional information may be found here.
Changes in Presentation details
Since Sitecore Layout Service returns JSON instead of HTML in headless approach there are some changes to presentation details were made.
Renderings - it’s not possible to use familiar MVC (Controller rendering, View rendering) renderings with headless sites. For this purposes, new renderings template was introduced - JSON rendering. You may specify familiar “Datasource Template” and “Datasource Location” fields as before, but the most important information now is Name - it’s needed to associate rendering with the view on Rendering Host side. There was a new field added to JSON rendering template as well - “Rendering Contents Resolver”. Since Rendering Host has no direct access to Sitecore items and uses only data returned by Layout Service (see screenshot below with response example), the rendering’s datasource is the only way to get data to display at View. “Rendering Contents Resolver” allows to choose what data will be passed. Default is the datasource item fields only, but there are couple of resolvers out of the box available, so you can pass child items data, or item with childrens, for example. You can create your own resolvers to fit your needs.
{
"uid": "8654d7f9-6df3-4d32-835a-92d4d65efc",
"componentName": "DataSourceExample",
"dataSource": "{3BC54537-E31D-4C9B-A230-088F92F3A0EF}",
"params": {},
"fields": {
"BodyText": {
"value": "Default"
},
"FeaturedImage": {
"value": {}
},
"Title": {
"value": "Default"
},
"PromoLink": {
"value": {
"href": "/en/",
"text": "",
"anchor": "",
"linktype": "internal",
"class": "",
"title": "",
"querystring": "",
"id": "{453C1A-7E24-4F2F-8069-84165C6130A3}"
}
},
"ExampleDate": {
"value": "2020-08-07T04:00:00Z"
}
}
}
There are changes in Layouts as well. New layout template (/sitecore/templates/Foundation/JavaScript Services/JSS Layout) was introduced. You can create as many as you need, but have to inherit them from this base one. There are no unique path to layout views as before - standard value “/Views/JssApp.cshtml” will be used in most cases - and appropriate view may be chosen at Rendering Host’s side based on layout ID. There is “Layout Service Placeholders” field added as well. It contains list of placeholders that will be passed from Layout Service to Rendering Host, so all placeholders that you may have on this layout have to be chosen here.