Anatomy of a Query

Prismic no longer recommends the gatsby-source-prismic-graphql plugin

With recent changes to Gatsby, Prismic no longer recommends the gatsby-source-prismic-graphql plugin that this documentation uses. Read more about the future of Prismic and Gatsby. We highly recommend using the gatsby-source-prismic instead. The documentation for this plugin can be found in the plugin's github README.

We will leave this documentation here for now, but will change it in the future when we determine the best approach for Prismic & Gatsby.

This article explains the anatomy of a GraphQL query when using Prismic + Gatsby.

What is a GraphQL query?

The basic operation that GraphQL syntax has to retrieve data is called Query, which is a read‐only kind of fetch. What differentiates Graphql from REST APIs (or others) is that you call exactly what you need in each query.

Basic GraphQL query parts

We use queries inside Gatsby pages and components to declare which data each one of them needs. We're going to go over all the sections that make up a query:

Diagram of the different parts of a query

Query type

This is the operation type that defines the kind of operation that you're performing. There are other operation types in GraphQL. The Prismic API is read only, so we will only ever use query. Check out the GraphQL official documentation about queries to learn more about this.

You can use it alone or along with the Query name (explained below). So if you're making an anonymous query, this value can be omitted.

Example in diagram: query

Query name

This is the operation you'll use to name your queries. This parameter will only be required when making multiple queries that share similar content. You could choose to leave queries unnamed but the official GraphQL docs recommend you not to do it, because names are useful when tracking the retrieved data of a certain query and when debugging a project. Read the GraphQL official documentation about queries.

Example in diagram: MyPosts

Fields (Root-level)

Root level fields initiate a query that is defined by the API schema definition. When querying your Prismic API endpoint this field will always be prismic and that's how Gatsby knows you're looking for your Prismic content.

Example in diagram: prismic

Root type fields provided by the schema

When working with GraphQL queries it's important to remember that the structure of a schema will depend on the API that you're working with. A GraphQL schema provides a root type for each kind of operation.

Example in diagram: The allPostsedges, and node fields are Root type fields provided by the schema when querying multiple documents.

If you want to visualize the schema of your endpoint you can go to the Gatsby GraphQL Explorer of your project while running your project in development. Accessible at http://localhost:8000/__graphql.

Read the official Gatsby documentation about using the Playground.

Arguments

Arguments serve as parameters that you can add to filter the response. They can be optional or required depending on the schema definition.

Example in diagram: where and author (note that author is also a Top-level field type, one of which can be used as an argument).

Variables

Variables are passed as the value of a given argument. They can be static or dynamic:

  • Static: In the diagram above, we're using the ID "ZmZAAhMC" of a document of the type Author as an example of a static search parameter.
  • Dynamic: Dynamic variables are also passed as the value of a given argument. In Gatsby you use dynamic variables to dynamically generate pages. The data passed into the query variables comes from the plugin. How dynamic variables work are beyond the scope of this article. If you'd like to learn more about this, check out the official Gatsby documentation on variables.

Fields (Top-level)

These represent available fields in your documents that you can retrieve from the Prismic API through the schema.

Example in diagram: title is a Title field, content is a Rich Text field, illustration is an Image field, and author is a Link field.

Union type

Unions are used whenever the value for a field could be multiple types of data. You can use unions to perform something similar to a switch conditional statement. After adding a Union you can then specify the fields that you need from a given type.

Example in diagram: The ...on PRISMIC_AuthorTag union is calling a linked document of the type author_tag. Then we can specify all the fields that exist in this document. In this case we're just calling a Rich Text field with the API ID of name. Learn more about how to retrieve linked field content using Unions.

Lifecycle of a query

With everything you've learned so far we'll now look into a complete example that will show you what working with a query looks like from start to finish.

1. Writing the query

First we need to write a query in the project to retrieve the data from the Prismic API endpoint. In this example we're creating a variable which holds a graphql query that has the Query name of MyPosts. Then allPosts indicates that It is going to filter all documents of the type Post.

We then use the where argument to filter out the docs where a Content relationship field has the API ID of author. In this case this ID "ZmZAAhMC" belongs to a document of the type AuthorTag. To call it we use the Union type ...on PRISMIC_AuthorTag and retrieve a Rich Text field inside this document that has the API ID of "name".

We also call other Top-level fields like title, content, and illustration.

Copy
import React from 'react'
import { graphql } from 'gatsby'

export const query = graphql `
 query MyPosts {
   prismic {
     allPosts(where: {author: "XmZAAhMC"}) {
       edges {
         node {
           title
           content
           illustration
           author {
             ... on PRISMIC_AuthorTag {
               name
             }
           }
         }
       }
     }
   }
 }
`

2. Retrieving the data

Here we are seeing an example of what the response of a query looks like. You can see that the JSON structure is similar to the query itself.

Copy
{
  "data": {
    "prismic": {
      "allPosts": {
        "edges": [
          {
            "node": {
              "title": [...],
              "content": [...],
              "illustration": {...},
              "author": {
                "name": [...]
              }
            }
          }
        ]
      }
    }
  }
}

3. Templating the data

Here's an example of how you could use and template the retrieved data from the query.

Copy
import React from 'react'
import { graphql } from 'gatsby'
import { RichText } from 'prismic-reactjs'

const Post = ({ data }) => {
  const prismicContent = data.prismic.allPages.edges[0]
  if (!prismicContent) return null
  const document = doc.node

  return (
    <div>
      {RichText.render(document.title)}
      {RichText.render(document.author.name)}
      {RichText.render(document.content)}
      <img src={document.illustration.url} alt={document.illustration.alt} />
    </div>
  )
}

export const query = graphql `
 query MyPosts {
   prismic {
     allPosts(where: {author: "XmZAAhMC"}) {
       edges {
         node {
           title
           content
           illustration
           author {
             ... on PRISMIC_AuthorTag {
               name
             }
           }
         }
       }
     }
   }
 }
`

export default Post

4. Browser view

Finally, we run our project and voilà! — our data is now visible in the browser for everyone to see.

The final rendered content
The final rendered content