All Articles

Sitecore JSS with Next.js - Rendering Contents Resolver

In this article, I will explain what a Rendering Contents Resolver is, and how to use the OOTB Rendering Contents Resolvers in a Sitecore JSS with Next.js solution.

What is a Rendering Contents Resolver?

In my previous article Sitecore JSS with Next.js - Creating your first component, we created a component that used the data from the datasource item to render itself. This is the default behavior for a component, the data that is passed to the component by the layout service will be the datasource itself.

However, we come across different requirements for different components. For example:

  • Data of the context item.
  • Data of the Children items.
  • Data from other items.

We can also use the GraphQL API to perform a query and obtain the data needed for our component. However, Sitecore offers an OOTB solution with the possibility to extend, Rendering Contents Resolvers.

You can find the Rendering Contents Resolvers in the path /sitecore/system/Modules/Layout Service/Rendering Contents Resolvers.

The resolvers that Sitecore offers OOTB are as follows:

  • Datasource Resolver - the default behavior. It serializes the rendering’s datasource item.
  • Datasource Item Children Resolver - serializes the children of the datasource item.
  • Context Item Resolver - serializes the context item instead of the datasource item.
  • Context Item Children Resolver - serializes the children of the context item.
  • Folder Filter Resolver - serializes the descendants of the datasource item, excluding folders.

Example Component

Here is an example, where we will need to modify the rendering content resolver and use the values in the component.

I have a component called Card List, in which I need to render all the Card items under the Card List. Each card has an image, a heading, a description, and a link.

  1. Create a component named CardListComponent by following the steps mentioned in my previous article.

  2. Add the component created to your page, I will be adding it to a page called demo in my example. Also, add and configure the datasources with some appropriate values.

  3. Go to the rendering item of the component in Sitecore and change the value for the field - Rendering Content Resolver, to Datasource Item Children Resolver. Perform a Publish to clear the layout service cache.

    Datasource Item Children Resolver

  4. Now, go to the GraphQL Playground and perform a layout query on your page.

    query {
      layout(site: "JSSProject", routePath: "/demo", language: "en") {
        item {
          rendered
        }
      }
    }

    The output of the query should be similar to the value below:

    {
      "data": {
        "layout": {
          "item": {
            "rendered": {
              "sitecore": {
                "context": {
                  "pageEditing": false,
                  "site": {
                    "name": "jssproject"
                  },
                  "pageState": "normal",
                  "language": "en",
                  "itemPath": "/demo"
                },
                "route": {
                  "name": "demo",
                  "displayName": "demo",
                  "fields": {
                    "pageTitle": {
                      "value": ""
                    }
                  },
                  "databaseName": "web",
                  "deviceId": "fe5d7fdf-89c0-4d99-9aa3-b5fbd009c9f3",
                  "itemId": "1a4a3d34-df6a-463f-8b72-58cc56ecc0d4",
                  "itemLanguage": "en",
                  "itemVersion": 1,
                  "layoutId": "aec6b942-174e-581c-a1a0-50aa51432a66",
                  "templateId": "74e5c244-4fb5-5ae9-bb19-0899d55bf312",
                  "templateName": "App Route",
                  "placeholders": {
                    "jss-main": [
                      {
                        "uid": "a52a4929-2ac1-4e8a-9a16-1372465c3ac0",
                        "componentName": "CardListComponent",
                        "dataSource": "{6539F816-642F-4B48-B5F7-658ABFE4B676}",
                        "params": {},
                        "fields": {
                          "items": [
                            {
                              "id": "8a43ce24-7ba2-4953-8392-8517b0ad5f32",
                              "url": "/demo/Page-Components/CardListComponent/Card-1",
                              "name": "Card 1",
                              "displayName": "Card 1",
                              "fields": {
                                "title": {
                                  "value": "GraphQL"
                                },
                                "description": {
                                  "value": "GraphQL"
                                },
                                "link": {
                                  "value": {
                                    "href": "/en/graphql",
                                    "text": "",
                                    "anchor": "",
                                    "linktype": "internal",
                                    "class": "",
                                    "title": "",
                                    "target": "",
                                    "querystring": "",
                                    "id": "{E507735E-CF6D-57C1-8B02-704027972952}"
                                  }
                                },
                                "image": {
                                  "value": {
                                    "src": "https://cm.jssproject.localhost/-/media/System/Email/Placeholders/image300x200.jpg?h=200&iar=0&w=300&hash=2D743D7A0F958598889BE6E80062B606",
                                    "alt": "Placeholder image",
                                    "width": "300",
                                    "height": "200"
                                  }
                                }
                              }
                            },
                            {
                              "id": "05917a7f-0b00-4234-91d7-1faf45d5d7c0",
                              "url": "/demo/Page-Components/CardListComponent/Card-2",
                              "name": "Card 2",
                              "displayName": "Card 2",
                              "fields": {
                                "title": {
                                  "value": "Styleguide"
                                },
                                "description": {
                                  "value": "Styleguide"
                                },
                                "link": {
                                  "value": {
                                    "href": "/en/styleguide",
                                    "text": "",
                                    "anchor": "",
                                    "linktype": "internal",
                                    "class": "",
                                    "title": "",
                                    "target": "",
                                    "querystring": "",
                                    "id": "{5F92EEFB-A658-56BA-98B3-0C0B1E6420E2}"
                                  }
                                },
                                "image": {
                                  "value": {
                                    "src": "https://cm.jssproject.localhost/-/media/System/Email/Placeholders/image300x200.jpg?h=200&iar=0&w=300&hash=2D743D7A0F958598889BE6E80062B606",
                                    "alt": "Placeholder image",
                                    "width": "300",
                                    "height": "200"
                                  }
                                }
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        }
      }
    }
  5. Now, we will modify the component definition in the code to match our requirements.

    import {
      Text,
      Field,
      withDatasourceCheck,
      LinkField,
      ImageField,
      Link,
      Image,
    } from '@sitecore-jss/sitecore-jss-nextjs';
    import { ComponentProps } from 'lib/component-props';
    
    type CardProps = {
      id: string;
      fields: {
        title: Field<string>;
        description: Field<string>;
        link: LinkField;
        image: ImageField;
      };
    };
    type CardListComponentProps = ComponentProps & {
      fields: {
        items: CardProps[];
      };
    };
    
    const CardListComponent = ({ fields }: CardListComponentProps): JSX.Element => (
      <div className="container">
        <div className="sc-cards">{fields?.items?.map((card) => card && <Card {...card} />)}</div>
      </div>
    );
    
    const Card = ({ fields, id }: CardProps): JSX.Element => (
      <div className="sc-card" key={id}>
        <Text field={fields.title} tag="h3" className='h3'/>
        <Text field={fields.description} tag="p" />
        <Link field={fields.link} className="link-field">
          <Image field={fields.image} />
        </Link>
      </div>
    );
    
    export default withDatasourceCheck()<CardListComponentProps>(CardListComponent);
  6. Once you save your changes in the code, your component should render successfully in your rendering host.

    Cards Listing Component

References

  1. Sitecore Documentation - Customizing the Layout Service rendering output

Happy Sitecoring!

Published Jun 6, 2023

Sitecore MVP Technology 2024-23. Web Developer with rich experience in Sitecore and ASP.NET MVC.