DE{CODE}: Gutenberg and Headless WordPress
Gutenberg, aka WordPress blocks, gives content producers powerful new ways to lay out content in a traditional WordPress site. But how can headless WordPress developers empower marketing teams with those same capabilities?
In this DE{CODE} session, the founder of GraphQL for WordPress (WPGraphQL), Jason Bahl, shares new capabilities and best practices for using the WordPress block editor on a headless site.
Session Slides
Full Text Transcript
JASON BAHL: Hi. Welcome to my talk on Gutenberg and Headless WordPress. My name is Jason Bahl. I’m the creator and maintainer of WPGraphQL. I’m a principal software engineer at WP Engine. You can find me on Twitter @jasonbahl or also on Twitter @wpgraphql.
So today, I want to talk to you about what Gutenberg even is, headless WordPress is, when and why you might want to use Headless WordPress, how you can use Gutenberg, specifically, with Headless WordPress, and when and why Headless WordPress and Gutenberg together might make sense for your projects.
So WordPress historically has had an editor that looked a little bit like this. We’ve had a TinyMCE text area, where we can edit our content. We can insert media and then publish our content and then in 2018 came Gutenberg, this block-based editor, that allows us to insert content into this blank canvas and interact with our content at the block level.
So each paragraph has settings. Each image has settings. Each gallery, heading– anything you can think of for content is what’s called the block. And we can get really granular with how we control our content now and we can drag and drop it and compose our content. So it’s this very rich editing experience in WordPress now and so it’s primer on what Gutenberg is.
So what is Headless WordPress now? So to understand Headless, let’s look at traditional WordPress. So traditional WordPress, we log into WordPress, the admin UI, and we publish our content and then users visit our site, and PHP, the language WordPress has built in, renders the page. So it loads CSS, HTML, and JavaScript and delivers the page to the user. So that’s kind of traditional WordPress.
With Headless WordPress, you still use WordPress as the CMS. You still publish content, curate content, administer content in WordPress, but instead of delivering a page in HTML to the browser, WordPress delivers data typically in JSON format, and then client applications can consume that data so we can have native iOS or Android applications or even virtual reality applications.
My colleague, Anthony, has shared content on how he’s using WordPress to power virtual reality applications. Or I worked at a newspaper where we used WordPress as the entry point for our print newspapers. So if you were reading a hard copy of printed newspaper, you were reading content produced in WordPress.
And of course, we can still use that data to render to the web as well, but instead of being locked down to PHP templating, we have flexibility to choose whatever front-end end technology that we want. So Headless decouples the back end, the management of content, and how we present the data that’s managed in WordPress.
So there’s two common ways we can use this data. We can get data in JSON format from the WP REST API, which is a built-in API to WordPress and there’s another API called WPGraphQL. This is an open-source plugin that you can install and get data out of WordPress and JSON. And we’ll be talking about WPGraphQL today.
So now that we know what WordPress is, why might you go and build Headless WordPress projects? Like I mentioned, you have a lot of flexibility with choosing your front-end tech. And to some people, that’s a very important thing being able to choose how they build the front-end projects. There’s some frameworks like Next and Gatsby and Svelte that really target improved core web vitals. So you might be able to go Headless with WordPress and have improved core web vitals.
You can benefit from things like code splitting in your code. So you can build components for your front-end application. And based on what component is being built out for the specific page will send lower or less assets to the client and speed up your pages. Headless also gives developers more fine control over the front-end user experience, so plugins that are installed in the WordPress admin, have less of an impact on the front-end
So admin users can’t just install plugins and have arbitrary scripts or arbitrary markup added to the front-end of a Headless site. It’s more a developer defines the constraints on the front-end and WordPress gets the data sent over and then one of the things I want to key in is developer experience.
With Headless WordPress, since you have the flexibility to use whatever tech stack you want, there is a benefit of better developer experience in some cases. And one of those cases I’m going to get into is called component-based development and we’ll talk a lot about that in a second.
So that’s some reasons why. So what situations might you be in when you want to use Headless WordPress? Well, if you need to build non-web applications like native mobile, you probably want to go to Headless. Again, if your core web vitals are poor on your WordPress site, your current WordPress site, or they’re OK, but it’s getting very costly to keep them good, you might want to consider Headless.
If you have multiple applications in your organization that need to get data out of WordPress, you might need to go Headless as well. And if you’re already invested in a component library, or component-based design system for your organization and you need data from WordPress, you might want to invest in going Headless. If a team prefers JavaScript and does not like building things in PHP, that’s also a reason to consider Headless.
Some reasons you might not want to go Headless, though– currently, it does take a little bit extra development time. So if you have a lower budget or scale back time and you already have solutions in traditional WordPress, you might not go Headless yet. If your site admins really need control of installing plugins that modify the front-end you might not go Headless yet.
If your team really prefers PHP and doesn’t want to learn JavaScript or alternative front-ends you might stick with traditional WordPress as well. And if you’re not invested in a component-based development or component-based library, if you have no interest in that, you might stick with traditional WordPress development workflows.
And if your core web vitals on your traditional WordPress are really good, and your maintenance costs are very low to keep your website running very fast, you might be OK to stick with traditional WordPress. So you don’t have to go Headless. But I’m going to show you why I think going Headless can be good for some teams.
So if we look at the WordPress developer experience again, we publish our content in one field that generates a big chunk of HTML. And even if we’re using the Gutenberg editor, which has these granular blocks, the end result is one big chunk of HTML. And so whether we publish in Gutenberg or the traditional classic editor, this chunk of HTML gets sent through PHP to our theme and we have one global page that loads our HTML, our CSS, and our JavaScript. And these assets are applied to the page globally.
So WordPress developers will typically decouple our development based on file types, so we will put our CSS in separate files that are applied globally to the page, or HTML will be written in PHP, and pulling the data we need from WordPress and then JavaScript will be written often times with jQuery in separate files. And so these three things will come together to build the page.
Problem is these aren’t isolated they’re applied to the whole page. So sometimes you can make a change. Like this happened to me. One time I made a change to a style in the footer of a site as requested by my manager and three days later, it was reported that style somewhere else on the site had changed because of that pass code review. We passed it.
All of a sudden, something else on the site was broken and this because CSS is applied globally and might impact things you don’t realize. There’s a new trend, though, over the past– I don’t know– seven, eight years maybe called component-based architecture. This allows us to build specific pieces of our application in what’s called components.
And we can couple our JavaScript, our HTML, our CSS in small bits that we can test in isolation and so we can build pieces of our application. Couple of concerns, the markup, the JavaScripts, the styles, and we can compose these components together to build more complex applications.
And so component-based development allows us to break complex features into smaller isolated pieces and we can test them in isolation, make sure they’re working and then we can couple our concerns that should be coupled. Every slice of UI has specific responsibility. If it’s an image card, it might be responsible for rendering the image at a certain size with a specific URL.
So it has markup dependencies. It has style dependencies. It might have stateful interactions. These are all concerned with that specific component. So we can couple our markup, our JavaScript, and our CSS in one place, test it, and make sure it works well. And because of this, we can then reuse these components throughout our application, or we can even reuse our components across projects.
So there’s a trend called component libraries. There’s projects like Material UI, or end design components, or Chakra UI is a popular one as well. And we can use these components across projects. And we can solve central concerns like accessible markup. And we can make updates to those and apply those across multiple projects in our organization at once and because of this– because of these reasons, we can iterate and ship faster often with a lot more confidence.
So how can we use Headless WordPress then? Like I mentioned before, there’s kind of two ways to get data out of WordPress and into components. One would be the REST API. One would be WPGraphQL. My friend, Drake, has been building Headless sites for a while, so I asked him and this is what he said…
He prefers WPGraphQL. So that’s what we’re going to talk about today. So what is WPGraphQL? You might ask. Well, it’s a free open-source WordPress plugin that provides an extendable GraphQL schema and API for any WordPress site. What’s GraphQL then? Well, it’s a graph query language.
All right, Jason. I still don’t understand what you’re saying. All right, so let me show you. So GraphQL, the way it works is that client applications send a request specifying what they want from the server. And a request looks something like this. It looks like JSON keys without values. So in this case, the request is asking for the viewer and on a viewer, we want the “name” field returned.
And a response from the GraphQL server might look like this. Its actual JSON data, keys and values and it matches the shape of the request. So in this case, we get the name, or we get the viewer with the name Jason Bahl. So GraphQL let’s client applications pluck trees out of the application data graph.
And what that looks like visually is something like this. We can enter the graph, let’s say, add a viewer or user field or a node. And that node might have a property like a name Jason. And that node might have connections to other nodes in the graph like an avatar, which might have a property like an image URL.
And that user might have connections to other nodes like post that that user has authored. And those posts might have properties themselves like a title, hello world, or goodbye Mars. And these posts might have connections to other nodes in the graph, such as categories with their own titles like news or sports. And those categories might have connections to other nodes as well like more posts. And those posts might have featured images and so on and so forth. So we have this big graph of data that we can ask for pieces of with GraphQL.
And so we can use tooling in the GraphQL admin or in the WordPress admin. There’s a tool called GraphiQL, where I can compose a query. And here I’m selecting the Viewer field with subselections, name, avatar, the URL and when we execute that, we get the fields we ask for and so visually that query looks a bit like this.
We entered the graph and we asked for one user. We asked for the user’s name, the connected avatar in the avatar’s URL. We have all of this graph of data available to us, but we only ask for a specific set of data and in response, we got that specific set back. And so then we can take– we can now use components.
So I talked about the benefits of component-based development, and I want to show you this in action. And so this is what I would call a presentational component. So this is a card component that is responsible. It has one responsibility for rendering this card with an image and a title.
And we can look at the code and we see we have some style control. We can set the width, we can pass it the image we want and we can pass it the title. So we can reuse this component throughout our project. And this component has all the dependencies we need. It has the HTML to render. It has the styles. We have some style control in here. It has some stateful components like the hover state and whatnot.
So this is an isolated component that we can reuse and with GraphQL now, we can take the query that we just composed in the WordPress admin using GraphQL and we can bring that in and have a viewer card component now. So we can write our query, couple it with our card component and now it completes the component.
We have our HTML, CSS our JavaScript. And because of the data, we now have something to render with the data that we asked for. So now we can use this throughout our application and there’s a feature of GraphQL called fragments and this allows us to take our GraphQL queries and break it into reusable pieces.
So in this case, I’m creating a user profile card fragment, and I’m specifying name, avatar, and URL and then I’m using that fragment in a bigger query. When we execute, we get the results we expect. We can now take that fragment, put it into a component. Now we have a different component called the User Profile Card.
This user profile card specifies that any time we query a user, we should get the name, the avatar, and the URL of the avatar to use in the component. So now we have this reusable component that anywhere in our application we ask for a user, we can get the data necessary to render this reusable card with the avatar and the name of the user.
And so this can now be brought in and used in bigger parts of our application. So here’s the query we had before the viewer query using the fragment that we’re importing from a reusable user profile card component. And then we’re outputting it in to a viewer card component and now we can reuse this across our application.
We can make bigger parts of our application that rely on this user card or the author card. So we can now have multiple components like blog title component that’s responsible for the title. We can have a user profile card that we just created that renders the user’s profile. We can have a content or excerpt component that’s responsible for the markup and the data for this part of our application.
And yes, we can build these small components that are responsible for the markup, the CSS, and the data needed to build this application. And we can compose them together. We can test them in isolation, also test them as bigger units. So we can use this in various templates as well.
We can use these reusable components for a blog post or our blog role where we have different authors, but we can use the same component to render them. We can use it for– the other archive page. So very similar to WordPress template parts, we can break up our Headless applications into small pieces but we get the benefit of coupling our technology together.
So that’s a little bit about Headless WordPress developer experiencing component-based design and benefits of that. So now when it comes to Gutenberg, specifically, why would you consider Headless WordPress with Gutenberg specifically? Well, if your team is already using Headless WordPress, possibly with Advanced Custom Fields and flexfields, and you want to update the editor experience to use Gutenberg, that’s obviously one reason you might go Headless with Gutenberg.
If you want to benefit from building components that are used in the admin and components that are used in the front-end it’s a good reason to consider going Headless with Gutenberg because the Gutenberg back end editor of the block editor is all component based. You might want to take advantage of structured input. each block in the admin has fields that are structured.
You have specific attributes that you can control on the field level. And you might want to benefit on having that structured output coming to your components as well. And like I mentioned, you might want to reuse components and blocks across projects. Like, you might want to have a block library that your agency has built that solves things like accessibility and specific markup concerns that you want to use across projects. And then you can update those across your projects, not just within one individual project.
So this is a part where like child themes in WordPress can be difficult to scale because you have to go to every single site to and update the markup and whatnot on every single site. Well, here, you can use block libraries as NPM dependencies and update them across your organization.
So currently, the state of WordPress development with Gutenberg is that we have blocks on the backend, which are component-based. We can build our own custom blocks or use core WordPress blocks. But the output in PHP is, like I mentioned, that one big chunk of HTML and so how can we transition from getting this one block of HTML to having components on the backend that also transfer to components on our front-end?
So we’re going to look at some options to get Gutenberg data out of WordPress and into components. So one option is to get content as HTML. So we can query our WordPress content as HTML and then parse that HTML to components. Or we can query blocks as GraphQL types. So we can– that allows us to query a list of blocks, each block would be a GraphQL type that we can map to a component.
So the content is HTML. This is something we can do in WPGraphQL core today. If you want to query blocks as individual GraphQL types, there’s two options at the moment. We have GraphQL for Gutenberg extension, which is community extension and then we have WPGraphQL Block Editor, which is a beta plugin that I’m working on personally.
And so let’s look at these options. In WPGraphQL core, we can query content as HTML and parse to components. What that looks like is we query something like a post, and we can ask for fields like ID and title or content. And the content is going to return one big string, one big chunk of HTML and then we can parse that HTML and map different DOM nodes to different components.
Like in this case on wpgraphql.com, the link over on the left is to the code where this is actually happening. I take the markup that is returned from WPGraphQL, and I parse it, look for specific HTML nodes and convert it to React components. So I can have interactive things like this code block, which does the syntax highlighting and allows users to click Copy and then I can also parse and create a table of contents, for example. So that’s one approach. And I’m using it in wpgraphql.com in production today.
Some things you might want to consider if you go this route, HTML payloads can be unpredictable. Changes in the server like installing a new block library or various HTML that editors can put into content, they’re unpredictable. So it could be very hard to parse. You can’t interospect the changes. As a client developer, you can’t see what changed, so just something to consider.
I would say that this approach works best for teams that have very tight control over the WordPress admin and the front-end. So if you’re a single person or a small team that’s working on the WordPress backend and the front-end, it might work OK for you because you can control the input and the output a little bit better.
One of the other options, WPGraphQL for Gutenberg, this is a community-maintained plugin. And this will allow you to query content blocks, each block as their own GraphQL type. The way this works is a settings page, you have to go in just the blocks as the schema, so this opens Gutenberg in an invisible iframe, gets the block registry from the JavaScript client and sends it to the server.
And then we can use GraphQL to query our blocks as specific types, and we can use fragments like I showed earlier and we can use these fragments to map to components on our front-end. So this is one option. Some considerations with this plugin, changes to the block registry are introspectable so that’s a good thing.
Teams working on the front-end application can use GraphQL introspection to see how the schema changes over time and they can know if there’s breaking changes or new fields that they can consume. I would say this approach works a little bit better for multi-person or multiple-team projects. If you have one team that works on the WordPress admin and a different team that works on the front-end, this approach might work better. They can use the GraphQL schema as a contract between the blocks that are being used on both sides.
One thing that’s a little interesting is that it loads blocks in the iframe like I mentioned. And because of this, it doesn’t always scale for every situation. So if you register blocks to a specific page or a specific template or a specific post type, this method of getting the block registry map to the schema might miss out on some blocks. So it might not scale for every project.
So the next project, WPGraphQL Block Editor, this is a beta plugin that I’m working on currently. And this also allows you to query content blocks as their own GraphQL type and so very similar to WPGraphQL for Gutenberg, we can write fragments that return the data we specify. And then we can use those fragments with our components on the front-end.
Some considerations with this, it is a beta plugin, so there’s that. You do benefit from structured input and structured output. So as the front-end developer, that’s a win for sure. It does work with blocks that are registered with block.json file. So core WordPress Gutenberg blocks do have this file and so this will work with that approach. A lot of third parties don’t register their blocks this way, so you would have to manually map those blocks.
Blocks are not treated as individual nodes. I would like to treat blocks as individual nodes, but there’s not a global ID, so you have to access those blocks as parts of bigger objects like a poster page.
So I hope you learned something about Headless WordPress, the benefits of Headless WordPress, and using Headless WordPress with Gutenberg. I invite you to try WPGraphQL today. You can sign up for a free Headless WordPress Sandbox account at wpengine.com/atlas. And thank you for joining my presentation. Again, you can find me on Twitter, jasonbahl, or also on Twitter @wpgraphql. Thank you.