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.
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)
- Repeatable groups
- Slice arrays
- A slice’s
primary
,non-repeat
,items
, orrepeat
sections (note: therepeat
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
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 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
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 repeatable group. Write the API ID of the repeatable 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 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
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
}
}
}
}
}
}
}
}
}
}
`
}
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.