Skip to main content
DocsExplanationMigrate from wp-graphql-gutenberg

Migrate From WPGraphQL Gutenberg

With wp-graphql-gutenberg being sunset you may find yourself needing to move to the improved wp-graphql-content-blocks plugin.

What's the difference?

Both plugins extend WPGraphQL to add support for blocks (aka. Gutenberg) to the WPGraphQL schema.

However, there are some key differences that you should be aware of:

  • WPGraphQL Gutenberg gets the blocks registry and sends it in a network request to the WordPress PHP application. So it needs to be synced from time to time.

  • It also allows the blocks to be served as JSON using the blocksJSON field. If requesting data this way, the data is not typechecked and you may overfetch data as a side effect.

  • Block attributes are using their own types, containing different type for deprecated versions. For example:

...on CoreParagraphBlock {
    attributes {
        ...on CoreParagraphBlockAttributes {
            content
        }
        ...on CoreParagraphBlockDeprecatedV1Attributes {
            content
        }
    }
}
  • It does not allow blocks to be returned as a flat list so you have to use deeply nested queries to get the list of innerBlocks (and this won’t nearly solve the issue 100%).

  • wp-graphql-content-blocks does not save anything in the database (this is actually a good thing) compared to wp-graphql-gutenberg. Therefore it only supports previews when the “preview” button is hit in the editor.

How do I migrate a block from wp-graphql-gutenberg?

To answer this question you will have check how you queried the blocks using wp-graphql-gutenberg. There are two different cases that you have to consider here:

You used the blocksJSON property to get the blocks data

The wp-graphql-content-blocks plugin does not expose the blocksJSON fields, because it is problematic to do so. Getting the data as plain JSON directly from the database completely overrides the principles of GraphQL and ignores the type safety of the system. If one of the properties is altered, you have no guarantee that the GraphQL server will catch them. Plus, most of the times you will over fetch data leading to slower queries, especially if you have lots of content on the screen.

So, due to the lack of Introspection, unpredictability, and in order to promote best practices, wp-graphql-content-blocks do not expose the block data as plain JSON. Instead, it is recommended to use GraphQL types to retrieve associated block attributes and fields.The effort required to add block fragments is not high. If you follow the recommended approach of co-located fragments, you may add them as properties to each of your block expected attribute list and make sure that you include those into the page query string.

Take a look at the following example taken from WebDevStudios nextjs-wordpress-starter. It shows an implementation of the CoreCode block using wp-graphql-gutenberg and getting the data using blockJSON.

With it, you would have to create a fragment like this:

CoreCode.fragments = {
  key: `CoreCodeBlockFragment`,
  entry: gql`
    fragment CoreCodeBlockFragment on CoreCodeBlock {
      attributes {
        ...on CoreCodeBlockAttributes {
          anchor
          backgroundColor
          content
          className
          gradient
          style
          textColor
        }
      }
    }
  `,
};

Based on the creating a custom block guide from the WordPress Core Blocks you just need to add the following fragment as a new property:

  key: `CoreCodeBlockFragment`,
  entry: gql`
    fragment CoreCodeBlockFragment on CoreCode {
      attributes {
        anchor
        backgroundColor
        content
        className
        gradient
        style
        textColor
      }
    }
  `,
};

When the WordPressBlocksViewer renders the component, it passes the whole block data as a property of that block. If your block is designed to accept different properties for attributes and for innerBlocks you have to create a wrapper to forward the properties into the right slots:

CoreCode.js
export default function CoreCode({attributes, children}) {
    const BlockCode = dynamic(() => import('@/components/blocks/core/BlockCode'))
    return <BlockCode {...attributes} innerBlocks={children}>
}

You used the block field with GraphQL types and fragments

If you were using the block field from the wp-graphql-gutenberg then most of the component fragment queries should be the same with the following exceptions.

You should be querying the block attributes without qualifying their type:

Before:

...on CoreParagraphBlock {
    attributes {
        ...on CoreParagraphBlockAttributes {
            content
        }
    }
}

After:

...on CoreParagraphBlock {
    attributes {
        content
    }
}

There are no separate fields previewBlocks and previewBlocksJSON. If you want to preview posts or pages you should be setting the asPreview boolean to true for the post/page in your GraphQL request (this is how Faust.js previews work under the hood).

The base interface for each block contains different fields, so you need to make sure your queries use the valid ones from this list:

  • renderedHTML: It’s the HTML of the block as rendered by the render_block function.

  • name: The actual name of the block taken from its block.json spec.

  • __typename: The type of block transformed from the name field in camel-case notation.

  • apiVersion: The apiVersion of the block taken from its block.json spec.

  • innerBlocks: The innerblock list of that block.

-isDynamic: Whether the block is dynamic or not, taken from its block.json spec.

  • clientId, parentClientId: Unique identifiers for the block and the parent of the block.