GraphQuery
GraphQuery is an API option that allows you to do selective fetching (to fetch only specific fields) and deep fetching (to fetch fields from linked documents).
The GraphQuery API option lets you make your queries more specific. You can do selective fetching (to retrieve only specific fields) and deep fetching (to retrieve content from linked documents).
Request URLs to the Rest API are limited to 2048 characters. You can reduce your string length by using line breaks with no spaces or tabs, or you can use a white space removal tool.
To learn how to use API options with HTTP or JavaScript, see the Rest API Technical Reference or @prismicio/client Technical Reference.
GraphQuery is not GraphQL
GraphQuery uses a GraphQL-like syntax. However, GraphQuery doesn’t include some GraphQL features such as named queries or introspection.
This example modifies the API response for a blog document. The blog document has a content relationship called author_link, which links to an author document. The query fetches two properties from the author document: author_name and author_image.
- Unencoded
- Encoded
- JavaScript
graphQuery={
blog {
author_link {
...on author {
author_name
author_image
}
}
}
}
graphQuery=%7B%0Ablog%7B%0Aauthor_link%7B%0A...onauthor%7B%0Aauthor_name%0Aauthor_image%0A%7D%0A%7D%0A%7D%0A%7D
{
graphQuery: `
{
blog {
author_link {
...on author {
author_name
author_image
}
}
}
}
`
}
In a Node.js app, that might look like this:
import * as prismic from "@prismicio/client"
const client = prismic.createClient("example-prismic-repo")
async function init() {
const response = await client.getAllByType("blog", {
graphQuery: `{
blog {
author_link {
...on author {
author_name
}
}
}
}`
})
return response
}
init()
The response to that query might look like this:
[
{
uid: 'hello-world',
type: 'blog',
// ...
data: {
author_link: {
type: 'author',
// ...
uid: 'walt-whitman',
data: {
name: 'Walt Whitman',
},
},
},
},
]
GraphQuery uses a syntax that resembles a JavaScript object with no values. Most properties only have a key. The corresponding value is returned on the API.
There are three special properties:
- A set is a property that describes a collection of nested properties.
- A union is a property that conditionally describes a set — such as a Slice or a linked document — and retrieves that value only if it is present.
- A spread fetches all the properties from a set.
A GraphQuery object starts and ends with curly brackets.
The top-level property of the object is a set that represents a custom type.
GraphQuery will only affect documents whose custom type is named in the GraphQuery option. If the GraphQuery object only names a blog_post custom type, documents of the homepage custom type will remain unaffected.
Within the custom type, you canselect fields:
- Unencoded
- Encoded
- JavaScript
graphQuery={
example_custom_type {
example_field_one
}
}
graphQuery=%7B%0Aexample_custom_type%7B%0Aexample_field_one%0A%7D%0A%7D
{
graphQuery: `
{
example_custom_type {
example_field_one
}
}
`
}
All Prismic fields are available as basic properties in GraphQuery. For structured fields like images and rich text, which have nested properties, you can only access the top-level property.
- Unencoded
- Encoded
- JavaScript
graphQuery={
example_custom_type {
example_number_field
example_image_field
}
}
graphQuery=%7B%0Aexample_custom_type%7B%0Aexample_number_field%0Aexample_image_field%0A%7D%0A%7D
{
graphQuery: `
{
example_custom_type {
example_number_field
example_image_field
}
}
`
}
A set is a collection of fields. The following properties are retrieved as sets:
- Documents (identified by the custom type)
- Groups
- Slice arrays
- A Slice’s primary, non-repeat, items, or repeat sections
A set is identified by its API ID followed by curly brackets containing properties.
- Unencoded
- Minified and encoded
- JavaScript
graphQuery={
example_set {
example_number_field
example_group_field {
example_rich_text_field
}
}
}
graphQuery=%7B%0Aexample_set%7B%0Aexample_number_field%0Aexample_group_field%7B%0Aexample_rich_text_field%0A%7D%0A%7D%0A%7D
{
graphQuery: `
{
example_set {
example_number_field
example_group_field {
example_rich_text_field
}
}
}
`
}
A union selects data from an optional set. The following properties can be retrieved with unions:
- Individual slices
- Slice variations
- Linked documents
To create a union, prepend the API ID of the property with ...on.
Here’s an example of a union type to select data from a linked document:
- Unencoded
- Minified and encoded
- JavaScript
graphQuery={
blog_post {
title
author_link {
...on author {
author_name
}
}
}
}
graphQuery=%7B%0Ablog_post%7B%0Atitle%0Aauthor_link%7B%0A...onauthor%7B%0Aauthor_name%0A%7D%0A%7D%0A%7D%0A%7D
{
graphQuery: `
{
blog_post {
title
author_link {
...on author {
author_name
}
}
}
}
`
}
If there are multiple possible custom types linked, specify them as additional properties:
- Unencoded
- Encoded
- JavaScript
graphQuery={
blog_post {
title
author_link {
...on author {
author_name
}
...on guest_author {
author_name
}
}
}
}
graphQuery=%7B%0Ablog_post%7B%0Atitle%0Aauthor_link%7B%0A...onauthor%7B%0Aauthor_name%0A%7D%0A...onguest_author%7B%0Aauthor_name%0A%7D%0A%7D%0A%7D%0A%7D
{
graphQuery: `
{
blog_post {
title
author_link {
...on author {
author_name
}
...on guest_author {
author_name
}
}
}
}
`
}
Here’s an example of a union type to select data from Slices:
- Unencoded
- Minified and encoded
- JavaScript
graphQuery={
example_custom_type {
slices {
... on text_block {
primary {
text
}
}
... on hero_image {
primary {
image
}
}
}
}
}
graphQuery=%7B%0Aexample_custom_type%7B%0Aslices%7B%0A...ontext_block%7B%0Aprimary%7B%0Atext%0A%7D%0A%7D%0A...onhero_image%7B%0Aprimary%7B%0Aimage%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D
{
graphQuery: `
{
example_custom_type {
slices {
... on text_block {
primary {
text
}
}
... on hero_image {
primary {
image
}
}
}
}
}
`
}
Here’s an example of a union type to select data from Slice variations:
- Unencoded
- Minified and encoded
- JavaScript
graphQuery={
example_custom_type {
slices {
... on text_block {
variation {
...on default {
primary {
title
}
items {
description
}
}
...on noTitle {
items {
description
}
}
}
}
}
}
}
graphQuery=%7B%0Aexample_custom_type%7B%0Aslices%7B%0A...ontext_block%7B%0Avariation%7B%0A...ondefault%7B%0Aprimary%7B%0Atitle%0A%7D%0Aitems%7B%0Adescription%0A%7D%0A%7D%0A...onnoTitle%7B%0Aitems%7B%0Adescription%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D
{
graphQuery: `
{
example_custom_type {
slices {
... on text_block {
variation {
...on default {
primary {
title
}
items {
description
}
}
...on noTitle {
items {
description
}
}
}
}
}
}
}
`
}
The spread operator selects all fields in a set. To create a spread, use the API ID for the property and then, inside curly braces, write the API ID of the property prepended with an ... and appended with Fields.
Here’s an example of selecting all fields from a document:
- Unencoded
- Encoded
- JavaScript
graphQuery={
example_custom_type {
...example_custom_typeFields
}
}
graphQuery=%7B%0Aexample_custom_type%7B%0A...example_custom_typeFields%0A%7D%0A%7D
{
graphQuery: `
{
example_custom_type {
...example_custom_typeFields
}
}
`
}
This works for all sets.
The spread operator will not select fields in nested sets, so they must be selected separately:
- Unencoded
- Encoded
- JavaScript
graphQuery={
blog {
...blogFields
author_link {
...on author {
author_name
}
}
}
}
graphQuery=%7B%0Ablog%7B%0A...blogFields%0Aauthor_link%7B%0A...onauthor%7B%0Aauthor_name%0A%7D%0A%7D%0A%7D%0A%7D
{
graphQuery: `
{
blog {
...blogFields
author_link {
...on author {
author_name
}
}
}
}
`
}
If a content relationship field is restricted to a single custom type, you can use a spread instead of a union to fetch all fields from a linked document:
- Unencoded
- Encoded
- JavaScript
graphQuery={
blog {
author_link {
...author_linkFields
}
}
}
graphQuery=%7B%0Ablog%7B%0Aauthor_link%7B%0A...author_linkFields%0A%7D%0A%7D%0A%7D
{
graphQuery: `
{
blog {
author_link {
...author_linkFields
}
}
}
`
}
In Slice Machine the Slice Zone can be found inside slices. The repeatable zone is referenced as items, and the non-repeatable as primary.
In this example, we have a homepage set with one Slice named text_block. We'll retrieve all the repeatable and non-repeatable fields from the default Slice and its noTitle variation.
We write the Slice name after using a union. Then inside variation we define the default Slice and its noTitle variation. Then we name the items or primary zones and then, inside curly braces, write items or primary prepended with a spread and appended with Fields:
Slice Machine Slice sets are slightly different from Slices in the Legacy Builder. It’s important to note these differences as they’re crucial when selecting the fields.
- Unencoded
- Encoded
- JavaScript
graphQuery={
homepage {
slices {
...on text_block {
variation {
...on default {
primary {
...primaryFields
}
items {
...itemsFields
}
}
...on noTitle {
items {
...itemsFields
}
}
}
}
}
}
}
graphQuery=%7B%0Ahomepage%7B%0Aslices%7B%0A...ontext_block%7B%0Avariation%7B%0A...ondefault%7B%0Aprimary%7B%0A...primaryFields%0A%7D%0Aitems%7B%0A...itemsFields%0A%7D%0A%7D%0A...onnoTitle%7B%0Aitems%7B%0A...itemsFields%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D
{
graphQuery: `
{
homepage {
slices {
...on text_block {
variation {
...on default {
primary {
...primaryFields
}
items {
...itemsFields
}
}
...on noTitle {
items {
...itemsFields
}
}
}
}
}
}
}
`
}
In the Legacy Builder, the Slice Zone can be found inside body. The repeatable zone is referenced as repeat, and the non-repeatable as non-repeat.
In this example, we have a homepage set with one Slice named text_block. We'll retrieve all the repeatable and non-repeatable fields from the default Slice and its noTitle variation.
We write the Slice name using a union. Then we call the repeat or non-repeat zones and then, inside curly braces, write repeat or non-repeat prepended with a spread and appended with Fields:
Slice Machine Slice sets are slightly different from Slices in the Legacy Builder. It’s important to note these differences as they’re crucial when selecting the fields.
- Unencoded
- Encoded
- JavaScript
graphQuery={
homepage {
body {
...on text_block {
non-repeat {
...non-repeatFields
}
repeat {
...repeatFields
}
}
...on image_gallery {
non-repeat {
...non-repeatFields
}
repeat {
...repeatFields
}
}
}
}
}
graphQuery=%7B%0Ahomepage%7B%0Abody%7B%0A...ontext_block%7B%0Anon-repeat%7B%0A...non-repeatFields%0A%7D%0Arepeat%7B%0A...repeatFields%0A%7D%0A%7D%0A...onimage_gallery%7B%0Anon-repeat%7B%0A...non-repeatFields%0A%7D%0Arepeat%7B%0A...repeatFields%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D
{
graphQuery: `
{
homepage {
body {
...on text_block {
non-repeat {
...non-repeatFields
}
repeat {
...repeatFields
}
}
...on image_gallery {
non-repeat {
...non-repeatFields
}
repeat {
...repeatFields
}
}
}
}
}
`
}
To return one or multiple fields from a linked document, define the API ID of each field after the API ID of the content relationship field. If there are multiple possible custom types linked, specify them as additional properties.
In this example, we have a blog set with an author_link that can be linked to two different custom types. We'll retrieve all fields from the type author and a title field from the type page:
First, we call the API of the content relationship field and inside curly braces, we write the linked custom type name using a union. Then to call all the fields we write the custom type name again prepended with a spread and appended with Fields or we call each individual field by its API ID:
- Unencoded
- Encoded
- JavaScript
graphQuery={
blog {
author_link {
...on author {
...authorFields
}
...on page {
title
}
}
}
}
graphQuery=%7B%0Ablog%7B%0Aauthor_link%7B%0A...onauthor%7B%0A...authorFields%0A%7D%0A...onpage%7B%0Atitle%0A%7D%0A%7D%0A%7D%0A%7D
{
graphQuery: `
{
blog {
author_link {
...on author {
...authorFields
}
...on page {
title
}
}
}
}
`
}
To return fields within a group set, declare the API ID of the group field and the API IDs of the fields you want to return.
In this example, we have a menu custom type with a group field called gallery with a key text named label and an image field named photo:
- Unencoded
- Encoded
- JavaScript
graphQuery={
menu {
gallery {
photo
label
}
}
}
graphQuery=%7B%0Amenu%7B%0Agallery%7B%0Aphoto%0Alabel%0A%7D%0A%7D%0A%7D
{
graphQuery: `
{
menu {
gallery {
photo
label
}
}
}
`
}
You can also return all fields within a group. Write the API ID of the group prepended with a spread and appended with Fields:
- Unencoded
- Encoded
- JavaScript
graphQuery={
menu {
gallery {
...galleryFields
}
}
}
graphQuery=%7B%0Amenu%7B%0Agallery%7B%0A...galleryFields%0A%7D%0A%7D%0A%7D
{
graphQuery: `
{
menu {
gallery {
...galleryFields
}
}
}
`
}
You can return the Slice content of a document linked to a content relationship field in a Slice.
In Slice Machine the Slice Zone can be found inside slices. The repeatable zone is referenced as items, and the non-repeatable as primary.
In this use case, we want to retrieve a rich text field called name. This field is found inside the repeatable zone of a Slice named contact that belongs to the author custom type. This document is linked to a content relationship field called details that's inside a Slice called paragraph that belongs to the page custom type.
We write the Slice name after using a union. Then inside variation, we define the default Slice with a union. Then, inside primary we call details, and within curly braces, we define the linked custom type with a union. From here you can repeat the process to reach the nested name field:
Slice Machine Slice sets are slightly different from Slices in the Legacy Builder. It’s important to note these differences as they’re crucial when calling the fields.
- Unencoded
- Minified and encoded
- JavaScript
graphQuery={
page {
slices {
...on paragraph_slice {
variation {
...on default {
primary {
details {
...on author {
slices {
...on contact_slice {
variation {
...on default {
items {
name
}
}
}
}
}
}
}
}
}
}
}
}
}
}
%7B%0Apage%7B%0Aslices%7B%0A...onparagraph_slice%7B%0Avariation%7B%0A...ondefault%7B%0Aprimary%7B%0Adetails%7B%0A...onauthor%7B%0Aslices%7B%0A...oncontact_slice%7B%0Avariation%7B%0A...ondefault%7B%0Aitems%7B%0Aname%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D
{
graphQuery: `
{
page {
slices {
...on paragraph_slice {
variation {
...on default {
primary {
details {
...on author {
slices {
...on contact_slice {
variation {
...on default {
items {
name
}
}
}
}
}
}
}
}
}
}
}
}
}
}
`
}
You can return the Slice content of a document linked to a content relationship field in a Slice.
In the Legacy builder, the document can be found inside body, and in the Slice Zone, the repeatable zone is referenced as repeat, and the non-repeatable as non-repeat.
In this use case, we want to retrieve a rich text called name. This field is found inside the repeatable zone of a Slice named contact that belongs to the author custom type. This document is linked to a content relationship field called details that is inside a Slice called paragraph that belongs to the page custom type:
We write the Slice name after using a union. Then, inside non-repeat we call details, and within curly braces, we define the linked custom type with a union. From here you can repeat the process to reach the nested name field:
Slice Machine Slice sets are slightly different from Slices in the Legacy Builder. It’s important to note these differences as they’re crucial when calling the fields.
- Unencoded
- Encoded
- JavaScript
graphQuery={
page {
body {
...on paragraph {
non-repeat {
details {
...on author {
body {
...on contact {
repeat {
name
}
}
}
}
}
}
}
}
}
}
graphQuery=%7B%0Apage%7B%0Abody%7B%0A...onparagraph%7B%0Anon-repeat%7B%0Adetails%7B%0A...onauthor%7B%0Abody%7B%0A...oncontact%7B%0Arepeat%7B%0Aname%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D%0A%7D
{
graphQuery: `
{
page {
body {
...on paragraph {
non-repeat {
details {
...on author {
body {
...on contact {
repeat {
name
}
}
}
}
}
}
}
}
}
}
`
}
Was this article helpful?
Can't find what you're looking for? Spot an error in the documentation? Get in touch with us on our Community Forum or using the feedback form above.