Query Data

In this article, you’ll learn how to perform queries to the Prismic API to retrieve content in your GraphQL application.

The GraphQL API endpoint

The GraphQL API endpoint allows you to retrieve the content from your Prismic repository. Your GraphQL API endpoint is accessible at:

Copy
https://your-repo-name.cdn.prismic.io/graphql

The GraphQL API Explorer

Every Prismic repository includes a GraphQL API explorer that will help you discover your API and test your queries:

Copy
https://your-repo-name.prismic.io/graphql

The GraphQL Explorer is divided into two parts: the left part lets you build a query, and the right part shows the query results. It offers an autocompletion feature that helps you build your query. By hitting ctrl + space, you will be able to see all the options available as you construct your query.

Query syntax

The schema gives you three options to write queries using the API ID of your document's Custom Type (in these examples, the Custom Type’s API ID is ExampleCustomType). The options are:

  1. ExampleCustomType: Queries a single document of a given type
  2. allExampleCustomTypes: Queries all documents of a given type.
  3. _allDocuments: Queries all the documents in your repository.

Here's a query for a single document:

Copy
query ExampleSingletonQuery($uid: String, $lang: String) {
  exampleCustomType(uid: $uid, lang: $lang) {
    example_title
  }
}

A query for all documents of a repeatable type:

Copy
query ExampleRepeatableQuery {
  allExampleCustomTypes {
    edges {
      node {
        example_title
      }
    }
  }
}

A query for all documents of all types:

Copy
query AllDocs {
  _allDocuments {
    edges {
      node {
        _meta {
          id
          uid
          type
        }
      }
    }
  }
}

To understand a bit about the anatomy of a query, let's see what each field does in this brief example:

  • query is the GraphQL reserved word for writing a query
  • ExampleSingletonQuery is the name of the query
  • ($uid: String, $lang: String) and (uid: $uid, lang: $lang) are variables to filter the response
  • exampleCustomType is the field that defines the type of Custom Type of the query, if it’s a singleton or repeatable type
  • example_title is an example of a Title field in Prismic
Copy
query ExampleSingletonQuery($uid: String, $lang: String) {
  exampleCustomType(uid: $uid, lang: $lang) {
    example_title
  }
}

Arguments

Arguments are parameters that you can add to filter the GraphQL response. They can be either static or dynamic. If they're dynamic, you pass your values in the form of variables.

The most common arguments you will use are:

  • fulltext for filtering by fulltext search
  • where for filtering by field
  • similar for filtering for similar documents
  • sortBy for sorting

When making test queries in the GraphQL Explorer, you'll see a Docs tab in the right top corner of the editor. Here you'll be able to see all the available filtering options.

Filter by full-text search

Use the fulltext argument to search for documents that contain a given term (or terms). It searches the term(s) in the text of a document. fulltext search is not case-sensitive.

The API will scan the following fields:

  • Rich Text
  • Title
  • Key Text
  • UID
  • Select

You can either perform a global full-text search using the fulltext argument alone; or, you can use the where argument to search the text of a specific field (for more info, see the following section on filtering by a field).

Here's an are example to get all the Custom Type “Page” documents that mention the term "Art". First. We do a global search and then select a Rich Text field with the API ID of example_title.

Here's the query for a global search:

Copy
query MyPages {
  allPages(fulltext: "Art") {
    edges {
      node {
        example_title
      }
    }
  }
}

Here's the query for a specific field:

Copy
query MyPages {
  allPages(where: {example_title_fulltext: "Art"}) {
    edges {
      node {
        example_title
      }
    }
  }
}

Filter by metadata

You can filter the response using metadata fields as arguments.

In the following example query, we filter documents of the type “Page” where the metadata value first_publication_date equals 2022-07-23T17:07:000.

Copy
query MyPages {
  allPages(firstPublicationDate: "2020-07-23T17:07:000") {
    edges {
      node {
        example_title
      }
    }
  }
}

Here are all the available metadata fields with usage examples:

uid

string

uid: "art"
uid_in

array of strings

uid_in: ["music", "games", "paintings"]
id

string

id: "WsDFGHJt5df7"
id_in

array of strings

id_in: ["EsdGHJt5df7", "WsDFGHJt5df7"]
lang

string

lang: "en-us"
tags

array of strings

tags: "article"
tags_in

array of strings

tags: ["article", "guide", "news"]
firstPublicationDate_after

date

firstPublicationDate_after:"2022-01-22T08:00:00Z"
firstPublicationDate_before

date

firstPublicationDate_before:"2022-10-22T10:00:00Z"
lastPublicationDate_after

date

lastPublicationDate_after:"2022-10-22T10:00:00Z"
lastPublication_before

date

lastPublicationDate_before:"2022-01-22T08:00:00Z"

Filter by a field

Use the where argument with content fields at the top level of your documents to filter out the response. Only fields at the top level of your document are available for filtering. Fields inside Slices aren't available.

In the next example, we filter documents of the type “Page” with a Boolean field with the API ID of example_boolean equal to true.

Copy
query MyPages {
  allPages(where: {example_boolean: true}) {
    edges {
      node {
        example_title
        _meta {
          firstPublicationDate
        }
      }
    }
  }
}

The following table lists examples of all the fields that can be used with the where argument.

The where field accepts a single key-value pair, specifying a field and a value to compare against. The type of comparison can be specified with a suffix, such as _lt (less than) or _gt (greater than).

With no suffix, the API will search for a direct match.

Link matches
string

where: {example_link: "https://prismic.io/"}

Key Text matches
string

where: {example_key_text: "Lorem ipsum"}

Content Relationship matches
string

where: {example_content_relationship: "WsDFGHJt5df7"}

Date matches
string

where: {example_date: "2022-01-22"}

Select matches
string

where: {example_select: "summer"}

Boolean matches
boolean

where: {example_boolean: true}

The _fulltext suffix will search for a Rich Text or Title field that contains a string.

Rich Text contains
string

where: {example_rich_text_fulltext: "Lorem Ipsum..."}

Title contains
string

where: {example_title_fulltext: "Lorem Ipsum..."}

The _gt and _lt suffixes will filter for a Number field greater or less than a given number.

Number greater than
float

where: {example_number_gt: 97}

Number less than
float

where: {example_number_lt: 98}

The _before and _after suffixes will filter for a Date field that is before or after a given date.

Before date
string

where: {example_date_before: "2022-01-22"}

After date
string

where: {example_date_after: "2022-01-22"}

The _range suffix will filter for a Number field that is within a given range.

Number in range
array of integers

where: {example_number_range:[1,3]}

The _near suffix will filter for a GeoPoint field that is within a given distance of a given location.

GeoPoint near
object

where: {example_geopoint_near: {lat: 20.6, lng: 0.02, dist: 10 }}

Filter for similar documents

Use the similar argument with an object containing the ID of a document. The max value you need to provide above will determine how sensitive the filter is. It represents the maximum number of documents that a term may appear in to remain relevant.

This means that the higher the value, the more documents will be returned. A lower maximum value will return fewer documents.

Here is an example of how to use the similar filter:

Copy
query MyPosts {
  allBlog_posts(similar: {documentId: "W45YDyEAAD42GS9s", max: 30}) {
    totalCount
    edges {
      node {
        title
      }
    }
  }
}

Sort results

The sortBy argument orders the results by a specific field prepended with either an _ASC (ascending order) or _DESC (descending order) option.

These fields can be a metadata publication date or a top-level content fields (fields inside slices or groups are unavailable).

  • meta_lastPublicationDate
  • meta_firstPublicationDate
  • Rich Text field
  • Title field
  • Key Text field
  • Select field
  • Date field
  • Timestamp field
  • Number field

Here is an example using publication dates. This query fetches get all blog_post documents sorted by the first publication date from newest to oldest (descending order).

Copy
query MyPosts {
  allBlog_posts(sortBy: meta_firstPublicationDate_DESC) {
    edges {
      node {
        title
        _meta {
          firstPublicationDate
        }
      }
    }
  }
}

Here's an example using content fields. This query fetches the product documents sorted by a Number field that has the API ID of price from highest to lowest (descending order).

Copy
query MyProducts {
  allProducts(sortBy: price_DESC) {
    edges {
      node {
        title
        price
      }
    }
  }
}

Pagination

The schema offers pagination information that you can use to build cursor-based pagination.

pageInfo { 
 hasPreviousPage 
}

boolean

Specifies if there is a page of results before the current page

pageInfo { 
  hasNextPage 
}

boolean

Specifies if there is a page of results after the current page

pageInfo { 
  startCursor 
}

string

The cursor of the item that starts the current list

pageInfo { 
  endCursor 
}

string

The cursor of the item that ends the current list

edges { 
  cursor 
}

string

An ID to query the documents that come before or after.

totalCount

number

The total number of items across all the pages of the query

Let's see an example of where these fields are located inside a query:

Copy
query AllMyPages {
  allPages {
    pageInfo {
      hasNextPage
      hasPreviousPage
      startCursor
      endCursor
    }
    totalCount
    edges {
      cursor
      node {
        example_title
      }
    }
  }
}

You can use four arguments with cursors to retrieve paginated results from your GraphQL API: afterbeforefirst, and last.

Here's an example using the after and first arguments. Once you have a given cursor, you can use the after argument to retrieve the documents that come after it. This works with the first argument to specify how many items to retrieve (up to 100).

Copy
query MyPosts {
  allBlog_posts(after: "YXJyYXljb25uZW", first: 99) {
    edges {
      node {
        example_title
      }
    }
  }
}

Here's an example using the before and last arguments. Likewise, you can use the before argument to retrieve the documents before the given cursor. This works with the last argument to specify how many items to retrieve (up to 100).

Copy
query MyBlogPosts {
  allBlog_posts(before: "YXJyYXljb25uZWN0aW9uOjE5", last: 10) {
    edges {
      node {
        example_title
      }
    }
  }
}

Selecting fields

Learn how to select Prismic fields in your queries using GraphQL.

Content from Prismic comes in more than a dozen types. Most of these are simple primitive values, like Numbers or Booleans. Others are more complex structured values, like Titles, Rich Texts, and Links.

Fields

Most Prismic fields are retrieved similarly. You need to specify the API ID of the given field. These fields are:

  • Title
  • Rich Text
  • Image
  • Date
  • Timestamp
  • Color
  • Number
  • Key Text
  • Select
  • Boolean
  • Embed
  • GeoPoint

Here's what retrieving any of these would look like. In the following example, we retrieve a Key Text field with the API ID of example_key_text that is at the top level of the document (outside of a Slice Zone):

Copy
query MyPages {
  allPages {
    edges {
      node {
        example_key_text
      }
    }
  }
}

Nested Content

In the case of Content Relationship and Group fields, you need to specify exactly what you need from each one.

Here's a query for a Content Relationship field:

Copy
query MyPages {
  allPages {
    edges {
      node {
        example_content_relationship {
          ...on _Document {
            __typename
            _meta {
              id
              uid
              lang
            }
          }
        }
      }
    }
  }

Here's a query for a Group field:

Copy
query MyPages {
  allPages {
    edges {
      node {
        example_group {
          example_number
        }
      }
    }
  }
}

Slices

We use the Union type inside queries to specify each of the Slices we need from a Custom Type using the following syntax:

Copy
...on ExampleCustomTypeBodySlice

Where ExampleCustomType is the name of your Custom Type and Slice the Slice's name.

In the following example, we have a Page Custom Type. It has one Slice with the API ID of playlist containing fields in both the repeatable and non-repeatable zones:

Copy
query MyQuery {
  page(uid: "jazz", lang: "en-us") {
    body {
      ...on PageBodyPlaylist {
        label
        type
        primary {
          playlist_name
        }
        fields {
          song
          author
        }
      }
    }
  }
}

Metadata fields

In singleton-type queries, the metadata fields are found in the first node of the query.

In repeatable type queries, the metadata fields are found inside edges > node.

Here's an example for a singleton query:

Copy
query PageQuery($uid: String, $lang: String) {
  page(uid: $uid, lang: $lang) {
    _meta {
      id
      uid
      type
      tags
      lang
      firstPublicationDate
      lastPublicationDate
      alternateLanguages {
        lang
      }
    }
  }
}

Here's an example for repeatable documents:

Copy
query MyPages {
  allPages {
    edges {
      node {
        _meta {
          id
          uid
          type
          tags
          lang
          firstPublicationDate
          lastPublicationDate
          alternateLanguages {
            lang
          }
        }
      }
    }
  }
}

Next steps

After retrieving your Slices and fields, you're ready to template your content, preview your draft documents, and finally deploy your site. We’ll detail how you can choose one framework to continue building your project on the following page.


Was this article helpful?
Not really
Yes, Thanks

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.