0

The out of the box Sitecore layout service api seems to follow the format /sitecore/api/layout/render/<app>. If I wanted to use a url of the like of /api/layout-service, is it possible to achieve this? Possibly through config updates alone?

1
  • Which version of JSS and which front end framework are you using? Is there a specific reason why you want to do this? Oct 12, 2023 at 20:25

2 Answers 2

0

The big question is why you would want to do this; however, I can provide an example in which you might want to. In the past, I did this not to modify the original path, but to add another easier way to get layout service responses during development / testing (ex. /api/pages/path/to/page). I am not currently aware of a way to update this via config alone (haven't looked).

This post may be of assistance to you: NextJS: Short URL for Viewing Layout Service Response. In essence, you capture a request for the arbitrary path you want to support, and in the back end, you simply return the fetch result of the default /sitecore/api/layout/render.

Note that any custom modification / addition of different layout service endpoints can be a security vulnerability. Depending on how you do it and what your architecture is, be mindful of security implications. For example, in Next.JS, adding custom code under your /pages directory can expose raw layout service responses, which can be problematic in production environments.

0

Maybe this blogpost can help? https://gary.wenneker.org/sitecore-jss-using-a-custom-layout-service-configuration/

This is the markdown version of that blog:

Sitecore JSS: Using a custom Layout Service configuration

It's easy to change the output of the JSS Layout Service. You can either choose to use the out of the box Content Resolvers or build your own one as I have shown in my post Sitecore JSS: Extending the Layout Service. The outcome is that you need to define a Content Resolver and point it to your assembly and having your rendering making use of it. So far so good. But what if you have multiple renderings? Then you need to change them all to make them use your resolver. This creates the need of a global Layout Service Configuration!

Creating the configuration patch

The first thing you learn when you want to use the connected my is testing the configuration. This is done by accessing the endpoint /sitecore/api/layout/render/jss?item=/.

enter image description here

And we get the expected result from the Layout Service

Now I want to get the endpoint to use my Content Resolver for every rendering on my site. You need to do the following things:

  • Create a configuration patch file
  • Test the Layout Service configuration
  • Configure the app and client end point

JSS Configuration Patch file

The structure of the Layout Service is easy to explain. You need to set it up under /sitecore/layoutService/configurations/config. The configuration has two elements:

  1. rendering - element holds the configuration for the placeholdersResolver, itemSerializer and the renderingContentsResolver. Tampering with the configuration of the two first ones will result in unwanted behaviour or even can break the JSS SDK. The renderingContentsResolver is the one I want to configure because I want to change the way the fields of my components are outputted. Because only data under the fields property has changed the structure stays intact and the SDK will not break.
  2. serialization - this element has the configuration for the transformer. In my former post I didn't cover this piece of code. What happens here is that you can change the route part of the returned data. For me it was necessary to change the way the fields were returned.

It is a recommendation to use the ref attribute. It then "copies" the existing configuration and only alters the additions you do in your configuration. This way you will have less conflict when upgrading JSS in the future.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
   <layoutService>
    <configurations>
    <config name="macaw">
        <rendering ref="/sitecore/layoutService/configurations/config[@name='jss']/rendering">
            <placeholdersResolver type="Sitecore.LayoutService.Placeholders.DynamicPlaceholdersResolver, Sitecore.LayoutService" />
            <itemSerializer type="Sitecore.JavaScriptServices.ViewEngine.LayoutService.JssItemSerializer, Sitecore.JavaScriptServices.ViewEngine" resolve="true">
              <AlwaysIncludeEmptyFields>true</AlwaysIncludeEmptyFields>
            </itemSerializer>
            <renderingContentsResolver type="Macaw.Sitecore.LayoutService.ItemRendering.ContentsResolvers.CustomRenderingContentsResolver, Macaw.JSS.Examples" resolve="true">
              <IncludeServerUrlInMediaUrls>true</IncludeServerUrlInMediaUrls>
            </renderingContentsResolver>
        </rendering>
        <serialization ref="/sitecore/layoutService/configurations/config[@name='jss']/serialization">
            <transformer type="Macaw.Sitecore.JavaScriptServices.ViewEngine.LayoutService.Serialization.CustomLayoutTransformer, Macaw.JSS.Examples" resolve="true" />
        </serialization>
    </config>
    </configurations>
   </layoutService>
  </sitecore>
</configuration>

Test the Layout Service configuration

But refreshing my endpoint did not give me the right result. Why?

The jss portion of this route refers to a particular configuration of the Layout Service, which is intended for use outside of JSS as well.

Looking at my configuration the name of it is macaw and not jss. This means I don't need to hit the endpoint /sitecore/api/layout/render/jss?item=/ but /sitecore/api/layout/render/macaw?item=/.

enter image description here

Configure the app and client end point

To make sure your app uses the right configuration you must add an extra attribute to your site configuration in your client solution and configure the client API in code. Otherwise it will try to use the jss configuration.

First add the layoutServiceConfiguration attribute and set it to your configuration name:

<app name="demo" layoutServiceConfiguration="macaw" sitecorePath="/sitecore/content/demo" useLanguageSpecificLayout="true" graphQLEndpoint="/api/demo" inherits="defaults" />

By default the service calls are still routed to the endpoint with the jss configuration and it is not done by the action above.

Diving into the server bundle I found out that there is a property called configurationName which is used to define if another configuration is used rather than the default jss one. You could also use the property serviceUrl, but then you need to construct it yourself.

if (options === void 0) { options = {}; }
    var _a = options.host, host = _a === void 0 ? '' : _a, _b = options.configurationName, configurationName = _b === void 0 ? 'jss' : _b, serviceUrl = options.serviceUrl;
    if (serviceUrl) {
        return serviceUrl;
    }
    return host + "/sitecore/api/layout/" + verb + "/" + configurationName;

Now open src/RouteHandler.js and search for the getRouteData function. Change the layoutServiceConfig object. next to the host attribute also add the configurationName attribute with your configuration name (macaw in my case).

function getRouteData(route, language, options = {}) {
  const fetchOptions = {
    layoutServiceConfig: { host: config.sitecoreApiHost, configurationName: 'macaw' },
    querystringParams: { sc_lang: language, sc_apikey: config.sitecoreApiKey },
    requestConfig: options,
  };

  return dataApi.fetchRouteData(route, fetchOptions).catch((error) => {
    console.error('Route data fetch error', error);
    return null;
  });
}

And the result is a connection to your configuration and data on your page!

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.