Query examples for the Delivery API

This topic describes some examples of how to query the Experience Edge GraphQL schema to meet common query needs.

Important

Most of the example queries in this topic are derived from Sitecore JSS styleguide sample apps. Item IDs and paths will vary by import/solution.

Important

If your site supports a fallback language, enable publishing language fallback on the Experience Edge Connector before you start.

Get an item by ID or path

You can query items anywhere in your content tree by path or ID to read their fields and other properties. You can use inline fragments to cast items to their projected data template type and fields to their field type.

Query

RequestResponse
query {
  # path can be an item tree path or GUID-based id
  item(path: "/sitecore/content/Experience-Edge/home", language: "en") {
    # items can be cast to a Template type with inline fragments
    ... on AppRoute {
      pageTitle {
        value
      }
    }
    # fields can be cast to a Field type with inline fragments
    field(name: "pageTitle") {
      ... on TextField {
        value
      }
    }
  }
}

Result

RequestResponse
{
  "data": {
    "item": {
      "pageTitle": {
        "value": "Welcome to Sitecore JSS"
      },
      "field": {
        "value": "Welcome to Sitecore JSS"
      }
    }
  }
}

Get items filtered by multiple paths

You can filter items based on multiple paths. This query example assumes the following site structure:

Content tree highlighting the items used in this example.

Assume that the /home/graphql and home/styleguide/Page Components items have the UUIDs 0C6F4AAF-DD7E-5FAF-B9B0-61070D496055 and AB99BA2B-B606-51E3-BAD9-FD8358DE1333, respectively. You want to get the /home items and descendants that are not /home/graphql and home/styleguide/Page Components or their children. The following query uses the NCONTAINS operator to exclude the path of these items and their children from the result.

Query

RequestResponse
query {
  pageOne: search(
     where: {
       AND: [
         {
           name: "_path"
           value: "54C8E9B5-0B2C-5363-8FA6-D32A3A302F51"
           operator: CONTAINS
         }
         {
           AND: [
             {
               name: "_path"
               value: "0C6F4AAF-DD7E-5FAF-B9B0-61070D496055"
               operator: NCONTAINS
             }
             {
               name: "_path"
               value: "AB99BA2B-B606-51E3-BAD9-FD8358DE1333"
               operator: NCONTAINS
             }
           ]
         }
       ]
     }
     # defaults to 10
     first: 10
   ) {
     total
     pageInfo {
       endCursor
       hasNext
     }
     results {
       url {
         path
       }
     }
   }
 }

Result

The search query result does not contain items with the paths /home/graphql and home/styleguide/Page Components or any of their descendants but returns the /home item and the remaining child items.

RequestResponse
{
  "data": {
    "pageOne": {
      "total": 5,
      "pageInfo": {
        "endCursor": "NQ==",
        "hasNext": false
      },
      "results": [
        {
          "url": {
            "path": "/styleguide/custom-route-type"
          }
        },
        {
          "url": {
            "path": "/styleguide"
          }
        },
        {
          "url": {
            "path": "/Page-Components/home-jss-main-ContentBlock-1"
          }
        },
        {
          "url": {
            "path": "/Page-Components"
          }
        },
        {
          "url": {
            "path": "/"
          }
        }
      ]
    }
  }
}

Get item layout for a URL

Most often used with Headless SDKs, you can find items by their site name and HTTP URL and then obtain their Layout Service output for rendering by framework-specific Sitecore placeholder implementations.

Query

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

Result

RequestResponse
{
  "data": {
    "layout": {
      "item": {
        "rendered": {
          "sitecore": {
            "context": {
              "pageEditing": false,
              "site": {
                "name": "experienceedge"
              },
              "pageState": "normal",
              "language": "en",
              "itemPath": "/"
            },
            "route": {
              "name": "home",
              "displayName": "home",
              "fields": {
                "pageTitle": {
                  "value": "Welcome to Sitecore JSS"
                }
              },
              "deviceId": "fe5d7fdf-89c0-4d99-9aa3-b5fbd009c9f3",
              "itemId": "2bde2083-5542-5569-ac5e-f1f42e29f75a",
              "itemLanguage": "en",
              "itemVersion": 1,
              "layoutId": "714096fc-3998-52cf-b87a-951fc7ce39d3",
              "templateId": "e34d8c4f-7e6c-560c-be24-e4d1fcdb16d8",
              "templateName": "AppRoute",
              "placeholders": {
                "jss-main": [
                  {
                    "uid": "2c4a53cc-9da8-5f51-9d79-6ee2fc671b2d",
                    "componentName": "ContentBlock",
                    "dataSource": "{CC3A044C-776B-5423-9BEA-CC5C2EDA8C9B}",
                    "fields": {
                      "heading": {
                        "value": "Welcome to Sitecore JSS"
                      },
                      "content": {
                        "value": "<p>Thanks for using JSS!! Here are some resources to get you started:</p>\n\n<h3><a href=\"https://jss.sitecore.net\" rel=\"noopener noreferrer\">Documentation</a></h3>\n<p>The official JSS documentation can help you with any JSS task from getting started to advanced techniques.</p>\n\n<h3><a href=\"/styleguide\">Styleguide</a></h3>\n<p>The JSS styleguide is a living example of how to use JSS, hosted right in this app.\nIt demonstrates most of the common patterns that JSS implementations may need to use,\nas well as useful architectural patterns.</p>\n\n<h3><a href=\"/graphql\">GraphQL</a></h3>\n<p>JSS features integration with the Sitecore GraphQL API to enable fetching non-route data from Sitecore - or from other internal backends as an API aggregator or proxy.\nThis route is a living example of how to use an integrate with GraphQL data in a JSS app.</p>\n\n<div class=\"alert alert-dark\">\n  <h4>This app is a boilerplate</h4>\n  <p>The JSS samples are a boilerplate, not a library. That means that any code in this app is meant for you to own and customize to your own requirements.</p>\n  <p>Want to change the lint settings? Do it. Want to read manifest data from a MongoDB database? Go for it. This app is yours.</p>\n</div>\n\n<div class=\"alert alert-dark\">\n  <h4>How to start with an empty app</h4>\n  <p>To remove all of the default sample content (the Styleguide and GraphQL routes) and start out with an empty JSS app:</p>\n  <ol>\n    <li>Delete <code>/src/components/Styleguide*</code> and <code>/src/components/GraphQL*</code></li>\n    <li>Delete <code>/sitecore/definitions/components/Styleguide*</code>, <code>/sitecore/definitions/templates/Styleguide*</code>, and <code>/sitecore/definitions/components/GraphQL*</code></li>\n    <li>Delete <code>/data/component-content/Styleguide</code></li>\n    <li>Delete <code>/data/content/Styleguide</code></li>\n    <li>Delete <code>/data/routes/styleguide</code> and <code>/data/routes/graphql</code></li>\n    <li>Delete <code>/data/dictionary/*.yml</code></li>\n  </ol>\n</div>\n"
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      }
    }
  }
}

Paginate items in an item bucket

When you work with Sitecore item buckets, a common requirement is to paginate all the items that descend from a particular template within that bucket. The following search query is helpful for these use cases.

Query

RequestResponse
fragment bucketItemFields on Item {
  ... on AppRoute {
    pageTitle {
      value
    }
  }
  url {
    path
  }
}

query {
  search(
    where: {
      AND: [
        {
          name: "_templates"
          value: "0929f436c3f3500a9f8bd1c57a67a192"
          operator: CONTAINS
        }
        {
          name: "_path"
          value: "7ab00eca411249818420666fc9110faf"
          operator: CONTAINS
        }
      ]
    }
    first: 5
    orderBy: { name: "pageTitle", direction: ASC }
  ) {
    results {
      ...bucketItemFields
    }
    pageInfo {
      endCursor
      hasNext
    }
    total
  }
}

Result

RequestResponse
{
  "data": {
    "search": {
      "results": [
        {
          "pageTitle": {
            "value": "Route A"
          },
          "url": {
            "path": "/bucket/2021/05/13/13/12/Route-A"
          }
        },
        {
          "pageTitle": {
            "value": "Route B"
          },
          "url": {
            "path": "/bucket/2021/05/13/13/12/Route-B"
          }
        },
        {
          "pageTitle": {
            "value": "Route C"
          },
          "url": {
            "path": "/bucket/2021/05/13/13/12/Route-C"
          }
        },
        {
          "pageTitle": {
            "value": "Route D"
          },
          "url": {
            "path": "/bucket/2021/05/13/13/12/Route-D"
          }
        },
        {
          "pageTitle": {
            "value": "Route E"
          },
          "url": {
            "path": "/bucket/2021/05/13/13/13/Route-E"
          }
        }
      ],
      "pageInfo": {
        "endCursor": "NQ==",
        "hasNext": true
      },
      "total": 26
    }
  }
}

Get the root item of a site

The Experience Edge schema does not currently allow querying of sites and their root items, but you can still find the root item of a site by using the layout query.

Query

RequestResponse
query {
  layout(site: "experienceedge", routePath: "/", language: "en") {
    item {
      homeItemPath: path
      contentRoot: parent {
        id
        path
      }
    }
  }
}

Result

RequestResponse
{
  "data": {
    "layout": {
      "item": {
        "homeItemPath": "/sitecore/content/Experience-Edge/home",
        "contentRoot": {
          "id": "5AAA894246145088B7AD604B4D177B39",
          "path": "/sitecore/content/Experience-Edge"
        }
      }
    }
  }
}

Get all site paths/pages

You can use the site query to find all the items in a specific language with layout data/presentation details on that site. This is useful, for example, for obtaining paths for a static site generator. The route results are paginated and, by default, return only 10 results. You must use the endCursor property with the first and after query arguments to paginate the results.

Query

RequestResponse
query {
 site {
  siteInfo(site: "example") {
   routes(language: "en") {
    results {
     route{
      id
     }
     routePath
    }
    total
    pageInfo {
     endCursor
     hasNext
    }
   }
  }
 }
}

Result

RequestResponse
{
 "data": {
  "site": {
   "siteInfo": {
    "routes": {
     "routesResult": [
      {
       "route": {
        "id": "31FB4D08F5E14B4C9AA4EFE8F486B87D"
       },
       "routePath": "/Page-B"
      },
      {
       "route": {
        "id": "49195BCAB09241A3BC30311F00B7DDC8"
       },
       "routePath": "/Page-A"
      },
      {
       "route": {
        "id": "BCDA1741BF0D4CA695519FEAE634FFFF"
       },
       "routePath": "/"
      }
     ],
     "total": 3,
     "pageInfo": {
      "endCursor": "Mw==",
      "hasNext": false
     }
    }
   }
  }
 }
}

Get items filtered by dates and numbers within a range

You can use operators to query for numbers and dates, such as:

  • Equals (EQ)

  • Not equal (NEQ)

  • Contains (CONTAINS)

  • Doesn't contain (NCONTAINS)

In addition, you can use the following operators to query a range of numbers or dates:

  • Less than (LT)

  • Less than or equals (LTE)

  • Greater than (GT)

  • Greater than or equals (GTE)

When you use these operators, the value needs to be wrapped in quotation marks. The date comparison supports all standard date/time formats, as well as yyyyMMddTHHmmssZ. Dates are stored in UTC format. However, the values entered in the query are assumed to be local ones.

Important

Before using this feature for the first time, republish the content you want to query, to rebuild the internal data structure. Otherwise, the data will be compared lexicographically, as strings. For example, if the data isn't rebuilt, a value of 3 is considered greater than 123.

Query - date range

RequestResponse
query {
  search(
    where: {
      AND: [
        { name: "birthdate" operator: LT value: "2024-01-01"}
        { name: "birthdate" operator: GT value: "1950-01-01"}
      ]
    }
  ) {
    results {
      name
      BirthDate: field(name: "birthdate") {
        value
      }
    }
  }
}

Result - date range

RequestResponse
query {
  search(
    where: {
      AND: [
        { name: "count" operator: LTE value: "300.0" }
        { name: "count" operator: GTE value: "71" }
      ]
    }
  ) {
    results {
      name
      Count: field(name: "count") {
        value
      }
    }
  }
}

Query - number range

RequestResponse
query {
  search(
    where: {
      AND: [
        { name: "count" operator: LTE value: "300.0" }
        { name: "count" operator: GTE value: "71" }
      ]
    }
  ) {
    results {
      name
      Count: field(name: "count") {
        value
      }
    }
  }
}

Result - number range

RequestResponse
{
  "data": {
    "search": {
      "results": [
        {
          "name": "3",
          "Count": {
            "value": "71"
          }
        },
        {
          "name": "2",
          "Count": {
            "value": "300"
          }
        },
        {
          "name": "1",
          "Count": {
            "value": "100"
          }
        }
      ]
    }
  }
}

Build site navigation

This sample query combines finding the site root with the ability to traverse item children. You can use the hasLayout argument to find only items with layout (navigable pages) and the includeTemplateIds argument to filter on a (base) data template.

Query

RequestResponse
fragment navigationFields on Item {
  ... on AppRoute {
    pageTitle {
      value
    }
  }
  url {
    path
  }
}

query {
  layout(site: "experienceedge", routePath: "/", language: "en") {
    item {
      ...navigationFields
      children(hasLayout: true, includeTemplateIDs: "e34d8c4f7e6c560cbe24e4d1fcdb16d8") {
        results {
          ...navigationFields
          children(hasLayout: true, includeTemplateIDs: "e34d8c4f7e6c560cbe24e4d1fcdb16d8") {
            results {
            	...navigationFields
            }
          }
        }
      }
    }
  }
}

Result

RequestResponse
{
  "data": {
    "layout": {
      "item": {
        "pageTitle": {
          "value": "Welcome to Sitecore JSS"
        },
        "url": {
          "path": "/"
        },
        "children": {
          "results": [
            {
              "pageTitle": {
                "value": "GraphQL | Sitecore JSS"
              },
              "url": {
                "path": "/graphql"
              },
              "children": {
                "results": [
                  {
                    "pageTitle": {
                      "value": "Sample 1 Page Title"
                    },
                    "url": {
                      "path": "/graphql/sample-1"
                    }
                  },
                  {
                    "pageTitle": {
                      "value": "Sample 2 Page Title"
                    },
                    "url": {
                      "path": "/graphql/sample-2"
                    }
                  }
                ]
              }
            },
            {
              "pageTitle": {
                "value": "Styleguide | Sitecore JSS"
              },
              "url": {
                "path": "/styleguide"
              },
              "children": {
                "results": [
                  {
                    "pageTitle": {
                      "value": "Custom Route Type | Sitecore JSS"
                    },
                    "url": {
                      "path": "/styleguide/custom-route-type"
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
  }
}

Build a page breadcrumb

You can use the ancestors field on the item graph type to create breadcrumb navigation. Use the hasLayout argument to find only items with layout (navigable pages), and includeTemplateIds to filter on a (base) data template.

Query

RequestResponse
fragment breadcrumbFields on Item {
  ... on AppRoute {
    pageTitle {
      value
    }
  }
  url {
    path
  }
}

query {
  # Assume the item id is available on the page
  item(path: "e2c5c62f42a95b17bc0e71bc9193db9a", language: "en") {
    ...breadcrumbFields
    ancestors(
      hasLayout: true
      includeTemplateIDs: "e34d8c4f7e6c560cbe24e4d1fcdb16d8"
    ) {
      ...breadcrumbFields
    }
  }
}

Result

RequestResponse
{
  "data": {
    "item": {
      "pageTitle": {
        "value": "Custom Route Type | Sitecore JSS"
      },
      "url": {
        "path": "/styleguide/custom-route-type"
      },
      "ancestors": [
        {
          "pageTitle": {
            "value": "Styleguide | Sitecore JSS"
          },
          "url": {
            "path": "/styleguide"
          }
        },
        {
          "pageTitle": {
            "value": "Welcome to Sitecore JSS"
          },
          "url": {
            "path": "/"
          }
        }
      ]
    }
  }
}

Use item fields with Sitecore Headless SDKs

The various Sitecore Headless SDKs all contain helpers for rendering field values. These helpers assist with rendering complex fields (such as images or links) and editable values in the context of inline editing. Item fields in the Experience Edge schema include jsonValue that outputs the field in a format compatible with these field helpers.

For example, the following link field could be rendered in React or Next.js using the Link field helper:

RequestResponse
<Link field={data.linkFieldExample?.externalLink?.jsonValue} />

Query

RequestResponse
query {
  richTextFieldExample: item(path: "d979794f76fd51829f3ece48d16dc36c", language: "en") {
    displayName
    ... on StyleguideFieldUsageRichText {
      sample {
        jsonValue
      }
    }
  }
  imageFieldExample: item(path: "c05be0b464885343b5670145b6815d03", language: "en") {
    displayName
    ... on StyleguideFieldUsageImage {dic
      sample1 {
        jsonValue
      }
    }
  }
  linkFieldExample: item(path: "d299e65e1f6c5ea3b71381c8e2f85baf", language: "en") {
    displayName
    ... on StyleguideFieldUsageLink {
      externalLink {
        jsonValue
      }
    }
  }
}

Result

RequestResponse
{
  "data": {
    "richTextFieldExample": {
      "displayName": "Styleguide-FieldUsage-RichText-3",
      "sample": {
        "jsonValue": {
          "value": "<p>This is a sample rich text field. <mark>HTML is always supported.</mark> In Sitecore, editors will see a WYSIWYG editor for these fields.</p>"
        }
      }
    },
    "imageFieldExample": {
      "displayName": "Styleguide-FieldUsage-Image-4",
      "sample1": {
        "jsonValue": {
          "value": {
            "src": "https://cm.experience_edge.localhost/-/media/experienceedge/data/media/img/sc_logo.png?iar=0&hash=F4F969FF95009AE0A80FA094C497ED25",
            "alt": "Sitecore Logo"
          }
        }
      }
    },
    "linkFieldExample": {
      "displayName": "Styleguide-FieldUsage-Link-9",
      "externalLink": {
        "jsonValue": {
          "value": {
            "href": "https://www.sitecore.com",
            "text": "Link to Sitecore",
            "url": "https://www.sitecore.com",
            "linktype": "external"
          }
        }
      }
    }
  }
}

Get information about all content sites

You can fetch information about all the content sites in a site query using the siteInfoCollection field. For example, to get the name and root path of all the available sites, use the following query:

Query

RequestResponse
query {
 site {
  siteInfoCollection{
   name
   rootPath
  }
 }
}

Result

RequestResponse
{
 "data": {
  "site": {
   "siteInfoCollection": [
    {
     "name": "example",
     "rootPath": "/sitecore/content/sxa/example"
    },
    {
     "name": "website",
     "rootPath": "/sitecore/content"
    }
   ]
  }
 }
}

Get information about a specific content site

You can use the siteInfo field in a site query to get information about a specific content site. For example, the following query returns the site name and root path.

Query

RequestResponse
query {
 site {
  siteInfo(site: example”) {
   name
   rootPath
  }
 }
}

Result

RequestResponse
{
 "data": {
  "site": {
   "siteInfo": {
    "name": "example",
    "rootPath": "/sitecore/content/sxa/example"
   }
  }
 }
}

List redirect rules

When querying for information about a specific site, you can request a list of redirect rules. In the following example query, the response includes the redirect type, target, pattern, and whether the redirection preserves any query string parameters.

Query

RequestResponse
query {
 site {
  siteInfo(site: example”) {
   name
   rootPath
   redirects {
    redirectType
    isQueryStringPreserved
    target
    pattern
   }
  }
 }
}

Result

RequestResponse
{
 "data": {
  "site": {
   "siteInfo": {
    "name": "example",
    "rootPath": "/sitecore/content/sxa/example",
    "redirects": [
     {
       "redirectType": "REDIRECT_302",
      "isQueryStringPreserved": true,
      "target": "/page C",
      "pattern": "/page b/"
     }
    ]
   }
  }
 }
}

Get error-handling pages

When querying for information about a specific site, you can request information on all the pages involved in the error-handling process. The result can help you determine if all the required error codes are handled and by which pages.

Query

RequestResponse
query {
 site {
  siteInfo(site: example”) {
  	errorHandling(language: en”) {
    notFoundPage {
     id
     path
     field (name: "Title") {
      name
      value
     }
    },
    notFoundPagePath,
    serverErrorPage {
     id
     name
     path
     field (name: "Title") {
      name
      value
     }
    },
   serverErrorPagePath
   }
  }
 }
}

Result

RequestResponse
{
 "data": {
  "site": {
   "siteInfo": {
    "errorHandling": {
     "notFoundPage": {
      "id": "7AC72838792444A389BDD10D63A30FA6",
      "path": "/sitecore/content/sxa/example/Home/custom-404-error-page",
      "field": {
       "name": "Title",
       "value": "custom-404-error-page"
      }
     },
     "notFoundPagePath": "/custom-404-error-page",
     "serverErrorPage": {
      "id": "846C9D39299740D0A25235ECA3F5B202",
      "name": "custom-500-error-page",
      "path": "/sitecore/content/sxa/example/Home/custom-500-error-page",
      "field": {
       "name": "Title",
       "value": "custom-500-error-page"
      }
     },
     "serverErrorPagePath": "/custom-500-error-page"
    }
   }
  }
 }
}

Get robot information

You can request information about which search engine crawlers can access the site using a site query.

Query

RequestResponse
query {
 site {
  siteInfo(site: example”) {
   robots
  }
 }
}

Result

RequestResponse
{
 "data": {
  "site": {
   "siteInfo": {
    "robots": "google, bing\r\nSitemap: https://xmcloudcm.localhost/sitemap.xml\r\n"
   }
  }
 }
}

Get the sitemap of an SXA site

You can query for the path to the media items generated for an SXA site sitemap.

Query

RequestResponse
query {
 site {
  siteInfo(site: example”) {
   sitemap
  }
 }
}

Result

RequestResponse
{
 "data": {
  "site": {
   "siteInfo": {
    "sitemap": " /-/media/Project/sxa/example/Sitemaps/sitemap.xml"
   }
  }
 }
}

Get dictionary entries

You can retrieve individual dictionary entries for a site by using the site query. You can combine cursor arguments to apply paging to the results. If those aren't provided, the default is a first page size of 500.

Query

RequestResponse
query  {
  site {
    siteInfo(site: "example") {
      name
      dictionary(language:"en",first:2, after:"eyJzZWFyY2hBZnRlciI6WyJrZXkyIiwiZGVtb3NpdGUtMzVjZDg5NjJjNzE4NDI4Nzk2YzBmYTU2YmY2ZjRmMjIta2V5Mi11ay11YSJdLCJjb3VudCI6Mn0=")
      {
        total
        pageInfo{
          hasNext
          endCursor
        }
        results
        {
          key
          value
        }
      }
    }
  }
}

Result

RequestResponse
  "data": {
    "site": {
      "siteInfo": {
        "name": "example",
        "dictionary": {
          "total": 2,
          "pageInfo": {
            "hasNext": false,
            "endCursor": "eyJzZWFyY2hBZnRlciI6WyJ0ZXN0MiIsIm5ldyBzaXRlLWU1MmU1ZjBiZmMxMzQ0Mzc5YWQ4YzcyMjY2NzIzZmI0LXRlc3QyLWVuIl0sImNvdW50IjoyfQ=="
          },
          "results": [
            {
              "key": "key1",
              "value": "value1"
            },
            {
              "key": "key2",
              "value": "value2"
            }
          ]
        }
      }
    }
  }
}

Do you have some feedback for us?

If you have suggestions for improving this article,