Bart Kooijman

Layout Service

Bart Kooijman

Bart Kooijman / 2022-03-10

4 min read

If you haven't already read the documentation this might be the time to do so. To avoid duplicating information and I will only add my learnings in this blog.

Layout Service API

An example of a Layout Service API endpoint:

https://my-app.local/sitecore/api/layout/render/default?item=/sitecore/content/my-app/home&sc_lang=en&sc_apikey={1111111111111-1111-1111-111111111111}

A sample response, which will be injected in your frontend component as props, could be the following:

{
  "sitecore": {
    "context": {
      "pageEditing": false,
      "site": {
        "name": "my-app"
      },
      "pageState": "normal",
      "language": "en",
      "itemPath": "https://my-app.local/"
    },
    "route": {
      "name": "home",
      "displayName": "home",
      "fields": {
        "pageTitle": {
          "value": "Headless Site"
        }
      },
      "databaseName": "web",
      "deviceId": "fe5d7fdf-89c0-4d99-9aa3-b5fbd009c9f3",
      "itemId": "958c925a-d0f0-5d2f-84a0-bc38238965bb",
      "itemLanguage": "en",
      "itemVersion": 1,
      "layoutId": "434e1acc-2256-5a51-98b1-88ebf825e468",
      "templateId": "f9e80209-c9cc-5d15-8558-eb4ccaf852e5",
      "templateName": "App Route",
      "placeholders": {
        "jss-main": [
          {
            "uid": "1fda9055-01b1-4f30-861d-d7009c1cb823",
            "componentName": "Teaser",
            "dataSource": "{B20D95DC-3A00-4D14-985C-18BDA4B84C94}",
            "fields": {
              "Title": {
                "value": "The title of my amazing Teaser"
              },
              "Content": {
                "value": "Teaser content right here!"
              }
            }
          }
        ]
      }
    }
  }
}

In editing mode the field value will return an editable property. This makes sure your field value is inline editable:


"fields": {
  "Title": {
    "value": "The title of my amazing Teaser",
    // editable property only returned in editing mode
    "editable": <input class="editable_css_example">The title of my amazing Teaser</input>
  },
}

Even if you're not a frontend developer it's clear you have all the information available to build the components and page structure.

Modify the Layout Service

In Sitecore MVC you reference a controller in the rendering, hence the name 'Controller Rendering'. In Sitecore Headless you use a rendering with a different template: 'JSON rendering'. In a JSON rendering, you don't reference a controller. You have two options:

  1. Content Resolvers will modify the Layout Service response. At first, you won't see a Content Resolver selected, but underneath the Datasource Content Resolver is used by default. Select a Content Resolver to modify the Layout Service data of the specific rendering. One of the tasks of a Sitecore Developer is to add custom Content Resolvers (.NET) when needed.

  2. Integrated GraphQL will enable you to query content in Sitecore. Out of the box you have access to three variables: $context, $datasource, and $language. Learn here how to add more variables. Based on these variables you query the Sitecore Content Tree. The result of the query will replace the output of the (default) Content Resolver. I will elaborate on GraphQL a lot more in other blog posts.

Be aware, it's not multiple choice! Once you enter a query in the GraphQL field, the Content Resolver choice will be overridden and not used anymore.

Controllers are replaced by Content Resolvers. Content Resolvers are like generic Controllers, reusable in many scenarios

Content Resolver or Integrated GraphQL?

I struggled a lot with these two options, when should I use which? Once you just start developing you get more feeling for the right choice.

In addition to this list, in my opinion, use a custom Content Resolver when:

  • Recurrency. Dealing with an unknown nested structure doesn't fit well with Integrated GraphQL.
  • You have external variables, which are not available in Integrated GraphQL. An option is to use Connected GraphQL with external variables, but you will lose the inline editing experience in Horizon or the Experience Editor. Another option is to extend the GraphQL schema, but be aware, extending GraphQL is not supported if you use the (mirrored) Edge Schema!

In any other scenario use Integrated GraphQL. Let's face it, 80% of all components are just variants of simple content components, Integrated GraphQL will give you enough power to get what you need.

Extend the Layout Service

You can extend the Layout Service Response. For example add properties to the Layout Service API, which you can use in your Connected GraphQL Queries. The documentation is great on this topic. Except for one thing, which costs me a few hours but can save you some time. When using the GraphQL Edge (mirrored) schema, by default (no pun intended) you use the default config instead of the jss config. Be sure to patch the correct config, otherwise, you won't see your changes appear!

Takeaway

The main takeaway is to understand the Layout Service is an API endpoint for requesting context, route and placeholders data. You can modify or extend this response. This opens a lot of possibilities, for example, implementing the concept of the Jamstack. Later on, I will cover this subject as well.

In my upcoming post, we will take a deep dive into GraphQL! Stay tuned.