GraphQL Syntax
Builderius uses a custom GraphQL implementation optimized specifically for WordPress Pro Feature data structures and page builder workflows. Unlike standard GraphQL, this syntax is designed to work seamlessly with WordPress's post types, custom fields, taxonomies, and user roles while being accessible to visual builders rather than requiring deep GraphQL knowledge.
Understanding these syntax rules is essential for writing valid queries that leverage WordPress data efficiently.
Root Object Requirement
All queries must be wrapped in a root object:
{
# ... all code here
}
Basic Syntax Rules
- Query Structure
- Field Selection
- Nested Objects
Every query follows this structure:
{
query_name {
field_name
}
}
Fields are listed inside curly braces:
{
post {
post_title
post_content
}
}
Use nested braces for object properties:
{
post {
featured_image {
file_url
alt_text
}
}
}
Arguments Syntax
- Simple Arguments
- Arguments Object
Arguments use parentheses and key-value pairs:
{
query_function(argument: "value") {
field
}
}
Collection queries use an arguments object that contains a series of key-value pairs:
{
posts_query(
arguments: {
key: "value"
another_key: 123
}
) {
posts {
field
}
}
}
Data Types
- Strings
- Numbers
- Booleans
- Arrays
Use double quotes for string values:
{
posts_query(
arguments: {
post_type: "post"
post_status: "publish"
}
) {
posts {
post_title
}
}
}
Numbers don't require quotes:
{
posts_query(
arguments: {
posts_per_page: 10
author: 5
}
) {
posts {
post_title
}
}
}
Use true or false without quotes:
{
terms_query(
arguments: {
hide_empty: true
taxonomy: "category"
}
) {
terms {
name
}
}
}
Use square brackets for arrays:
{
posts_query(
arguments: {
post__in: [1, 2, 3, 4]
post_status: ["publish", "private"]
}
) {
posts {
post_title
}
}
}
Special Utilities
- Variables
- Aliases
- Directives
Use variables to reference dynamic data from the current template context. This creates relationships between different parts of your query.
- Local context:
"{{variable_name}}"- data from current item - Global context:
"[[variable_name]]"- site-wide data
{
post {
ID @private
related_posts: posts_query(
arguments: {
post__not_in: "{{ID}}"
}
) {
posts {
post_title
}
}
}
}
Use aliases to rename fields for clearer output or to call the same field multiple times with different parameters. Separate alias from field name using colon:
title==post_titlethumbnail==file_url(size: THUMBNAIL)- ...
{
posts_query {
posts {
title: post_title
content: post_content
featured_image {
thumbnail: file_url(size: THUMBNAIL)
large: file_url(size: LARGE)
}
}
}
}
Use @ symbol for directives that modify field behavior:
@private- field needed for logic but hidden from output@recursive- enables recursive querying for hierarchical data@transform- applies expression to transform field value inline
{
nav_menu(identifier: "name", value: "main-menu") {
items {
ID @private
title
url
children @recursive {
title
url
}
uppercase_title: title @transform(
expression: "upper(title)"
)
}
}
}
Syntax Conventions
- Field Names
- Indentation
- Line Breaks
- Use snake_case:
post_title,featured_image - No spaces allowed:
post title❌ - No special characters except underscore
Use consistent indentation for readability:
{
posts_query {
posts {
post_title
featured_image {
file_url
}
}
}
}
- Each field on separate line
- Opening brace on same line as field name
- Closing brace aligned with opening statement
Expression Syntax
Expressions are used to perform data transformation, calculations and more.
- Simple Expression
- With Arguments
- Transform Directive
- Single Line Rule
{
posts_query {
posts {
post_title
uppercase_title: expression_result(
expression: "upper(post_title)"
)
}
}
}
{
posts_query {
posts {
post_title
short_title: expression_result(
expression: "limit_words(post_title, 3)"
)
post_date
formatted_date: expression_result(
expression: "date('F j, Y', strtotime(post_date))"
)
}
}
}
{
posts_query {
posts {
post_title
uppercase_title: post_title @transform(
expression: "upper(post_title)"
)
}
}
}
Expressions must be on one line:
expression: "function1() && function2()" ✅
expression: "function1() &&
function2()" ❌
Combining Queries
You can combine multiple queries in sophisticated ways to create custom data relationships and nested structures.
- Multiple Independent
- Nested Queries
- Relational Queries
Independent queries in same variable:
{
# Recent blog posts
recent_posts: posts_query(
arguments: {
post_type: "post"
posts_per_page: 5
}
) {
posts {
post_title
post_date
}
}
# Team members
team_members: users_query(
arguments: {
role: "author"
number: 4
}
) {
users {
display_name
avatar_url
}
}
# Site options
site_title: option_value(name: "blogname")
contact_email: option_value(name: "admin_email")
}
Query within query structure:
{
post {
ID
post_title
post_author {
display_name
# Nested query for author's other posts
author_posts: posts_query(
arguments: {
author: "{{ID}}"
posts_per_page: 3
post_type: "post"
}
) {
posts {
post_title
permalink
}
}
}
}
}
Queries connected by data variables:
{
posts_query(
arguments: {
post_type: "post"
posts_per_page: 5
}
) {
posts {
ID @private # ID will be used in nested loop to establish relationship of terms to post
post_title
post_excerpt
# Get categories for this specific post
post_categories: terms_query(
arguments: {
taxonomy: "category"
object_ids: "{{ID}}" # limit terms to those assigned to current post in loop
}
) {
terms {
name
slug
}
}
}
}
}
Key patterns:
- Multiple queries: Independent data sources in single variable
- Nested queries: Queries inside object structures for hierarchical data
- Relational queries: Using
@privatefields and data variables to connect queries
These patterns enable sophisticated data relationships while maintaining readable query structure.
Common Syntax Errors
- Missing Root Object
- Missing Quotes
- Invalid Field Names
- Incorrect Braces
post { ❌
post_title
}
{ ✅
post {
post_title
}
}
{
posts_query(
arguments: {
post_type: post ❌
}
) {
posts {
post_title
}
}
}
{
posts_query(
arguments: {
post_type: "post" ✅
}
) {
posts {
post_title
}
}
}
{
posts_query {
posts {
post title: post_title ❌ (space in alias)
post_title: post_title ✅
}
}
}
{
posts_query {
posts {
post_title
} ❌ (missing closing brace)
}
{
posts_query {
posts {
post_title
}
} ✅
}
These syntax rules form the foundation for writing valid Builderius GraphQL queries.
WPGraphQL Syntax Comparison
Builderius uses its own GraphQL syntax - standard WPGraphQL queries won't work. This custom implementation uses familiar WordPress field names (post_title vs title), WordPress query arguments (meta_query, tax_query), and direct array access instead of edges/nodes pagination, making it more intuitive for WordPress developers.
- Builderius GraphQL
- WPGraphQL
{
posts_query(
arguments: {
post_type: "post"
posts_per_page: 5
}
) {
posts {
ID
post_title
featured_image {
thumbnail: file_url(size: THUMBNAIL)
medium: file_url(size: MEDIUM)
large: file_url(size: LARGE)
alt_text
}
}
}
}
Built-in WordPress features:
- WordPress field names (
post_title) - Arguments object with WordPress query parameters
- Direct array access without pagination structure
- Built-in image size constants
query GetPosts {
posts(first: 5) {
edges {
node {
id
title
featuredImage {
node {
thumbnailUrl: sourceUrl(size: THUMBNAIL)
mediumUrl: sourceUrl(size: MEDIUM)
largeUrl: sourceUrl(size: LARGE)
altText
}
}
}
}
}
}
Standard GraphQL features:
- Standard GraphQL field names (
title,sourceUrl) - Relay-style edges/nodes pagination structure
- Nested node objects for media relationships
- Query variables and fragments support