When building a modern web app with WordPress and Next.js, GraphQL is an excellent choice for fetching content. Many developers rely on libraries like Apollo Client to manage GraphQL queries, but I decided to simplify things and avoid adding another dependency. Fetching posts directly with fetch
in Next.js turned out to be just as easy.
In this post, I’ll walk you through how to use WordPress GraphiQL to test your queries and fetch posts in Next.js without relying on a dedicated GraphQL client like Apollo.
First, make sure your WordPress installation has GraphQL capabilities:
https://your-wordpress-site.com/graphql
The GraphiQL IDE provides an interactive environment to test your GraphQL queries.In the GraphiQL IDE, write a query to fetch posts. Here’s an example query:
query GetPosts {
posts {
nodes {
id
title
content
date
slug
}
}
}
nodes
: Contains an array of posts.id
, title
, content
, date
, and slug
.Test the query in GraphiQL. If successful, you’ll see the response structure, which looks like this:
{
"data": {
"posts": {
"nodes": [
{
"id": "1",
"title": "Hello World",
"content": "<p>This is the first post!</p>",
"date": "2024-12-19",
"slug": "hello-world"
}
]
}
}
}
If you haven’t already, set up a Next.js project:
npx create-next-app@latest wordpress-nextjs cd wordpress-nextjs
Rather than using Apollo Client, you can use the built-in fetch
API to make GraphQL queries in Next.js. Here’s how:
GetPosts
, that makes a GraphQL request to your WordPress endpoint.const GetPosts = async () => {
const url = `${process.env.NEXT_PUBLIC_GQL_HOST ?? ''}`;
try {
const response = await fetch(url, {
next: { tags: ['dev'] }, // Optional caching tag for Next.js
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `
query getPosts($categoryName: String = "Dev") {
posts(first: 100, where: { categoryName: $categoryName }) {
nodes {
title
content
id
date
excerpt
contentType {
node {
name
}
}
}
}
}
`,
}),
});
if (!response.ok) {
throw new Error(`Error fetching posts: ${response.statusText}`);
}
const data = await response.json();
return data.data.posts.nodes;
} catch (error) {
console.error(error);
return [];
}
};
export default GetPosts;
import GetPosts from '../utils/GetPosts';
export default function Posts({ posts }) {
return (
<div>
<h1>WordPress Posts</h1>
{posts.map((post) => (
<div key={post.id}>
<h2>{post.title}</h2>
<p>{new Date(post.date).toLocaleDateString()}</p>
<div dangerouslySetInnerHTML={{ __html: post.content }} />
</div>
))}
</div>
);
}
export async function getStaticProps() {
const posts = await GetPosts();
return {
props: {
posts,
},
};
}
GetPosts
: Fetches posts directly from the WordPress GraphQL API.getStaticProps
: Fetches data at build time to optimize performance.dangerouslySetInnerHTML
: Safely renders the HTML content of posts..env.local
NEXT_PUBLIC_GQL_HOST=https://your-wordpress-site.com/graphql
npm run dev
http://localhost:3000/posts
to see your posts displayed.