GraphQuery

This shows how to use the Prismic GraphQuery query option to retrieve certain fields and retrieve content from linked documents.

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.

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.

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",
        },
      },
    },
  },
];

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:

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.

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.

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:

graphQuery={
  blog_post {
    title
    author_link {
      ...on author {
        author_name
      }
    }
  }
}

If there are multiple possible custom types linked, specify them as additional properties:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

graphQuery={
  page {
    body {
      ...on paragraph {
        non-repeat {
          details {
            ...on author {
              body {
                ...on contact {
                  repeat {
                    name
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}