October 14, 2022

One of the questions I get asked every other week is “Does next-drupal work with GraphQL?” .

Yes. Both the Next.js Drupal module and the next-drupal package work with GraphQL 🥳

Let’s take a look at how we can use DrupalClient to fetch GraphQL data.


Fetching GraphQL data with DrupalClient

We built the DrupalClient on top of the standard Fetch API. This means you can use the DrupalClient.fetch method to make GraphQL requests.

Here’s what a GraphQL query looks like:


import { DrupalClient } from "next-drupal"

// 1️⃣ - Create a new DrupalClient.
const drupal = new DrupalClient("http://example.com")

// 2️⃣ - Build your /graphql endpoint
const graphqlUrl = drupal.buildUrl("/graphql")

// 3️⃣ - Make a request
const response = await drupal.fetch(graphqlUrl.toString(), {
  method: "POST",
  body: JSON.stringify({
    query: `
      query {
        nodeArticles(first: 10) {
          nodes {
            id
            title
          }
        }
      }
    `,
  }),
})

const { data } = await response.json()


Authentication

To make authenticated requests, set your clientId and clientSecret on the client. You can then use the withAuth option when fetching:


export const drupal = new DrupalClient("http://example.com",
  {
    auth: {
      clientId: process.env.DRUPAL_CLIENT_ID,
      clientSecret: process.env.DRUPAL_CLIENT_SECRET,
    },
  }
)

const response = await drupal.fetch(graphqlUrl.toString(), {
  method: "POST",
  withAuth: true,
  body: JSON.stringify({
    query: `
      query {
        nodeArticles(first: 10) {
          nodes {
            id
            title
          }
        }
      }
    `,
  }),
})

👉 We are using the Simple OAuth module for authentication. You can read more about authentication in Next.js for Drupal here.


Data Fetching in Next.js

Let’s build a blog landing page using article nodes fetched using GraphQL.

Create a new page at pages/blog.tsx with the following:


import { Layout } from "components/layout"
import { NodeArticleTeaser } from "components/node--article--teaser"
import { drupal } from "lib/drupal"

export async function getStaticProps() {
  const graphqlUrl = drupal.buildUrl("/graphql")

  // Fetch the first 10 articles.
  const response = await drupal.fetch(graphqlUrl.toString(), {
    method: "POST",
    withAuth: true, // Make authenticated requests using OAuth.
    body: JSON.stringify({
      query: `
        query {
          nodeArticles(first: 10) {
            nodes {
              id
              title
              path
              author {
                displayName
              }
              body {
                processed
              }
              created
              image {
                width
                url
                height
              }
            }
          }
        }
      `,
    }),
  })

  const { data } = await response.json()

  return {
    props: {
      articles: data?.nodeArticles?.nodes ?? [],
    },
  }
}

export default function BlogPage({ articles }) {
  return (
    <Layout>
      <div>
        <h1 className="mb-10 text-6xl font-black">Latest Articles.</h1>
        {articles?.length ? (
          articles.map((node) => (
            <div key={node.id}>
              <NodeArticleTeaser node={node} />
              <hr className="my-20" />
            </div>
          ))
        ) : (
          <p className="py-4">No nodes found</p>
        )}
      </div>
    </Layout>
  )
}

If you visit /blog on your Next.js site, you should see a list of the most recent articles.

That was easy, right?

Note: We’re using the GraphQL Compose module by Octahedroid for schema generation. 

If you’d like to see a more advanced example with getStaticPaths, check out the example-qraphql in the next-drupal repository.


What about Preview Mode, Incremental Static Regeneration..etc?

All the features of the Next.js for Drupal module work with GraphQL. No special implementation required. 🎉