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 Document 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.

Example

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
Unencoded
Copy
graphQuery={
  blog {
    author_link {
      ...on author {
        author_name
        author_image
      }
    }
  }
}
Encoded
Copy
graphQuery=%7B%0Ablog%7B%0Aauthor_link%7B%0A...onauthor%7B%0Aauthor_name%0Aauthor_image%0A%7D%0A%7D%0A%7D%0A%7D
JavaScript
Copy
{
  graphQuery: `
    {
      blog {
        author_link {
          ...on author {
            author_name
            author_image
          }
        }
      }
    }
  `
}

In a Node.js app, that might look like this:

Copy
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:

Copy
[
  {
    uid: 'hello-world',
    type: 'blog',
    // ...
    data: {
      author_link: {
        type: 'author',
        // ...
        uid: 'walt-whitman',
        data: {
          name: 'Walt Whitman',
        },
      },
    },
  },
]

Usage

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.

GraphQuery object

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
Unencoded
Copy
graphQuery={
  example_custom_type {
    example_field_one
  }
}
Encoded
Copy
graphQuery=%7B%0Aexample_custom_type%7B%0Aexample_field_one%0A%7D%0A%7D
JavaScript
Copy
{
  graphQuery: `
    {
      example_custom_type {
        example_field_one
      }
    }
  `
}

Fields

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
Unencoded
Copy
graphQuery={
  example_custom_type {
    example_number_field
    example_image_field
  }
}
Encoded
Copy
graphQuery=%7B%0Aexample_custom_type%7B%0Aexample_number_field%0Aexample_image_field%0A%7D%0A%7D
JavaScript
Copy
{
  graphQuery: `
    {
      example_custom_type {
        example_number_field
        example_image_field
      }
    }
  `
}

Sets

A set is a collection of fields. The following properties are retrieved as sets:

  • Documents (identified by the custom type)
  • Repeatable groups
  • Slice arrays
  • A slice’s primary, non-repeat, items, or repeat sections (note: the repeat section was deprecated in favor of repeatable group fields in May 2024)

A set is identified by its API ID followed by curly brackets containing properties.

  • Unencoded
  • Minified and encoded
  • JavaScript
Unencoded
Copy
graphQuery={
  example_set {
    example_number_field
    example_group_field {
      example_rich_text_field
    }
  }
}
Minified and encoded
Copy
graphQuery=%7B%0Aexample_set%7B%0Aexample_number_field%0Aexample_group_field%7B%0Aexample_rich_text_field%0A%7D%0A%7D%0A%7D
JavaScript
Copy
{
  graphQuery: `
    {
      example_set {
        example_number_field
        example_group_field {
          example_rich_text_field
        }
      }
    }
  `
}

Union

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
Unencoded
Copy
graphQuery={
  blog_post {
    title
    author_link {
      ...on author {
        author_name
      }
    }
  }
}
Minified and encoded
Copy
graphQuery=%7B%0Ablog_post%7B%0Atitle%0Aauthor_link%7B%0A...onauthor%7B%0Aauthor_name%0A%7D%0A%7D%0A%7D%0A%7D
JavaScript
Copy
{
  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
Unencoded
Copy
graphQuery={
  blog_post {
    title
    author_link {
      ...on author {
        author_name
      }
      ...on guest_author {
        author_name
      }
    }
  }
}
Encoded
Copy
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
JavaScript
Copy
{
  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
Unencoded
Copy
graphQuery={
  example_custom_type {
    slices {
      ... on text_block {
        primary {
          text
        }
      }
      ... on hero_image {
        primary {
          image
        }
      }
    }
  }
}
Minified and encoded
Copy
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
JavaScript
Copy
{
  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
Unencoded
Copy
graphQuery={
  example_custom_type {
    slices {
      ... on text_block {
        variation {
          ...on default {
            primary {
              title
            }
            items {
              description
            }
          }
          ...on noTitle {
            items {
              description
            }
          }
        }
      }
    }
  }
}
Minified and encoded
Copy
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
JavaScript
Copy
{
  graphQuery: `
    {
      example_custom_type {
        slices {
          ... on text_block {
            variation {
              ...on default {
                primary {
                  title
                }
                items {
                  description
                }
              }
              ...on noTitle {
                items {
                  description
                }
              }
            }
          }
        }
      }
    }
  `
}

Spread

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
Unencoded
Copy
graphQuery={
  example_custom_type {
    ...example_custom_typeFields
  }
}
Encoded
Copy
graphQuery=%7B%0Aexample_custom_type%7B%0A...example_custom_typeFields%0A%7D%0A%7D
JavaScript
Copy
{
  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
Unencoded
Copy
graphQuery={
  blog {
    ...blogFields
    author_link {
      ...on author {
        author_name
      }
    }
  }
}
Encoded
Copy
graphQuery=%7B%0Ablog%7B%0A...blogFields%0Aauthor_link%7B%0A...onauthor%7B%0Aauthor_name%0A%7D%0A%7D%0A%7D%0A%7D
JavaScript
Copy
{
  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
Unencoded
Copy
graphQuery={
  blog {
    author_link {
      ...author_linkFields
    }
  }
}
Encoded
Copy
graphQuery=%7B%0Ablog%7B%0Aauthor_link%7B%0A...author_linkFields%0A%7D%0A%7D%0A%7D
JavaScript
Copy
{
  graphQuery: `
    {
      blog {
        author_link {
          ...author_linkFields
        }
      }
    }
  `
}

Use cases

All fields from a slice created with Slice Machine

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
Unencoded
Copy
graphQuery={
  homepage {
    slices {
      ...on text_block {
        variation {
          ...on default {
            primary {
              ...primaryFields
            }
            items {
              ...itemsFields
            }
          }
          ...on noTitle {
            items {
              ...itemsFields
            }
          }
        }
      }
    }
  }
}
Encoded
Copy
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
JavaScript
Copy
{
  graphQuery: `
    {
      homepage {
        slices {
          ...on text_block {
            variation {
              ...on default {
                primary {
                  ...primaryFields
                }
                items {
                  ...itemsFields
                }
              }
              ...on noTitle {
                items {
                  ...itemsFields
                }
              }
            }
          }
        }
      }
    }
  `
}

All fields from a slice created with the Legacy Builder

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
Unencoded
Copy
graphQuery={
  homepage {
    body {
      ...on text_block {
        non-repeat {
          ...non-repeatFields
        }
        repeat {
          ...repeatFields
        }
      }
      ...on image_gallery {
        non-repeat {
          ...non-repeatFields
        }
        repeat {
          ...repeatFields
        }
      }
    }
  }
}
Encoded
Copy
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
JavaScript
Copy
{
  graphQuery: `
    {
      homepage {
        body {
          ...on text_block {
            non-repeat {
              ...non-repeatFields
            }
            repeat {
              ...repeatFields
            }
          }
          ...on image_gallery {
            non-repeat {
              ...non-repeatFields
            }
            repeat {
              ...repeatFields
            }
          }
        }
      }
    }
  `
}

Fields from a linked document

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
Unencoded
Copy
graphQuery={
  blog {
    author_link {
      ...on author {
        ...authorFields
      }
      ...on page {
        title
      }
    }
  }
}
Encoded
Copy
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
JavaScript
Copy
{
  graphQuery: `
    {
      blog {
        author_link {
          ...on author {
            ...authorFields
          }
          ...on page {
            title
          }
        }
      }
    }
  `
}

Fields in a repeatable group

To return fields within a repeatable 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 repeatable group field called gallery with a key text named label and an image field named photo:

  • Unencoded
  • Encoded
  • JavaScript
Unencoded
Copy
graphQuery={
  menu {
    gallery {
      photo
      label
    }
  }
}
Encoded
Copy
graphQuery=%7B%0Amenu%7B%0Agallery%7B%0Aphoto%0Alabel%0A%7D%0A%7D%0A%7D
JavaScript
Copy
{
  graphQuery: `
    {
      menu {
        gallery {
          photo
          label
        }
      }
    }
  `
}

You can also return all fields within a repeatable group. Write the API ID of the repeatable group prepended with a spread and appended with Fields:

  • Unencoded
  • Encoded
  • JavaScript
Unencoded
Copy
graphQuery={
  menu {
    gallery {
      ...galleryFields
    }
  }
}
Encoded
Copy
graphQuery=%7B%0Amenu%7B%0Agallery%7B%0A...galleryFields%0A%7D%0A%7D%0A%7D
JavaScript
Copy
{
  graphQuery: `
    {
      menu {
        gallery {
          ...galleryFields
        }
      }
    }
  `
}

Slice content of a linked document within a slice with Slice Machine

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 with the id contact_slice that belongs to the author custom type. This document is linked to a content relationship field called details inside a slice called paragraph_slice 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
Unencoded
Copy
graphQuery={
  page {
    slices {
      ...on paragraph_slice {
        variation {
          ...on default {
            primary {
              details {
                ...on author {
                  slices {
                    ...on contact_slice {
                      variation {
                        ...on default {
                          items {
                            name
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
Minified and encoded
Copy
%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
JavaScript
Copy
{
  graphQuery: `
    {
      page {
        slices {
          ...on paragraph_slice {
            variation {
              ...on default {
                primary {
                  details {
                    ...on author {
                      slices {
                        ...on contact_slice {
                          variation {
                            ...on default {
                              items {
                                name
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  `
}

Slice content of a linked document within a slice with the Legacy Builder

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
Unencoded
Copy
graphQuery={
  page {
    body {
      ...on paragraph {
        non-repeat {
          details {
            ...on author {
              body {
                ...on contact {
                  repeat {
                    name
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
Encoded
Copy
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
JavaScript
Copy
{
  graphQuery: `
    {
      page {
        body {
          ...on paragraph {
            non-repeat {
              details {
                ...on author {
                  body {
                    ...on contact {
                      repeat {
                        name
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  `
}

Can't find what you're looking for?

Need technical Support? Spot an error in the documentation? Get in touch with us on our Community Forum.