This documentation covers the blog features integrated with the GraphQL Starter theme. It explains how to query blog posts, implement search functionality, and more. You’ll find examples of GraphQL queries and mutations.
For now it’s not possible to publish posts using GraphQL. The only way to publish posts is to use the WordPress Interface. So there is no available GraphQL mutation to publish posts.
To get posts, you can use the posts
query. The folowing query contains some example fields that you can use to get posts.
query GetPosts {
posts {
nodes {
id
databaseId
title
content
date
slug
excerpt
categories {
nodes {
name
slug
}
}
featuredImage {
node {
sourceUrl
altText
}
}
author {
node {
name
description
avatar {
url
}
}
}
}
}
}
To get a single post, you can use the post
query.
# Query
query GetPost($id: ID!) {
post(id: $id) {
id
title
}
}
# Variables
{
"id": "cG9zdDox"
}
To search posts, you can use the posts
query with the where
argument.
# Query
query SearchPosts($search: String!) {
posts(where: {search: $search}) {
nodes {
id
title
excerpt
slug
date
categories {
nodes {
name
}
}
featuredImage {
node {
sourceUrl
altText
}
}
author {
node {
name
}
}
}
}
}
# Variables
{
"search": "Hello"
}
The GraphQL Starter theme provides functionality to work with post comments. Here are the available queries and mutations:
To add a comment to a post, use the createComment
mutation:
# Query
mutation AddComment($input: CreateCommentInput!) {
createComment(input: $input) {
success
comment {
id
content
date
author {
node {
name
}
}
}
}
}
# Variables
{
"input": {
"commentOn": 1, # Post Database ID to comment on
"content": "Great post!",
"author": "John Doe",
"authorEmail": "john@example.com"
}
}
To get comments for a specific post:
# Query
query GetPostComments($id: ID!) {
post(id: $id, idType: DATABASE_ID) {
id
title
comments(first: 100) {
nodes {
id
content
parentId
}
}
}
}
# Variables
{
"id": 1 # Post Database ID
}
Test endpoints using the provided HTTP files:
testing-graphql/blog-posts/post-comment.http
WPGraphQL uses cursor-based pagination for posts, which is more reliable than offset-based pagination for large datasets.
first
: Number of items to fetch (like “items per page”)after
: Cursor pointing to the item after which to starthasNextPage
: Indicates if more items existendCursor
: Cursor of the last item in current result set{ “first”: 1 }
{ “data”: { “posts”: { “nodes”: [ { “id”: “cG9zdDoxNA==”, “title”: “First Post”, “excerpt”: “…” } ], “pageInfo”: { “hasNextPage”: true, “endCursor”: “YXJyYXljb25uZWN0aW9uOjE0” } } } }
2. **Next Page Query**
```graphql
query GetPaginatedPosts($first: Int!, $after: String) {
posts(first: $first, after: $after) {
nodes {
id
title
excerpt
}
pageInfo {
hasNextPage
endCursor
}
}
}
# Variables
{
"first": 1,
"after": "YXJyYXljb25uZWN0aW9uOjE0"
}
after
parameterendCursor
from responsehasNextPage
to show/hide “Load More” buttonendCursor
as after
parameterendCursor
hasNextPage
is false
async function loadPosts() { const query = ` query GetPaginatedPosts($first: Int!, $after: String) { posts(first: $first, after: $after) { nodes { id title excerpt } pageInfo { hasNextPage endCursor } } } `;
const variables = {
first: 10,
after: endCursor
};
const response = await fetchGraphQL(query, variables);
const { nodes, pageInfo } = response.data.posts;
// Update cursors
endCursor = pageInfo.endCursor;
hasNextPage = pageInfo.hasNextPage;
return nodes; } ```
The total
field in pageInfo
returns the total number of pages based on your pagination settings. This is useful for building pagination UI components.
# Query
query GetPostsCounts($first: Int!) {
posts(first: $first) {
pageInfo {
total # Total number of pages
}
}
}
# Variables
{
"first": 1 # Number of posts per page
}
3 posts with 1 post per page = 3 pages
{
"data": {
"posts": {
"pageInfo": {
"total": 3
}
}
}
}
first
parameter is required and determines posts per pagefirst
: 1-100 posts per pagetotal
represents total number of pagestotal
ensure that the constant GRAPHQL_STARTER_POST_PAGES_COUNT_ENABLED
is set to true
in the config.php
file.GRAPHQL_STARTER_POST_PAGES_COUNT_ENABLED
is set to false
: “Cannot query field "total" on type "RootQueryToPostConnectionPageInfo".”first
parameter: “The “first” parameter is required for pagination calculation.”first
value: “The “first” parameter must be a numeric value”Note: The
total
field is not available in thepageInfo
object when constantGRAPHQL_STARTER_POST_PAGES_COUNT_ENABLED
is set tofalse
. So set it to false if you don’t need the total pages count.
window.addEventListener('scroll', () => {
if (
hasNextPage &&
window.innerHeight + window.scrollY >= document.body.offsetHeight - 1000
) {
loadPosts();
}
});
<button
onclick="loadPosts()"
disabled={!hasNextPage}
>
{hasNextPage ? 'Load More' : 'No More Posts'}
</button>
Test endpoints using the provided HTTP files:
testing-graphql/blog-posts/post-paginations.http
To enable the like posts functionality, you need to define the GRAPHQL_STARTER_LIKE_POSTS_ENABLED
constant in the functions.php
file.
define('GRAPHQL_STARTER_LIKE_POSTS_ENABLED', true);
# Query
query GetPostsWithLikes($first: Int!) {
posts(first: $first) {
nodes {
databaseId
title
likeCount
}
}
}
# Variables
{
"first": 2
}
# Query
query GetSinglePost($id: ID!) {
post(id: $id, idType: DATABASE_ID) {
databaseId
title
likeCount
}
}
# Variables
{
"id": "cG9zdDox"
}
Toggling a post like is done using the toggleLike
mutation. It does not require authentication.
mutation TogglePostLike($postId: ID!) {
toggleLike(input: {id: $postId}) {
post {
databaseId
likeCount
}
}
}
# Variables
{
"postId": "cG9zdDox"
}
Anonymous users are tracked using cookies:
wp_anonymous_id
Like counts are stored in post meta:
_like_count
Test endpoints using the provided HTTP files:
testing-graphql/blog-posts/posts-like-queries.http
testing-graphql/blog-posts/toggle-like-mutations.http
{
"name": "wp_anonymous_id",
"value": "anon_[hash]",
"path": "/",
"secure": true,
"httpOnly": true,
"sameSite": "Strict"
}