Skip to content
Merged
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"faustjs",
"faustwp",
"heroicons",
"innerblock",
"Kevinbatdorf",
"lastmod",
"recma",
Expand All @@ -14,7 +15,8 @@
"shikijs",
"sindresorhus",
"stylesheet",
"tailwindcss"
"tailwindcss",
"wpgraphql"
],
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
Expand Down
153 changes: 153 additions & 0 deletions src/pages/docs/explanation/migrate-from-wp-graphql-gutenberg/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
export const metadata = {
title: "How to Migrate From WPGraphQL Gutenberg",
};

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

## What is wp-graphql-gutenberg?

As explained, 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:

```gql
...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](https://github.com/WebDevStudios/nextjs-wordpress-starter/blob/main/components/blocks/core/BlockCode/BlockCode.js).

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:

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

If you followed one of our the tutorials for [creating a new block](insert-url-here-when-ready) from the WordPress Core Blocks you just need to add the following fragment as a new property:

```gql CoreCode.fragments = {
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:

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

If you are not satisfied by the way `WordPressBlocksViewer` passes on the properties, you can open a [new Feature Request](https://github.com/wpengine/wp-graphql-content-blocks/issues/new) 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:**

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

**After:**

```gql
...on CoreParagraphBlock {
attributes {
content
}
}
```

There are no separate fields `previewBlocks` and `previewBlocksJSON`. If you want to preview posts or pages, you should be using the [Faust.js Previews mechanism](/docs/how-to/post-previews).
.

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.
4 changes: 4 additions & 0 deletions src/pages/docs/nav.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@
{
"title": "Deploying Your App",
"route": "/docs/explanation/deploy-your-app/"
},
{
"title": "Migrate from wp-graphql-gutenberg",
"route": "/docs/explanation/migrate-from-wp-graphql-gutenberg/"
}
]
}
Expand Down