Custom Content Types in Headless WordPress

Matt Landers Avatar


When you build a headless site, you are dependent on an API to provide structured content to the frontend from the CMS. The frontend takes the content and decides how to display it to the user. But how the frontend shows that content comes in different forms. Content producers used to render posts in HTML because they need more control over how the content looks. But for other content types, such as employees on a team page, you should structure content. The frontend takes the structured data and renders it to the user according to the design.

All headless CMSs allow you to create structured data via custom content types, but how do we do this in WordPress? Through the power of the plugin ecosystem, of course! With a few plugins, we can create a good experience for the content producer to enter structured data. The plugins that we’ll need are:

  • WPGraphQL
  • Custom Post Types UI
  • CPT extension for WPGraphQL
  • Advanced Custom Fields
  • ACF extension for WPGraphQL

With these plugins, we can create a UI in WordPress that looks like this:

Add new team member UI

Let’s walk through the steps needed to create this UI.

Create the Custom Post Type

The first thing we need to do is create a custom post type. We can do this with the CPT UI plugin. Click CPT UI in the menu. The following interface appears:

For our team members’ post type, we can use “teammembers” for Post Type Slug. “Team Members” for the plural label and “Team Member” for the singular labels. Add the labels in the WP admin in the navigation bar and editor for team members.

Scroll down to the bottom of the page, and you’ll see a section for WPGraphQL that looks like this:

We need to tell WPGraphQL what to call the entity in the schema for plural and singular. Use this syntax for your queries. For Single Name, use “teammember”, and for Plural Name, use “teammembers”.

To put the finishing touches on our editing experience, turn off Featured Image and Editor.

  1. Scroll up just a bit, and you’ll see a list of supported items.
  2. Unselect Editor and Featured Image.

Now, you can click Save Post Type. At this point, you’ll see “Team Members” in the side navigation. If you click it and add a new team member, you’ll only see the title in the editor. We need more than a title, so let’s add custom fields to the post type.

Add Custom Fields

In the side navigation, click Custom Fields. A list of field groups appears. Click Add New to start creating a new custom field group.

First, we need to give the field group a name. This can be whatever will help you identify the field group. Let’s call it “Team Member Fields.” Next, we need to let ACF know where we want to apply these fields. We can do this in the Location section. The field group should not show up on every post because it is specific to team members. We only want to show the field group when the post type is equal to “Team Member.”

Now that we set the location, we need to add custom fields to the field group. Click the + Add Field button. The following screen appears:

Let’s add a field for a description of the team member. Enter “Bio” as the Field Label, and the Field Name will be auto-populated with “Bio”. The Field Name is what we will use in our GraphQL queries.

A bio will likely be more than one line, so let’s change the Field Type to “Text Area.” The Field Type determines how the user will enter the data, and the Text Area will give the user a multi-line input box.

There are other options like required and instructions that you can fill out, but make sure that Show in GraphQL is selected. If we don’t turn that on, we won’t query the field from GraphQL.

There are other options like required and instructions that you can fill out as well, but the one option we need to make sure is slected is “Show in GraphQL”. If we don’t turn that on, we won’t be able to query the field from GraphQL.

We’re going to use Title for the name field. That way, when we view the list of Team Members, we will see them listed by name. You could also create a name field, but it would be redundant for the user that enters the team members.

Once you’ve added all the fields you want on a team member, please scroll down to the bottom of the page and make sure you have Show in GraphQL selected and provide a GraphQL Field Name, the name used when we query team members. Let’s name it “acfTeamMembers”.

Finally, scroll back to the top of the page, and click Publish. Once published, click on Team Members in the navigation and add a new team member. You should see the title field and all the custom fields you added. ????

Next, let’s query our custom content type with WPGraphQL!

Query Custom Content Types

At this point, you should have a custom content type for team members in WP admin. Make sure you add a few team members before going any further to see the GraphQL query results, then open the GraphiQL IDE via the top navigation.

To build the query, use the schema explorer on the UI’s left side and find the “teammembers” entity. Expand it and select the fields you want to query. GraphiQL will modify the query in the editor to match what you choose. Run the query by pressing the play button above the editor. Here’s an example query, but it may be different depending on the fields you added.

  teammembers {
    nodes {
      acfTeamMembers {

And that’s it! Now, you can query team members from anywhere you need the data and get back structured data just like you defined it.