When the burden of rendering is removed from WordPress, it becomes an open source API platform. With a few plugins like WPGraphQL, you can create an extensible backend for your React apps to consume which enables modern architectures and development practices in WordPress.
API-first Development with Headless WordPress
AI Generated Video Summary
This Talk discusses API-first development with headless WordPress, highlighting its benefits and the availability of resources. It explores the use of plugins and frameworks like WPGraphQL and the headless framework from WP Engine to create custom post types and make GraphQL calls. The Talk also covers building websites, querying and caching data, deploying apps with the Atlas platform, and improving user experience. It touches on authentication, efficiency, backend resources, and WooCommerce integration in headless WordPress, as well as WordPress accessibility and SEO optimization.
1. API-first development with headless WordPress
Hello, React Summit. In this session, we'll talk about API-first development with headless WordPress. WordPress is a great choice for API development because it's widely used, free, and open source. It's also great for headless development and you don't need to know PHP. We have resources available on GitHub and developers.wp-engine.com. Let's dive right in and build a site that lists developers on Twitter based on their language.
Hello, React Summit. I'm Matt Landers, head of developer relations at WP Engine. And in this session, we're gonna talk about API-first development with headless WordPress. So our agenda is really simple. I'm gonna do some talky talk, I'm gonna talk to you a little bit about what we're gonna do, and then we're gonna do a demo.
For this session, there's a few resources that are available to you. The code that I'm going to be using and deploying in this session can be found on my GitHub at matt-lander or slash followa.dev repository. The framework that we're going to be using for headless WordPress is from WP Engine. So if you go to the WP Engine GitHub, you'll see a headless-framework open source project. That is what we're going to use to kick off our projects in getting going. You can also go to developers.wp-engine.com and get a ton of resources from me and my team on headless WordPress and how to do specific things. Let's dive right in and do API development with WordPress. For this demo, we're going to build a site that lists out different developers on Twitter that we can go follow. We want to be able to find developers based on the language that they typically use because if I'm a developer and I want to follow another developer, I'm probably looking for somebody that works in the language and frameworks or technologies that I know so that I can get more information and learn more about it. That's what we're going to build on the site. We're going to use headless WordPress to be the platform that we use for our API and also where our users will be able to go in and enter in the data for the website. What I've done is I've used Local to spin up a WordPress site on my local machine.
2. Developers and GraphQL
You can use LocalWP.com to quickly spin up WordPress sites and work on them locally. Install the WPGraphQL plugin for a better API experience with WordPress. The Custom Post Type UI and Advanced Custom Fields plugins turn WordPress into an API building platform. With the headless framework from WP Engine, we can make GraphQL calls and get structured data about developers. Let's create a custom post type for developers and configure it to show up in GraphQL.
You can get this at LocalWP.com. It's really great for quickly spinning up sites in WordPress and working on them locally. Then you can push them up somewhere live.
All right. So I've already got this running and I also have some plugins that I always use already installed. The number one plugin that I always use is WPGraphQL. You've got to have that because you need a nice API whenever you're going to work with WordPress. There is a REST API already but I find it much easier to use a GraphQL API, especially since there are so many relationships in our data.
There's also two other plugins that really turn WordPress into an API building platform. That would be the Custom Post Type UI and Advanced Custom Fields. There's also extensions for those two for WPGraphQL that I have installed as well, and I have the headless framework from WP Engine installed as well, which is a plugin.
Let's look at what that gives us first. If we go to the GraphQL playground here, we'll see that we can make GraphQL calls straight into our data and get content out. By default, WordPress has Posts and Pages. This content comes out as raw HTML as we can see here. On the front end, and from an API, that's not really what I want to get all the time. For instance, in this case, I want to get a list of developers and some structured data about them. I want to build an API that's going to give me the data back on the front end that looks the way I want it to look.
So, let's do that. The first thing that we're going to do is create that custom content type, which in WordPress is called a custom post type. We're going to call it developers, and our plural label will be developers and developer. We'll see why we need that in just a second. We'll scroll down and we're going to get rid of some of the default things that show up on this post. We only want the title, and we want this to show up in GraphQL. So, I got to tell it how I want it to show up in GraphQL. I'm going to add that post type. As soon as I add that, you'll notice that there's a developer section in our menu now, which is cool. So, now I have a way that I can go and see the developers that I've entered. Now I've had some from previously, and they show back up. So I don't want to have to enter those in again.
3. Adding developer fields and custom post types
But if I click one, I can only see the name. This isn't very useful, right? So now, we can go over to our graphical editor and we could pull these out. Oh, we could say developers and just grab the title. And we can get that data out now. So we have the title, but we need more data than this. We need to pull out, we want there GitHub, their Twitter handle, all of those things. So let's go ahead and add those. So we go to custom fields.
But if I click one, I can only see the name. This isn't very useful, right? So now, we can go over to our graphical editor and we could pull these out. Oh, we could say developers and just grab the title. And we can get that data out now.
So we have the title, but we need more data than this. We need to pull out, we want there GitHub, their Twitter handle, all of those things. So let's go ahead and add those. So we go to custom fields. And we say developer fields. You can name that whatever you want. And then I only want these to show up on that developer custom post type, I don't want to show up on my blog posts or my pages, I only want them to show up on my developer custom post type. And then we can just add fields really simply. So I'm going to add a name, and I want that to show up in GraphQL so I make sure I have that checked here. I also want to add Twitter. So I want their Twitter handle, that's just going to be text as well. Now I also want to know what languages they work in. So languages. And we'll do a taxonomy. So in WordPress, taxonomy are things like tags or categories. And for this, we're going to use tags to do this. We also want to get their personal blog. This will be a URL. And we'll see how that comes into play in a minute. And we want their GitHub. Again, another URL. And that should be good. All right. So we're going to go down at the bottom here, and we want to make sure this shows up in GraphQL again. And I usually prefix the field group name with ACF and my developer, whatever I want to call it. All right.
4. Building the website and pulling data from the API
We'll go back to the top and we will publish this. Now look, we have all of these fields and a nice editor for someone to come edit. We're pulling all of that data out in a nice structured way. We're not getting raw content like we did with a post, we're getting real content like we would expect from an API. The next step is to go build the website. So let's go do that.
We'll go back to the top and we will publish this. Now let's go over to our, go back to our editor. And now look, we have all of these fields and a nice editor for someone to come edit. So I could come in here and say, well, I know that Will also knows C-sharp. So I'll add a new tag here. And call that. He doesn't have a blog. And then we're good, we can update that. So now I have a nice editor. I can go add a new developer and add all that in. And then we want, now what I'm going to get is a nice API, right? So if I go to my graphical IDE, I can now pull all of these out. Name, and we can scroll down over here as well. And we'll see that they're going to show up in that ACF developer group. You know, there's GitHub, name, personal blog, Twitter, what languages they have, so let's run this. Alright, pretty cool. So now we're pulling all of that data out in a nice structured way. We're not getting raw content like we did with a post, we're getting real content like we would expect from an API, right? We can even rename this, so we'll just give it an alias, call it data instead of ACF. Now we've got something nice that we can use in our website. So the next step is to go build the website. So let's go do that.
5. Using the Headless Framework and Making Queries
For the site, we're using the headless framework from WP Engine, which makes connecting to WordPress and pulling down content easy. The project is set up and the site has been customized. We have environment variables to configure the WordPress instance and a headless WordPress secret. Now we can use the framework's functionality to make calls to WordPress. We start by getting GQL from Apollo and saving our query. Then we provide the query to the homepage, which requires the developers type.
So for the site, we're going to use the headless framework from WP Engine, it's an open source project that makes connecting to WordPress and pulling down content really easy. So we're going to go ahead and use that. So if we go to that project in GitHub and we scroll down, there's an npx command that you can run that will go ahead and get that project set up for you. I've already run that in the interest of time, and I've got it set up. So let's look at what it is right now.
I've pulled out a lot of the boilerplate that's in there, so there's this whole site there for you that shows post and has a blog. Pull that out and put in some of my own CSS and some components. So this is what the site looks like right now. We have this cool light dart mode, which we did purely with CSS variables, definitely check out the code if you think that's cool. And then, let's get into the code and see what we're going to do here.
Alright, so we have this environment variables file, where we tell the framework where our WordPress instance is. So this is just looking at our local instance right now, we'll change that when we deploy it live to a live instance. And then we have our headless WordPress secret, which that comes out of WordPress itself. So if I come back over here, I go to settings, you can see the secret is in here, can't hack me this is local, you won't be able to see the real one. You can try. Alright, so we got that set up. And that means that the framework is ready, it knows how to talk to WordPress, we just have to use the functionality from the framework to make those calls. So let's do it. And the first thing that we want to do is to get GQL from Apollo. And we're going to use this to save our query. So we'll say get all this. we're going to grab that from here that we did earlier. And just paste it in. All right, so now we have our query, which is great. Now we need to make the query and provide that to the homepage. So let's determine what the homepage is going to need from a type standpoint. So create an interface, home props. And it's going to have a developers, we need to pass in developers. And it'll be the developers type, which I've already defined. And I can show you that.
6. Mapping out and displaying developer data
We have the type and array ready for the developers. Let's map them out and put them in a card component. The card component expects developer props, which we can pass using developer.data. We also have a pure component for displaying the card. Now, let's provide data to the homepage by exporting getStaticProps and grabbing the Apollo client using GetApolloClient.
Right here, I have this type. This looks just like what we're going to get back from the query. So if you go over here, it's the same fields, just typed out in TypeScript. And then I have the array. And since it's under that data property, like we have right here, we have it extended like that for the developers. All right, cool. So that's what we're going to pass in here. So let's give this a type, react.fc and we'll pass in home props. And now we'll have those developers ready for us. Great.
Let's go ahead and map this out. So developers.map. And we'll put those in a card component. We have this component created. I'll show that in just a second. We need a key, which is going to be developer.data.twitter because that should be unique. And then the card just expects those developer props. So we're going to do developer.data. And let's take a look at that component real quick. We'll import that. And it's just a pure component that just has some styling and stuff like that for us. We don't have to type all this out for the demo. But it's just a pure component that will show a card of each of the developers.
So we're looping through that, but we haven't provided this homepage any data yet. So we're using Next, and we can make this a static page if we just export getStaticProps. So let's do that. GetStaticProps, and it has a context. And we're going to type that, getStaticProps.context. And then we want to grab the Apollo client. So we can do that with a framework method called GetApolloClient.
7. Querying and Caching Data
We grab the data from Client.Query using GetAllDevs. We return the props with Developers as Data.Developers.Nodes. We pass in Revalidate1 for constant data updates. We make a framework call to GetNextStaticProps to cache the query. We grab the client from the framework's headless provider. We query to get all devs and save the cache. We return the props and display the developers. We add a new developer, Dan Abramov.
And we just pass in the context. That will, when we pass in the context, it'll store the cache of that query on the context So we don't end up making the call multiple times. The framework handles all that for us. And we want to make the query. So we're going to grab the data from Client.Query. We need to await this, because it returns a promise. And we'll pass in GetAllDevs.
Alright, great. Now we have our data. We need to return that. So we're going to return props, which is going to have Developers, and it'll be Data.Developers.Nodes. And the reason for that is right here. So it's going to come back as Developers.Nodes. So that's why we're passing that in the way that we are. We also want to pass in Revalidate1 here, so that we constantly get new data as we add those developers to our headless WordPress site. And there's one other thing I want to do here, which is make a framework call to GetNextStaticProps, and I just pass in the context. This is the final thing that I need to do to make sure that I cache that query. And I'm going to import that from the framework. From our next section of the framework.
All right. So now what we're doing is we're grabbing the client, which has been put onto our application by the framework. If we look in this app here, we have a headless provider, and this does all the magic of making sure that Apollo is set up and ready for us to go. We make the query to get all devs. We call this framework method just to save the cash from Apollo onto the context. And then we return our props, pass that into our home, and just show these cards. So let's see if it's working. We'll refresh this, and there they are. We have our developers coming out of Hellas WordPress, so let's go create another one just to show how this is working. Then come in here, add a new one, let's say Dan Abramov. Pretty sure this is just Dan Abramov...
8. Deploying the App with Atlas Platform
Might not be. He works at Facebook, and he knows React. Now that we have our site up and running, the next step is to deploy it using the Atlas platform from WP Engine. We can deploy WordPress sites and Node front-ends written in various frameworks like nets, Gatsby, Vue, or Angular. Let's create a new app in Atlas, name it 'Follow a dev', and configure the environment settings. Provide the GitHub repository, environment variable, and the URL to the site. Save the settings and click 'Create app'.
Might not be. He works at Facebook, and he knows React, I'd say. And those things. We'll publish that, go back over here, refresh. I have to refresh twice. Not this time. And there's Dan. All right, cool. It was not the right handle.
Now that we have our site up and running, the next step that we would want to do is to actually deploy this and make it live. So I'm excited to show off a little bit about what I've been working on at WP Engine, which is the Atlas platform, where you can deploy your WordPress site and your Node front-end, no matter what you've written it in. In this case, we're using nets, but we could use Gatsby or Vue or Angular or whatever. And we can deploy it to Atlas. So let's go ahead and do that.
If I come over to my WP Engine portal, I have this site already running. So I have a WordPress site, and now I just want to deploy my app. So I go to Atlas, and I'm going to create a new app. And I'm just going to name the app. Follow a dev. And we're going to use our headless environment name is going to be production. We don't need anything else, right? And then we want follow a dev is our WordPress environment. We're going to run this in US central. In our GitHub settings, this is running at Matt-lander slash follow a dev, and it's on the main branch. And we need to give it that environment variable that we created earlier. Right here. And we need to give it the URL to our site, which I've got this already running out here. So I just need to grab this URL. I've got more developers already set up. We'll save that. We'll click create app.
9. Deploying the App and Improving User Experience
It'll go out, pull our code from GitHub, download it. NPM install, run a build script, npm run wpe-build is the script that it runs. Our site is up and running, it's good. We've given it a URL. I also attached a custom domain to it. At WPENGINE, we've been working to make headless WordPress a really great headless CMS, and part of that is improving the user experience. So we've been working through our open source framework to create a content modeler, which allows you to create content models in a much more user-friendly way.
It'll go out, pull our code from GitHub, download it. NPM install, run a build script, npm run wpe-build is the script that it runs. And once it does that, it will run next build, which will create all of our static pages and then deploy it where it will run npm start. Where we spin that up on port 8080. And then the platform knows how to run it. But once it's up and running, it will be good to go. And we'll see that that is over here building. And when it's done, we'll come back and we'll be running.
Alright, so our site is up and running, it's good. We've given it a URL. I also attached a custom domain to it. And now we can go out and check it out. So it's actually on follow-up dev, and you saw how fast that is. It's just running. It's instant. It's running static. And we also added some more functionality in here, you can check it out in the code, but we can filter by different keywords here, or different languages. And it's super fast and quick. So check that out, check out the code, check out Atlas, and let me know what you think.
Alright, before we're done, I have one more thing that I want to show you. So at WPENGINE, we've been working to make headless WordPress a really great headless CMS, and part of that is improving the user experience. You probably noticed that while we were creating those custom content types that it didn't feel very headless first. Because there are a lot of fields in there that just didn't make sense. So we've been working through our open source framework, which is out here. Make sure you star it so you can follow along on some code to create a content modeler, which I'm demoing right now. So this is the first time anyone has seen this, but it allows you to create content models in a much more user-friendly way. So we could create that same content model, so developer, developers, that we created earlier in this much better user experience. We have different fields that we can create, so we can put in our name as a text field, we can add another field for the languages, which is a repeater, so that's like an array. We can create these fields and we can create this content type in this very simple way and then we can also have a different experience for our editors, which will be coming out soon. So you can't get this yet, but make sure you follow along with our project so that you know when it is available.
10. Keeping track and building with Headless WordPress
If you want to keep track of what I'm doing with Headless WordPress, visit developers.wpengine.com. Join our Slack channel and check out our weekly content, including Headless WordPress Live on YouTube and the Decode podcast on iTunes and Spotify. Build cool things with Headless WordPress and happy coding.
And finally, if you want to keep track of the things that I'm doing, my team is doing around Headless WordPress, go to developers.wpengine.com. You can join our Slack channel, where we have lots of people in there that are talking about Headless WordPress and doing different projects around it. Also we create a lot of content on a weekly basis. So we have Headless WordPress Live, where we do live coding on YouTube every Friday at 1PM Central, check that out. We actually built this followdev site during one of our live coding sessions. And then we also have the Decode podcast, so come and check that out. It's out on iTunes, Spotify, all over. But we just talk about everything, front end development, and some things around Headless WordPress as well. So check it out. Let me know what you think, and go build some cool things with Headless WordPress. Happy coding.
11. Surprising Poll Results
I'm surprised that people are still doing REST instead of GraphQL. Some are stuck in the past and the infrastructure is tied to REST. Moving to GraphQL can be difficult.
I'm actually really surprised about this poll. I expected everyone to want to do GraphQL, but it looks like people are still doing REST, I'm glad I asked this, because it's a surprising result.
Yeah, but just think about maybe some of them are just stuck in the past, more or less. And not because they don't want to do GraphQL, but just because the whole infrastructure is really tied to REST in general. Maybe that's one thing there. And also the components relies on REST. It's pretty hard to just move to GraphQL. It can be. Yeah, that's true. For sure.
12. Authentication in Headless WordPress
WordPress has its own authorization mechanism, allowing you to make authenticated requests by adding an authorization token. The Open Source Framework provides an authentication flow similar to OAuth. It allows users to log in on the front end, exchange an access code for a token, and use that token to access authorized data. Third-party logins, like GitHub or Auth0, are also possible. The validation of access tokens and decoding of user information typically happens on the backend.
All right, so we received a couple of questions. And I will start with Yuri's question. He's wondering about authentication in Headless WordPress. Is it included out of the box, or we should still integrate with third-party services like Auth0 via plugins, as it was implemented in WordPress REST API previously? Right, so WordPress has its own authorization mechanism. So if you're comfortable with that, then you can definitely use it. The only thing that you have to do to make authenticated requests is to add the authorization token to the request to WP-GraphQL or to the REST API as well.
So in our plugin that we've created, the Open Source Framework, there's an authentication flow that we've implemented. It's similar to OAuth. So if you hit a page on your front end site where you need authorization, like a preview link, for instance, of somebody who's writing a blog and they want to preview it before they publish it. When they hit the link on the front end, it will route them to WordPress to log in, which then will redirect them back to the front end with an access code. That code will be exchanged for a token, and then you can use that token in your request to pull back any data that you need for authorization. But if you wanted third party logins, like login with GitHub or something like that, or Auth0, you can do that as well. I haven't tested that out, but that is an interesting scenario that I should take a look at. Yeah. But as we were discussing previously, I'm also fighting with this access token to know exactly that's not coming from a hacker, let's say. I would like to encode or decode it and see the actual user. This is something that happens on the backend. So it's really something that maybe a third party or WordPress, if it's doing it, it's something really good to rely on. Right. In that case, you could use your backend for your frontend for that as well. So if you're using a third party and then integrate that into WordPress, if you needed to use that token to access data, you could do that for sure. Yeah, exactly. Or maybe a custom of right. Right.
13. Efficiency of WP GraphQL
WP GraphQL is very efficient with its queries, much more efficient than the rest API. Demos have shown that the GraphQL API takes only 20 milliseconds to retrieve data, compared to 8 seconds with the rest API.
Another question it's coming from Renee Goretzka. If you have nested GraphQL queries, does the plugin fetch the data in one SQL Genie request or does it shoot out several requests to the SQL database? I'm not a hundred percent familiar with the inner workings of WP GraphQL, but I can get that question to Jason Ball, who's on our team and who maintains that. I will say that it's very efficient with its queries, a lot more efficient than the rest API. There are some demos that we've done where we hit a server with lots of posts and taxonomies like tags and categories, and it takes, you know, eight seconds to come back with the rest API. And then when the GraphQL API, it takes, you know, 20 milliseconds. So it's much more efficient than using the rest API, for sure.
QnA: Data Loader, Types, Performance, and Dashboards
Yeah. There's a data loader involved. Optimizations. Carlos Barraza asks about generating types for operations. Navis asks about plugins to improve performance. Headless WordPress offers scalability and performance options. Marcus Young asks about custom dashboards and using the WordPress dashboard. Existing plugins on the admin side will continue to work.
Yeah. I think there's also maybe a data loader involved, right? And there will be like, basically for, even though you're using WordPress or not, it is going to go and take something or is going to join the requests maybe. And yeah, another question. Exactly. Yes. Yes. So optimizations.
Another question is coming from Carlos Barraza. How did you generate the types for the operations? We created the types. So, well, the plugin comes with standard types. So if you have like a regular post or something like that, those will, the plugin has those types available for you. But if you have a custom post type, you'll need to provide those types. So you probably just didn't see it in the presentation, but those types were there. Or you provide them.
Another question comes from Navis. Are there any plugins to improve performance? We discussed previously about performance? Maybe there are plugins to improve it. So one of the reasons that you would go with headless WordPress in the first place is for scalability and performance. You know WordPress traditionally when you have the rendering mixed with the API and the data, different plugins are doing different things you don't have a lot of control over. It's kind of difficult to scale WordPress, but when you go, when you split the architecture up into where you have the API and the front end, it gives you a lot more options on how you would scale that platform. So you can do caching at the node layer. So if you have a post that's being hit a lot and you're doing server side rendering or something like that you could cache at the node layer and only reach out to WordPress whenever you absolutely need to. And you can also distribute that front end globally, which you couldn't do with WordPress, since it's so tied to the database. So there's a lot of options when you go headless for scalability, just by opening up that architecture.
Great. Another question comes from Marcus Young. First of all, he or she loves your presentation. So congrats on that. And the question is, do you also create custom dashboards for clients with this headless way, or just use the WordPress dashboard? Custom dashboards on the admin side I assume? I think so, right? If you already have plugins that you're using, yeah, so if you already have plugins that work on the admin side, those will continue to work. So if you have something that's working from a dashboard perspective, I would say stick with it. Why reinvent that? Whenever you go headless, you do lose all the plugins that modify the front end.
QnA: Backend Resources and WooCommerce Integration
Take advantage of backend resources to reduce development burden. WooCommerce has APIs that can be used for e-commerce integration. Although no specific integrations have been built on top of WooCommerce yet, it is possible to use it in place of Shopify. A workshop showcasing the integration of Shopify with WordPress was conducted recently. Building out-of-the-box solutions for WooCommerce is a potential opportunity.
So I would definitely take advantage of whatever you can on the back end to reduce the development burden, for sure. Yeah, it makes sense.
Well, a great question arrived. It's from Giannakis87. What about WooCommerce plugin or do you have already any integrations more specifically to e-commerce? Yeah, so WooCommerce has APIs that you can take advantage of. We haven't built anything specifically on top of WooCommerce yet. I've actually done a few live coding sessions where I use Shopify mixed in with WordPress. So mix content commerce and there's actually a workshop that's part of this conference that we did last week. I think it goes live again next week where we build a Shopify e-commerce store. But it would be no different than to use WooCommerce instead of that. We just wanted to show using different data sources going into that. But there's definitely an opportunity there to build some stuff out of the box for WooCommerce for sure.
QnA: WordPress Accessibility and SEO
By default, the WordPress instance is publicly accessible, but the frontend can be taken offline for security and SEO reasons. Yoast has a plugin for WP GraphQL to query for head tags. Creating fields via the API is not possible out of the box, but can be enabled with WP GraphQL's extensibility.
Another question, a long one, but it is really nice. It's addressed by CW. Since both Static Frontend and WordPress are hosted on WEngine, is the WordPress instance publicly accessible or it's a VPC of sort so that you can access the Static Frontend and interact with it via Apollo? Or can someone still accidentally arrive on the WordPress site? Right, so by default, the WordPress instance is available on the internet because a lot of people want to hit that from the browser. So if you were going to do client side stuff you might want to hit your WordPress instance from the browser. But it is possible to take your backend offline completely and only make it accessible from the node side if you were so inclined to do that. One thing that we do in the plugin is we do take the front end off the internet. So it's not indexed by a search engine or something like that. So if you were to hit like the front end for WordPress that person would be redirected to the front end that's in node to prevent, you know, multiple SEO potential like being indexed and also to reduce the surface area from a security standpoint. So they could only get to wp-admin which is gonna be a lot harder to break in than some plugin that's messing with your front end.
All right. Speaking about SEO, Zach Winnie asked, is there a way to query for things like head tags for SEO with WordPress Engine Headless? Yes. And we did that in our React in the workshop for this conference. So Yoast has a plugin for WP GraphQL so that you can pull all the Yoast data out of WordPress. And then Will Johnston, who's on my team at WP Engine, he created a React component that you can take that data and just plug it into the React component and it'll put it in the head for you. It'll do that on static or server side rendering, however you wanna do that as well.
And I think we have time for one more question. Luis Zardon is asking, any way to create fields via API to WordPress? Is there any way to create new fields through the API? That's a good question. I don't think that out of the box you can do that, but it's something you could easily enable with WP GraphQL. WP GraphQL is very extensible and I've used it to create fields for sure. And also, so I've used WP GraphQL's extensibility to create a form where you can just only submit to the form, but not read the form data, which is a good way to create a, like a contact form. It's pretty cool.
And, thank you so much, Matt. We had so many questions, but time's out. And, I want, but maybe people can still reach out to you. Are you going to be available on the call? Yeah, I'm going to join the spatial chat here in a minute. So if you want to jump on there, I'll be there. But you can also reach out to me through my GitHub or Twitter or wherever you want to find me. Matt Undershorelander is on Twitter. Amazing. Thank you so much once again, and enjoy the rest of the day, Matt.