0

TL;DR

Has anyone been able to use seo-friendly, bucketless urls with the GraphQL Layout Service?

Environment

  • Sitecore 10.2 XM
  • Headless 20
  • NextJS Rendering Host
  • SXA 10.2
  • SPE 6.3

Background

In traditional, MVC-rendered sites, a Sitecore developer has historically been able to eliminate buckets from urls using a combination of a custom link manager and an item resolver that executes within the httpRequestBegin pipeline.

In a headless implementation, the GraphQL Layout Service is the recommended API for retrieving Layout content for a route.

In Sitecore, I have a folder with 1000 routes, each corresponding to an individual Biography. Each item is named after a person. This folder is bucketed by the first letter of the item name.

Folder Structure Example

  • /people
    • /a
    • /b
    • /c
      • /cheeto-bandito

I want to setup my GraphQL query like this:

query () {
  layout(site: "MainSite", routePath: "/people/cheeto-bandito", language: "en") {
    item {
      rendered
    }
  }
}

Expected Result

The Layout Service is able to resolve the item provided in the routePath parameter based on my Custom Item Resolver.

Actual Result

{
    "data": {
        "layout": null
    }
}

The httpRequestBegin does not apply here. I haven't found a pipeline that I can use to influence the ItemResolver process in the Sitecore.Services.GraphQL.EdgeSchema.Queries.LayoutQuery.

My best bet would be to override the IContentService that's registered in the Sitecore.Services.GraphQL.EdgeContent.config file included with Headless 20.

<register serviceType="Sitecore.Services.GraphQL.EdgeSchema.Services.IContentService, Sitecore.Services.GraphQL.EdgeSchema" implementationType="Sitecore.Services.GraphQL.EdgeSchema.Services.ContentService, Sitecore.Services.GraphQL.EdgeSchema" />

So far I haven't had much luck with this. This might be due to the fact that Sitecore doesn't seem to have published a Nuget package for Sitecore.Services.GraphQL.EdgeSchema that's compatible with Sitecore 10.2.

Sitecore.Services.GraphQL.EdgeSchema Nuget Package

Alternatives Explored

If my site was entirely SSG, I could return a friendly url and an internal path as part of the Sitemap Service response. Unfortunately for us, this site is large and we're using SSG and ISR to keep build times to a minimum. This means that not every route is returned by the Sitemap service.

1 Answer 1

0

Sitecore changed the versioning of their package. Try to use 6.0.0 for Sitecore.Services.GraphQL.EdgeSchema. It should correspond to 10.2.

How to change getting context item in Layout service:

  1. Review implementation of Sitecore.LayoutService.Mvc.Controllers.LayoutServiceController It uses Context.Item. You may override it, or you may override the resolving context item for layout service.Or you may override how the context item is resolved.

  2. Layout service resolves context item in mvc.requestBegin pipeline.

<mvc.requestBegin patch:source="Sitecore.Mvc.config">
<processor type="Sitecore.Mvc.Pipelines.Request.RequestBegin.SetupPageContext, Sitecore.Mvc"/>
<processor type="Sitecore.Mvc.Pipelines.Request.RequestBegin.ExecuteFormHandler, Sitecore.Mvc"/>
<processor type="Sitecore.Mvc.Pipelines.Request.RequestBegin.EnsureLoggedInForPreview, Sitecore.Mvc"/>
<processor type="Sitecore.LayoutService.Mvc.Pipelines.RequestBegin.ContextItemResolver, Sitecore.LayoutService.Mvc" resolve="true" patch:source="Sitecore.LayoutService.Mvc.config"/>
</mvc.requestBegin>
  1. Sitecore.LayoutService.Mvc.Pipelines.RequestBegin.ContextItemResolver. It is based on Sitecore.Data.Managers.DefaultItemManager. You may override Sitecore.LayoutService.Mvc.Pipelines.RequestBegin.ContextItemResolver to get custom item resolver.

Review your showconfig.aspx page, you should have

<getLayoutServiceContext>
    <processor type="Sitecore.LayoutService.ItemRendering.Pipelines.GetLayoutServiceContext.PageEditingContext, Sitecore.LayoutService" patch:source="Sitecore.LayoutService.config"/>
    <processor type="Sitecore.LayoutService.ItemRendering.Pipelines.GetLayoutServiceContext.UserContext, Sitecore.LayoutService" patch:source="Sitecore.LayoutService.config"/>
    <processor type="Sitecore.LayoutService.ItemRendering.Pipelines.GetLayoutServiceContext.SiteContext, Sitecore.LayoutService" patch:source="Sitecore.LayoutService.config"/>
    <processor type="Sitecore.LayoutService.ItemRendering.Pipelines.GetLayoutServiceContext.LanguageContext, Sitecore.LayoutService" patch:source="Sitecore.LayoutService.config"/>
    <processor type="Sitecore.LayoutService.ItemRendering.Pipelines.GetLayoutServiceContext.ItemPathContext, Sitecore.LayoutService" resolve="true"/>
</getLayoutServiceContext>

You have ItemPathContext processor, it uses LinkManager internally.

Conclusion: You may override getting context item by writing your own classes and patching configuration. But it looks like Layout Service uses the same logic to get Context Item and to get links to the items. It means that you most probably don't need to change anything here.

1
  • Thanks @Anton! 2 things make your answer hard to implement for me: 1. The GraphQL Edge libraries are all v6.1 in Sitecore 10.2. The nuget package mentioned is only v6.0. 2. The pipelines above would work for the RESTful Layout Service because the parameters are easily interpreted in the HTTP Request. I'm using GraphQL, which requires some additional 'interpretation' to set the item context. When I look at the code under Sitecore.Services.GraphQL.EdgeSchema.Queries.LayoutQuery, this is what's looking up the item: Item obj1 = this._contentService.ResolveItemByPath(str2, rootItem); Aug 16, 2022 at 14:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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