Skip To Main Content

How to Migrate From wp-graphql-gutenberg

In this guide we provide a list of recommended steps to migrate any blocks you have developed from wp-graphql-gutenberg plugin to wp-graphql-content-blocks plugin.

What is wp-graphql-gutenberg?

As explained in this tutorial, it’s an extension for WPGraphQL that adds the blocks to the WPGraphQL schema just like the wp-graphql-content-blocks.

However there are some key differences that you need to 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 in the screen.

So due to the lack of Introspection and unpredictability and in order to promote best practices, we do not expose the block data as plain JSON.

What we instead propose is to use GraphQL types to retrieve associated block attributes and fields.

The effort required to add block fragments is not very high. If you follow the recommended approach of co-located fragments you can just 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 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
        }
      }
    }
  `,
};
Code language: JavaScript (javascript)

If you followed one of our the tutorials for creating a new block from the WordPress Core Blocks you just need to add the following fragment as a new property:

CoreCode.fragments = {
  key: `CoreCodeBlockFragment`,
  entry: gql`
    fragment CoreCodeBlockFragment on CoreCode {
      attributes {
        anchor
        backgroundColor
        content
        className
        gradient
        style
        textColor
      }
    }
  `,
};
Code language: JavaScript (javascript)

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 may have 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}>
}
Code language: JavaScript (javascript)

If you are not satisfied by the way WordPressBlocksViewer passes on the properties, you can open a new Feature Request so that the Faust team can review it.

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 seperate fields previewBlocks and previewBlocksJSON. If you want to preview posts or pages, you should be using the Faust.js Previews mechanism.
  • 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.
    • clientIdparentClientId: Unique identifiers for the block and the parent of the block.