Sitecore Headless Next.js – Forwarding custom query parameters to Layout Service

A few weeks ago the following question came up by Robbert Hock on Sitecore Chat:

Contents Resolver question: with Context.HttpContext.Request.Params["item"] I can read the url of the item. But when for example we have a url like /news?page=1, how would I read the page querystring prop in a contents resolver? Somehow I can’t find it, since the request is like /sitecore/api/layout/render/default

Robbert Hock

This is a fair question, if you would like to process custom parameters in your custom Contents Resolver.

To support this behavior we need to extend the default RestLayoutService, to pass these custom query parameters to the Layout Service. The nicest way I have found is to inherit from the RestlayoutService and overwrite the getFetchParams.

import { RestLayoutService, RestLayoutServiceConfig } from '@sitecore-jss/sitecore-jss-nextjs';
interface FetchParams {
[param: string]: string | number | boolean;
sc_apikey: string;
sc_site: string;
sc_lang: string;
tracking: boolean;
}
export class ParameterizedRestLayoutService extends RestLayoutService {
constructor(private config: RestLayoutServiceConfig) {
super(config);
}
protected getFetchParams = (language?: string): FetchParams => {
return {
sc_apikey: this.config.apiKey,
sc_site: this.config.siteName,
sc_lang: language || '',
tracking: this.config.tracking ?? true,
custom_parameter: '🩹 lorem ipsum',
};
};
}

The FetchParams interface needs to be copied manually at the moment, because it’s not exported. The original getFetchParams method should be also copied because it can’t be called in the child class, even if it’s protected – I am not a TypeScript expert, but I found that the arrow/lambda functions are not becoming part of the prototype.

Of course this is not enough yet, we need to tell to the Sitecore to use this new ParameterizedRestLayoutService. For that, we need to navigate to the layout-service-factory.ts, and instead of the RestLayoutService, we just need to use the newly created ParameterizedRestLayoutService.

import { LayoutService } from '@sitecore-jss/sitecore-jss-nextjs';
import config from 'temp/config';
import { ParameterizedRestLayoutService } from './parameterized-rest-layout-service';
export class LayoutServiceFactory {
create(): LayoutService {
return new ParameterizedRestLayoutService({
apiHost: config.sitecoreApiHost as string,
apiKey: config.sitecoreApiKey,
siteName: config.jssAppName,
configurationName: 'default',
});
}
}
export const layoutServiceFactory = new LayoutServiceFactory();

Then on the Sitecore side you can retrieve the querystring using the HttpContextBase in your custom Contents Resolver.

public class CustomContentsResolver : RenderingContentsResolver
{
private readonly HttpContextBase _httpContext;
public CustomContentsResolver(HttpContextBase httpContext)
{
_httpContext = httpContext;
}
protected override JObject ProcessItem(Item item, Rendering rendering, IRenderingConfiguration renderingConfig)
{
var querystring = _httpContext.Request.QueryString;
return base.ProcessItem(item, rendering, renderingConfig);
}
}

This way you can forward the parameters from the client side to the Layout Service or you can implement any custom business logic to forward different parameters.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s