WP Manifestindependent plugin directory
manifest / integrations / wp-graphql-content-blocks

WPGraphQL Content Blocks #1 in Integrations & APIs

Plugin that extends WPGraphQL to support querying (Gutenberg) Blocks as data

★ 150stars
29krelease downloads
≈3.5kactive sites
v4.8.7latest · 1d ago

Install

Download wp-graphql-content-blocks.zip From the v4.8.7 release on GitHub, Oct 21, 2026

Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/wpengine/wp-graphql-content-blocks/releases/download/v4.8.7/wp-graphql-content-blocks.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

WordPress plugin that extends WPGraphQL to support querying (Gutenberg) Blocks as data.

How to Install

This plugin is an extension of wp-graphql, so make sure you have it installed first.

  1. Download the latest .zip version of the plugin
  2. Upload the plugin .zip to your WordPress site
  3. Activate the plugin within WordPress plugins page.

There is no other configuration needed once you install the plugin.

Getting started

Once the plugin is installed, head over to the GraphiQL IDE and you should be able to perform queries for the block data (This plugin is an extension of wp-graphql, so make sure you have it installed first.). There is a new field added in the Post and Page models called editorBlocks. This represents a list of available blocks for that content type:

{
  posts {
    nodes {
      # editorBlocks field represents array of Block data
      editorBlocks(flat: false) {
        # fields from the interface
        renderedHtml
        __typename
        # expand the Paragraph block attributes
        ... on CoreParagraph {
          attributes {
            content
          }
        }
        # expand a Custom block attributes
        ... on CreateBlockMyFirstBlock {
          attributes {
            title
          }
        }
      }
    }
  }
}

How do I query block data?

To query specific block data you need to define that data in the editorBlocks as the appropriate type. For example, to use CoreParagraph attributes you need to use the following query:

{
  posts {
    nodes {
      editorBlocks(flat: false) {
        __typename
        name
        ... on CoreParagraph {
          attributes {
            content
            className
          }
        }
      }
    }
  }
}

If the resolved block has values for those fields, it will return them, otherwise it will return null.

{
  "__typename": "CoreParagraph",
  "name": "core/paragraph",
  "attributes": {
    "content": "Hello world",
    "className": null
  }
}

What about innerBlocks?

In order to facilitate querying innerBlocks fields more efficiently you want to use editorBlocks(flat: true) instead of editorBlocks. By passing this argument, all the blocks available (both blocks and innerBlocks) will be returned all flattened in the same list.

For example, given the following HTML Content:

<columns>
  <column>
    <p>Example paragraph in Column</p>
    <p></p
  ></column>

  <column></column
></columns>

It will return the following blocks:

[
  {
    "__typename": "CoreColumns",
    "name": "core/columns",
    "id": "63dbec9abcf9d",
    "parentClientId": null
  },
  {
    "__typename": "CoreColumn",
    "name": "core/column",
    "id": "63dbec9abcfa6",
    "parentClientId": "63dbec9abcf9d"
  },
  {
    "__typename": "CoreParagraph",
    "name": "core/paragraph",
    "id": "63dbec9abcfa9",
    "parentClientId": "63dbec9abcfa6",
    "attributes": {
      "content": "Example paragraph in Column 1",
      "className": null
    }
  }
]

The CoreColumns contains one or more CoreColumn block, and each CoreColumn contains a CoreParagraph.

Given the flattened list of blocks though, how can you put it back? Well that's where you use the `` and parentId fields to assign temporary unique ids for each block.

The clientId field assigns a temporary unique id for a specific block and the parentClientId will be assigned only if the current block has a parent. If the current block does have a parent, it will get the parent's clientId value.

So in order to put everything back in the Headless site, you want to use the flatListToHierarchical function as mentioned in the WPGraphQL docs.

Note

Currently the clientId field is only unique per request and is not persisted anywhere. If you perform another request each block will be assigned a new clientId each time.


Querying Object-Type Block Attributes in WPGraphQL

Overview

With this update, you can now query object-type block attributes with each property individually, provided that the typed structure is defined in the class typed_object_attributes property or through a WordPress filter.

How It Works

The typed_object_attributes is a filterable array that defines the expected typed structure for object-type block attributes.

  • The keys in typed_object_attributes correspond to object attribute names in the block.
  • Each value is an associative array, where:
    • The key represents the property name inside the object.
    • The value defines the WPGraphQL type (e.g., string, integer, object, etc.).
  • If a block attribute has a specified typed structure, only the properties listed within it will be processed.

Defining Typed Object Attributes

Typed object attributes can be defined in two ways:

1. In a Child Class (typed_object_attributes property)

Developers can extend the Block class and specify typed properties directly:

class CustomMovieBlock extends Block {
    /**
     * {@inheritDoc}
     *
     * @var array<string, array<string, "array"|"boolean"|"number"|"integer"|"object"|"rich-text"|"string">>
     */
    protected array $typed_object_attributes = [
        'film' => [
            'id'         => 'integer',
            'title'      => 'string',
            'director'   => 'string',
            'soundtrack' => 'object',
        ],
        'soundtrack' => [
            'title'  => 'string',
            'artist' => 'string'
        ],
    ];
}

2. Via WordPress Filter

You can also define typed structures dynamically using a WordPress filter.

add_filter(
    'wpgraphql_content_blocks_object_typing_my-custom-plugin_movie-block',
    function () {
        return [
            'film'       => [
                'id'         => 'integer',
                'title'      => 'string',
                'director'   => 'string',
                'soundtrack' => 'object',
            ],
            'soundtrack' => [
                'title'  => 'string',
                'artist' => 'string'
            ],
        ];
    }
);

Filter Naming Convention

To apply custom typing via a filter, use the following format:

wpgraphql_content_blocks_object_typing_{block-name}
  • Replace / in the block name with -.
  • Example:
    • Block name: my-custom-plugin/movie-block
    • Filter name: wpgraphql_content_blocks_object_typing_my-custom-plugin_movie-block

Example:

Example block.json Definition

If the block has attributes defined as objects, like this:

"attributes": {
    "film": {
      "type": "object",
      "default": {
        "id": 1,
        "title": "The Matrix",
        "director": "Director Name"
      }
    },
    "soundtrack": {
      "type": "object",
      "default": {
        "title": "The Matrix Revolutions...",
        "artist": "Artist Name"
      }
    }
}

This means:

  • The film attribute contains id, title, director.
  • The soundtrack attribute contains title and artist.

WPGraphQL Query Example

Once the typed object attributes are defined, you can query them individually in WPGraphQL.

fragment Movie on MyCustomPluginMovieBlock {
    attributes {
        film {
            id
            title
            director
            soundtrack {
                title
            }
        }
        soundtrack {
            title
            artist
        }
    }
}

query GetAllPostsWhichSupportBlockEditor {
    posts {
        edges {
            node {
                editorBlocks {
                    __typename
                    name
                    ...Movie
                }
            }
        }
    }
}

Contributor License Agreement

All external contributors to WP Engine products must have a signed Contributor License Agreement (CLA) in place before the contribution may be accepted into any WP Engine codebase.

  1. Submit your name and email
  2. 📝 Sign the CLA emailed to you
  3. 📥 Receive copy of signed CLA

❤️ Thank you for helping us fulfill our legal obligations in order to continue empowering builders through headless WordPress.

Releases

Newest 25 of 35 recorded releases. Each count is every asset in that release; expand a row for the breakdown.

Tag
Published
Assets
Downloads
v4.8.7 latest
Oct 21, 2026 1d ago
wp-graphql-content-blocks.zip +2 assets
26
wp-graphql-content-blocks.zip16
schema.graphql9
info.json1
Jul 6, 2026 3mo ago
wp-graphql-content-blocks.zip +1 asset
7,283
wp-graphql-content-blocks.zip7,159
schema.graphql124
May 27, 2026 4mo ago
wp-graphql-content-blocks.zip +1 asset
1,303
wp-graphql-content-blocks.zip1,259
schema.graphql44
Jun 12, 2025 1 year ago
wp-graphql-content-blocks.zip +1 asset
4,861
wp-graphql-content-blocks.zip4,762
schema.graphql99
Apr 29, 2025 1 year ago
wp-graphql-content-blocks.zip +1 asset
1,380
wp-graphql-content-blocks.zip1,352
schema.graphql28
Mar 5, 2025 1 year ago
wp-graphql-content-blocks.zip +1 asset
3,536
wp-graphql-content-blocks.zip3,505
schema.graphql31
Mar 3, 2025 1 year ago
wp-graphql-content-blocks.zip +1 asset
157
wp-graphql-content-blocks.zip146
schema.graphql11
Feb 17, 2025 1 year ago
wp-graphql-content-blocks.zip +1 asset
694
wp-graphql-content-blocks.zip674
schema.graphql20
Feb 11, 2025 1 year ago
wp-graphql-content-blocks.zip +1 asset
292
wp-graphql-content-blocks.zip279
schema.graphql13
Feb 6, 2025 1 year ago
wp-graphql-content-blocks.zip +1 asset
189
wp-graphql-content-blocks.zip181
schema.graphql8
Jan 28, 2025 1 year ago
wp-graphql-content-blocks.zip +1 asset
403
wp-graphql-content-blocks.zip377
schema.graphql26
Jan 14, 2025 1 year ago
wp-graphql-content-blocks.zip +1 asset
334
wp-graphql-content-blocks.zip304
schema.graphql30
Dec 12, 2024 1 year ago
wp-graphql-content-blocks.zip +1 asset
286
wp-graphql-content-blocks.zip266
schema.graphql20
Nov 14, 2024 1 year ago
wp-graphql-content-blocks.zip +1 asset
221
wp-graphql-content-blocks.zip206
schema.graphql15
Nov 11, 2024 1 year ago
wp-graphql-content-blocks.zip +1 asset
37
wp-graphql-content-blocks.zip28
schema.graphql9
Sep 19, 2024 2 years ago
wp-graphql-content-blocks.zip +1 asset
918
wp-graphql-content-blocks.zip879
schema.graphql39
Aug 14, 2024 2 years ago
wp-graphql-content-blocks.zip +1 asset
564
wp-graphql-content-blocks.zip487
schema.graphql77
Jun 25, 2024 2 years ago
wp-graphql-content-blocks.zip +1 asset
842
wp-graphql-content-blocks.zip801
schema.graphql41
Apr 9, 2024 2 years ago
wp-graphql-content-blocks.zip +1 asset
777
wp-graphql-content-blocks.zip735
schema.graphql42
Feb 28, 2024 2 years ago
wp-graphql-content-blocks.zip +1 asset
1,349
wp-graphql-content-blocks.zip1,243
schema.graphql106
Feb 28, 2024 2 years ago
wp-graphql-content-blocks.zip +1 asset
21
wp-graphql-content-blocks.zip12
schema.graphql9
Feb 28, 2024 2 years ago
wp-graphql-content-blocks.zip
12
Feb 5, 2024 2 years ago
wp-graphql-content-blocks.zip +1 asset
428
wp-graphql-content-blocks.zip416
schema.graphql12
Oct 12, 2023 3 years ago
wp-graphql-content-blocks.zip +1 asset
1,948
wp-graphql-content-blocks.zip1,871
schema.graphql77
Oct 4, 2023 3 years ago
wp-graphql-content-blocks.zip +1 asset
138
wp-graphql-content-blocks.zip127
schema.graphql11
All releases on GitHub →

Active-site estimate ≈3,510 comes from the median of recent superseded releases. Method.