Skip to main content

Post Queries

Query WordPress posts for dynamic templates and content displays.

What This Guide Covers

Posts are the foundation of most WordPress sites - blog articles, news updates, case studies, product descriptions, and more. This guide shows you how to query WordPress posts using Builderius GraphQL for any content scenario.

You'll learn how to:

  • Get current post data for single post templates
  • Query multiple posts for archive pages and listings
  • Filter posts by categories, tags, custom fields, and dates
  • Work with custom post types (products, events, portfolios)
  • Access custom fields from ACF and MetaBox
  • Build related content sections and post relationships
  • Handle pagination for large post collections

Query Single Post

Get the post you're currently viewing:

{
post {
post_title
post_content
post_date
}
}

Complete Post Fields Reference

Here's what's available when querying a post - all standard WordPress fields plus custom field integrations:

{
post {
# Basic Fields
ID
post_title
post_content
post_excerpt
post_date
post_datetime
post_modified_date
post_status
post_name
post_type
post_parent
permalink
guid

# Native WordPress Meta Fields
custom_price: meta_value(key: "_price")
featured_flag: meta_value(key: "_featured")

# All Meta Fields (returns array)
meta {
key
value
}

# Author Information
post_author {
ID
display_name
user_email
user_login
avatar_url
roles
description
}

# Featured Image
has_featured_image
featured_image {
title
alt_text
caption
description
thumb: file_url(size: THUMBNAIL)
medium: file_url(size: MEDIUM)
medium_large: file_url(size: MEDIUM_LARGE)
large: file_url(size: LARGE)
xl: file_url(size: SIZE_1536X1536)
xxl: file_url(size: SIZE_2048X2048)
original: file_url(size: ORIGINAL)
sizes
}

# Taxonomies
categories {
term_id
name
slug
description
count
}

tags {
term_id
name
slug
description
count
}

# Custom Taxonomy Terms
event_categories: terms_query(
arguments: {
taxonomy: "event_category"
object_ids: "{{ID}}"
}
) {
terms {
term_id
name
slug
description
count
}
}

# Comments
comments_open
comments {
ID
comment_author
comment_content
comment_date
comment_approved
}

# ACF Fields
price: acf_value(name: "price")
featured: acf_value(name: "featured")
gallery: acf_value(name: "gallery")

# ACF Relationship Fields
related_products: acf_post_objects_value(name: "related_products") {
ID
post_title
permalink
}

# ACF Repeater Fields
testimonials: acf_repeater_value(name: "testimonials") {
name: acf_value(name: "name")
quote: acf_value(name: "quote")
rating: acf_value(name: "rating")
}

# MetaBox Fields (Post Level)
sku: metabox_value(field_id: "sku")
product_specs: metabox_value(field_id: "product_specs")

# MetaBox Post Object Fields
manufacturer: metabox_post_value(field_id: "manufacturer") {
ID
post_title
website: metabox_value(field_id: "website")
}
}
}

Main Posts Loop

WordPress automatically provides the main query for each archive template. These are the default post loops available without any custom arguments - just the standard WordPress main query for each archive type.

Main blog page - automatically shows latest posts:

{
archive {
title
posts_query {
posts {
ID
post_title
post_excerpt
post_date
post_author {
display_name
avatar_url
}
featured_image {
file_url(size: MEDIUM)
alt_text
}
categories {
name
slug
}
tags {
name
slug
}
}
pagination {
links
current_page
total_pages
}
}
}
}

Custom Post Queries

Custom post queries Pro feature let you manually specify exactly what content you want, with your own filtering and arguments. Unlike the main query (which WordPress generates automatically based on the current page), custom queries give you complete control.

Main Query vs Custom Query:

  • Main Query (archive.posts_query) - WordPress automatically decides what posts to show based on current page context
  • Custom Query (posts_query(arguments: {...})) - You specify exactly what posts to fetch with custom arguments

Recent posts with category filtering:

{
posts_query(
arguments: {
post_type: "post"
post_status: "publish"
posts_per_page: 6
orderby: "date"
order: "DESC"
}
) {
posts {
ID
post_title
post_excerpt
post_date
post_author {
display_name
avatar_url
}
featured_image {
file_url(size: MEDIUM)
alt_text
}
categories {
name
slug
}
}
pagination {
links
}
}
}

Query Arguments

Complete Arguments Reference

All arguments available for posts_query

{
posts_query(
arguments: {
# Post Type & Status
post_type: "post" # String/Array - Filter by post type
post_status: "publish" # String/Array - Filter by status

# Pagination & Limits
posts_per_page: 10 # Int - Number of posts to return (-1 for all)
offset: 5 # Int - Number of posts to skip from start
paged: 2 # Int - Page number for pagination

# Ordering
orderby: "date" # String - Sort field (date, title, menu_order, rand, meta_value)
order: "DESC" # String - Sort direction (DESC, ASC)
meta_key: "custom_order" # String - Meta key for meta_value ordering

# Include/Exclude Posts
post__in: [1, 5, 12] # Array - Include only these post IDs
post__not_in: [3, 7] # Array - Exclude these post IDs

# Author Filtering
author: 1 # Int - Posts by specific author ID
author__in: [1, 5, 12] # Array - Posts by any of these author IDs
author__not_in: [3, 7] # Array - Exclude posts by these author IDs

# Hierarchy
post_parent: 10 # Int - Posts with specific parent ID
post_parent__in: [10, 15] # Array - Posts with any of these parent IDs
post_parent__not_in: [5, 8] # Array - Exclude posts with these parent IDs

# Advanced Filtering
meta_query: { # Object - Filter by custom field values
array: [
{
key: "price"
value: 100
compare: ">"
}
]
}
tax_query: { # Object - Filter by taxonomy terms
array: [
{
taxonomy: "category"
field: "slug"
terms: ["news"]
}
]
}
date_query: { # Object - Filter by date ranges
array: [
{
after: "2024-01-01"
before: "2024-12-31"
}
]
}
search: "wordpress" # String - Search posts by keyword
}
) {
posts {
post_title
}
}
}

Basic Filtering

Filter by specific post types:

{
posts_query(
arguments: {
post_type: "page"
}
) {
posts {
post_title
}
}
}

Filter by Taxonomy Terms

Filter posts using WordPress taxonomies like categories, tags, or custom taxonomies. Use tax_query to specify taxonomy filtering conditions.

Posts from one specific category:

{
posts_query(
arguments: {
tax_query: {
array: [
{
taxonomy: "category"
field: "slug"
terms: ["news"]
operator: "IN"
}
]
}
}
) {
posts {
post_title
}
}
}

Filter by Custom Field Values

Filter posts based on custom field (meta) values. Use meta_query to specify conditions for ACF fields, MetaBox fields, or native WordPress meta.

Posts with a specific meta field value:

{
posts_query(
arguments: {
meta_query: {
array: [
{
key: "featured"
value: true
compare: "="
}
]
}
}
) {
posts {
post_title
featured: acf_value(name: "featured")
}
}
}

Find posts related to the current post based on different relationship types. These queries use the current post's data to find connected content.

Find posts that share categories with the current post:

{
post { # curent post
ID @private. # use ID to establish exclude this post
categories @private {
term_id # use terms to base relation on
}
related_posts: posts_query(
arguments: {
posts_per_page: 5
post__not_in: "{{ID}}"
tax_query: {
array: [
{
taxonomy: "category"
field: "term_id"
terms: "{{pluck(categories, 'term_id')}}" # posts that share the current post terms
operator: "IN"
}
]
}
}
) {
posts {
post_title
post_excerpt
}
}
}
}

Pagination

Handle pagination for post listings, whether using WordPress default archive pagination or custom query pagination.

Standard pagination for WordPress archives (automatic):

{
archive {
posts_query {
posts {
post_title
}
pagination {
links
current_page
total_pages
}
}
}
}

Advanced Filtering

Combine multiple filtering methods for complex queries. These examples show how to layer date ranges, custom field conditions, and taxonomy filters together.

Filter posts by publication date ranges:

{
posts_query(
arguments: {
date_query: {
array: [
{
after: "2024-01-01"
before: "2024-12-31"
inclusive: true
}
]
}
}
) {
posts {
post_title
post_date
}
}
}

Performance Tips

Optimize your queries for better performance by using these techniques to reduce data transfer and processing time.

Use @private to query data you need for variables but don't want in output:

{
post {
ID @private # Hidden from output, available for {{ID}}
post_title
categories @private { # Get categories privately
term_id
}
related_posts: posts_query(
arguments: {
post__not_in: ["{{ID}}"] # Uses hidden ID
}
) {
posts {
post_title
}
}
}
}

Common Use Cases

Real-world examples of post queries you'll commonly need. These patterns cover the most frequent scenarios for displaying WordPress content.

Homepage featured posts selection based on custom field:

{
posts_query(
arguments: {
meta_query: {
array: [
{
key: "featured_on_homepage" # Custom field name
value: true # Field must be true
compare: "=" # Exact match
}
]
}
posts_per_page: 3 # Limit to 3 posts
}
) {
posts {
post_title
post_excerpt
featured_image {
file_url(size: MEDIUM) # Medium size thumbnail
alt_text
}
permalink # Full URL to post
}
}
}