 Hello, everyone. So before we start, of course, general announcements, lunch will be after this. You are not able to bring any type of food into here. It is all going to be out those doors where you'll get a food voucher. So just no bringing food in here. Other than that, I just wanted to introduce Jason Ball. He'll be. Thank you. Can you guys hear me OK? All right. So yeah, I'm here to talk about building static sites with WordPress, Gatsby, and WP GraphQL. Got the link to these slides here if you want to follow along. I think if you append slash live, it'll actually follow as I scroll on your machine as well. So first off, who am I? Jason Ball, of course. Senior web engineer, a media news group in Denver, Colorado. Denver native. I've been doing WordPress development for over 10 years now. Love WordPress, open source software in general. I'm the creator and maintainer of a plugin called WP GraphQL, which is what part of this talk is going to talk about. Obligatory family pictures. So what this talk covers. All right, what are and why should we care about static sites? What is Gatsby JS and how does it work? What is WP GraphQL and how does it work? And then how do we use these two things together, WP GraphQL and Gatsby, to build a static site? So end goal. We're going to use WordPress as a CMS to input dynamic data. And then we're going to output a static Gatsby site to render the content. So we're going to have regular WordPress site, host our content. Obviously WordPress, PHP renders a normal WordPress site. End result, we're going to hopefully get here to a, or not hopefully, we're going to get to a static site, which is using Gatsby and React. And by static, it doesn't mean that the content can't change. It means it's static files as in HTML without server lookups in the back end. We'll talk about that in a second. So first off, why static sites? Well, because they're so hot right now. No, but for real, I mean, everybody is in love with static sites right now. They're all the rage. But for real, static sites are pre-generated. So the files are static. They don't require database lookups or anything like that. They're low resource. You can use them offline. And they're secure by default because again, there is no database. So the tag vector is almost non-existent. Dynamic sites like WordPress, for example, they're compiled on the fly. Meaning when a user visits your site, the data gets compiled for that particular request, requires some server resources to figure out what to render to the user. It can be resource intensive. Typically online only. You can do things to fix that with WordPress. And it needs some sort of security to make sure people aren't doing stuff to your site. WordPress is good at security. I'm not saying not to use WordPress because of that, but you have to take action. So this is what a WordPress request typically looks like. Somebody hits, goes to their browser, makes a request. WordPress then uses PHP to figure out what they're asking for. Typically it then asks MySQL, the underlying database to get some data. Then it composes using the template or theme that you're using in plugins and what have you. It composes a page out of HTML, enqueue some JavaScript, load some CSS, sends it back to the user and they can see your site. With a static site, user makes a request and they just see the files. There's none of this, database lookups, there's no server computations. It's just, here's your file. So as you can see, it's clearly faster, right? Come on, that's obviously faster. So yeah, static sites are blazing fast, right? They're also super secure. I even tweeted about this, help my blazing fast Gatsby site just got hacked, said no one ever. They're also cheap for hosting, often time, even at massive scale, hosting static HTML files, a lot of hosts will do it for you even for free. You can put static sites on GitHub, pages are netlify with absolutely no cost. There might become a cost of let's say, like millions of pages, they might talk to you about paying them, but for the average site, you can get away with hosting it for free, even with your own domain name in many cases. Where WordPress obviously, there's usually some fee for hosting. So Gatsby, anybody heard of Gatsby? Oh nice, good crowd, all right. So Gatsby is a React static site generator. So you use React for the templating, you build React components, you feed them data, Gatsby takes those React templates, composes static HTML files, and then you have your static site. It uses GraphQL to source your content. So when you fire up a Gatsby site, it gives you this local GraphQL endpoint that you can talk to to get data and put it into your React templates. It does some cool stuff to optimize your site to make it faster, it can optimize your images for you. It can do link prefetching automatically out of box for you. So users that go to click a page, that page has already been loaded for you. Even though it's static and already rapidly fast, that makes it even faster. It uses some cool things like React Helmet for SEO so you can, you know, the things you'd be using Yoast SEO for to put stuff in the head of your WordPress site. You can get that data into a static site as well. Does some progressive web app and service worker stuff for you that makes your sites even faster? Yeah, so this is kind of what Gatsby build step looks like. Gatsby, when you fire it up and run a build of your static site, it talks to GraphQL to get data. That data can be many sources. It can be markdown files. It could be static JSON files. It could be external database. It could be a combination of all these or something else. The source doesn't really matter as long as it's some kind of data. Then you feed that data into React. React outputs those static files. Then you have a website. So, yeah, so what we're gonna be looking at is having a WordPress site be that source for our Gatsby site. So we have a WordPress site set up. You know, let's run a PHP WordPress. We're gonna enable a plugin, activate a plugin called WP GraphQL, which gives WordPress, your WordPress site, a GraphQL endpoint. It makes WordPress a GraphQL server. And we'll take a look at what that means in a second. So Gatsby's gonna talk to WordPress using GraphQL. WordPress is gonna send raw data back in JSON to Gatsby. Gatsby's gonna pipe that data into React templates and we're gonna have our site. Then users can visit that site and the user request itself doesn't actually have to hit the WordPress database. So yeah, WP GraphQL. You can learn more about it, wpgraphql.com. So it's just a GraphQL plugin. You activate it like any other WordPress plugin. So activate that. In this case, I'm activating a second plugin called WP GraphQL, which gives you an IDE for interacting with GraphQL queries. Yeah, so let's take a look at what GraphQL looks like. This is an example of a GraphQL query. It looks essentially like JSON keys without the values. So in this case, we can say, hey, GraphQL, I want the name of this viewer. I want the viewer and I'll have viewer, I want name. And in response, I'm gonna get a response that looks pretty much identical to what I asked for. So it's very predictable. I'm not getting heaps of data that I didn't ask for and yeah, and send the exact same shape that I did ask for. So what WP GraphQL does is turn WordPress into an application data graph and this is kind of what that looks like visually. So at the heart of WordPress, we have posts. Posts can have properties or fields like a title. That title is gonna resolve to some concrete data like hello world. Posts can be connected to other nodes in our graph, in the application data graph. Those nodes might be a featured image or category terms. And those nodes themselves might have their own properties like the category might have the name news or the name of crime. But those categories can have connections to other nodes in your application like other posts that also have their own properties like titles. And those posts can have other connections and it goes on. So GraphQL allows us to pluck nodes or trees out of this application data graph. So if you take a query like this, we say, hey GraphQL, I want to query, I want to query one post with this ID and on that post, I want to title a link and the categories and on each category node, I want the name. You might get a response that looks like this, very predictable, you get a post, you get the title, you get the link, you get a list of the categories and on each categories node, you get the name. So you ask for what you want and you get exactly what you asked for. So this is what it looks like. You have this big graph of data but you're only selecting pieces of it to use. So you want this one post and it's associated categories but you don't want those categories posts. Just stop there. So that's the data you get. The stuff highlighted in pink is what you get back. The rest remains untouched. So this is a live program that allows you to play with it. You can visit it yourself, playground.wpgraphql.com. You can play around with it but I'll show some quick examples to get you up to speed on kind of how GraphQL works. There's a graphical editor. It's an IDE for playing with GraphQL. It comes with a nice feature where you can search what's available to you in a GraphQL schema but it's pointed out a WordPress site running WP GraphQL. So some example queries. In this case, I might need to zoom in. Can you all see? All right. In this case, I'm saying, hey WordPress, I want one post and on that post I want the ID, the title and the date. I can execute that and I'm gonna give back exactly what I asked for. I can extend this like my previous example, ask for the nodes. So I can do these nested queries to get related attributes of stuff in my graph. I can't even ask for further properties like all posts that are, all posts that are in the uncategorized category. So I can do these deeply nested queries and get related data very declaratively almost like I'm speaking plain English, right, to my computer. I want post, title, categories and their posts. So very declarative language. I can get collections of posts so I can get a single post or I can get collections of posts. I can get pages. I can get categories and the categories children and their children and their children. I can get users, right. I can even query for plugins if I have proper access to see them. Same thing with themes. Things that are not easily queryable, right. You can access this through your graph now. In query general settings, maybe, except that field. And if you make a mistake, you get helpful errors. But yeah, so you can query general settings like the name of your site, the language of your site, things like that. So very helpful stuff if you're building headless WordPress installs. There's some cool features of GraphQL like aliases. In this case, I can tell GraphQL what I want the field to come back as. So instead of posts, I want it to be called card lists. And instead of nodes, I want it to be called cards. And when I execute, GraphQL is smart enough to send it back to me, matching what I wanted it to be called. So these are just some features of GraphQL and this is all WordPress WP GraphQL in action. So this is actually hitting a real WordPress site with WP GraphQL active. So you can play around with that site. So let's, now we'll take a look at Gatsby. So how to build a Gatsby site. At the heart of Gatsby, when you first fire up a Gatsby site or a Gatsby project, there's a file called gatsbynode.js. This is a build script that is you tell Gatsby what to build. So it doesn't do anything for you, it only does what you tell it to do. So in our case, to recreate a WordPress site in Gatsby, we're gonna have to go through process to create posts, create pages, create users, create categories and create tags. You could do more or less of this depending on your use case. So this is the entire Gatsby node file just pulling these other files that handle the process to go create posts. So let's just take a look at one example, the create posts action. So the actual file is a little bit longer than this. I abbreviated it, but here's the gist. We tell Gatsby to use GraphQL to query WP GraphQL to get posts. We use these arguments for pagination. So we say we want the first X amount of posts after this point in the data set. So we can say I want the first 100 posts after zero, which would be the start of your database. And then that's gonna return an end cursor or where that query ended. And whether there's more info, has next page will be true or false. We can use those values to continue to paginate through our data. So if has next page is true, we can run this query again to get more posts. So we say, hey Gatsby, talk to WordPress, get 100 posts. If there's another page, get 100 more posts. If there's more, get more. And you can keep going through. Once has next page is false, move on. So that means we've queried all the posts in the database and on those posts we have a couple of fields, an ID, a URI, like the actual URL for the post. The post ID, which is the database ID and the title of the post. So we have a little bit of data. We map over that or we loop over that data. And along with that data you get these fields and we pass it to a template as context. So let's take a look at what that template file looks like. We're passing these fields ID, URI, post ID and title to this template and then on this template we can use GraphQL again with those variables we sent over. So we send an ID, we can use that ID to say, hey WordPress, give me this one specific post based on that ID. And on this I want the title so I can render it in my React component. I want the content so I can render it. I want the author and on that author I want the name, the slug, the avatar and the URL so I can render the image. And I also wanna list the categories. So then we can get that. Gatsby's gonna take this data, feed it to our components and then our components are just React components, largely HTML with data just rendering, variable data rendering. So I wanna actually show some live code now, hopefully. So let's take a look. I have, let's actually take a look at the live sites. So I actually have this site up, it's a WordPress site populated with data from wptest.io. So this is a normal WordPress site, nothing too fancy going on, you can interact with it, you can go to the homepage, you can click through pages, you can go to the category archives, what have you. And then I built this site which is also live, Gatsby-wgraphql-blog-example and this is an example of free hosting on Netlify. So essentially the same, same site, right? I can click into pages, I can click into categories, I can click into posts. We have menus, this menu is managed in WordPress but Gatsby queries the menu data from GraphQL to render it in my static site. I have pretend widgets even that actually work, right? So I can navigate my static site, all the data is coming from WordPress but this is all static, there's no database request happening each time I'm clicking a page, there's no cache lookups, it's just a static HTML file. I can even do cool stuff like pagination, like I can paginate through my posts. Right? So this is that same site, I've got it running locally so I wanna do some live code just to show you kind of what the developer experience of working with Gatsby and WP-graphql looks like and that's fun. All right, let's try that again. They always say don't live code in your talks and I say watch, I'm gonna do it anyway. So this is a, actually this is helpful anyway so when you first fire up Gatsby it runs through your build script so what's it? Yeah, zoom in. So I fired this up, I ran the command Gatsby develop, it ran through that file that I talked about this first file so it's gonna run through this file so we're gonna create posts, we're gonna create pages, create users, create tags and you can see I have it logging out, it created these posts, created this page, created this tag and then we're done and it says visit your site here. So let's take a look, I wanna look at what it might look like to create a new widget. So here I have my Gatsby project, we have some components and in here we have a sidebar component, very simple. So sidebar just imports a couple other components, a recent post, categories, recent comments. So we're gonna create a new widget just to see how this works. So just right here we'll say const, I don't know, what do we wanna get? We'll just get the site title and render that. So we'll say like site title widget. So for now I'm just gonna say site title just hard coded and add this here and of course, what did I do? What's that? Returning, there we go, there we go. So now we have site title here and I bet if I would have read that warning it probably told me that too, which is a cool thing about Gatsby and React in general, there's a lot of helpful dev tools. So we have some static data now coming in. So we wanna get some data from WordPress. So we're going to import GraphQL from Gatsby and there's another component called static query. We are going to wrap R with a static query. Then we can tell Gatsby what data we want and actually for static query I don't need GraphQL. All right, so one thing you might have noticed when I fired up this develop environment you get this graphical editor as well for your Gatsby site. So I can fire this up and I can explore what's available to Gatsby. So Gatsby now is stitching in my WordPress schema for my WordPress site, but I can also query like markdown files for my file system or whatever I want and you can install Gatsby plugins that bring in other sources of data as well like GraphCMS as a data source or Drupal as a data source or whatever you want. Wherever your data is you can most likely get it into Gatsby. So I can play with this so I can search WPGraphQL posts or in our case we're gonna say general settings and title. So I can play in my DevTools with the query I want to run. Say yeah, that's the data I want, right? And then I can just literally copy this into my component and then this one actually, so this one we're gonna get the data and we have to return what we want. So we're gonna return our H1 here. I did this right. We should still see site title. So we can see it's loading. Maybe I did something wrong, so let's take a look. It is not liking my query, sweet. So we can use React DevTools actually to see what's going on here. So we can see that it is loading and my guess is I have poor network, I have no network connection. That is why. Let me try that again. If you don't have network connection you can't query data from a website. Bomber. All right, well I am not able to connect to wifi so that is not gonna work. All right, so let's pivot instead of live code let's just look at some existing code. So on the sidebar let's get rid of this site title widget that we were gonna make. Let's just take a look at how the existing recent post widget is created then. So recent posts were just, I played around with the graphical editor to say what data I wanted. So I tell WordPress, hey for this recent post widget I want the first five posts and on that I want the ID, the title, and the link. Then I can pass it to my static query. I'm gonna get the data, the response of that query back and then I can map over that and I can render it as a link and that is how we get this recent posts link. So I can also edit and you'll see live updates as I type. So like recent posts. WC WordCamp Phoenix. So as I'm editing my dev experience you'll see it updated in my component rendering. So the experience is pretty nice and it just went away. So unlike WordPress where you're probably publishing data and then talking back and publishing data and talking back, DevTools and Gatsby give you these real time updates which is really nice. I can do things like change my style so we can just say style or CSF, yeah style. So we could say background, color, yeah it sure is. So we can say background color red and right there it'll live update as I'm coding. I can then hopefully ask for additional data so like let's say we wanted to show a date with our link. My query is coupled right here with where I'm rendering it so I can then say, so I can say I need this date from WordPress so that I can render it right here and now you can see the date. It's not formatted well but you can see the date is coming through, right? Turns out I don't need the date anymore. I don't have to search my application to figure out where that data is coming from. It's coupled right here with my component so I can just come clean that up. Now my application is gonna be that much faster because less data is being passed through, right? So that's some examples of it. One thing I wanna show that's pretty unique is this menu query. So in this case we actually have a menu and let's take a look at it in the dashboard. So we have a menu that I can manage using tools I know well like the WordPress menu manager. So in my case, yeah, so we have this really big menu right that has like 10 levels of items, right? So I can query that with Gatsby or with GraphQL in general and you can see I have the exact same menu here. So level one, two, three, four, five, right? I have this 10 levels of menu. Let's say for my use case I decide my application should only support two levels of menus. This is the menu query in Gatsby that's asking for all the menu items. So I can adjust this query. So we say, hey Gatsby get these menu items on the primary menu and I want these fields. These fields are the ID, the label, the URL and the type of the connected object like whether it's post or page or term or something else. So I can adjust that query and you can see in real time now I'm only supporting one level so I don't have nested levels. I can, at the query level, I don't have to do this logic in my application and say, hey, I got 100 levels of data, you know, iterate over this and do whatever. You can do this at the query level where you ask for the data, you can say, I only want this deep of data. So we could do it like at this level which is what, four or five levels deep. I can refresh my page and you'll see now I'm gonna have what, three, four, five levels. So at the query level, I can say, here's what I want to support in my application. Go get it for me, let me render it. So the developer experience of using GraphQL and then feeding that into React using DevTools like hot reloading, I think is pretty awesome and then the end result having an actual static site so that your users don't have to hit database, you don't have to worry about security. I think it's pretty awesome. So yeah, so that's the gist of building static sites, some actual trade-offs with Gatsby, some pros, it's blazing fast, it's super secure, it's crazy cheap. I think it's a fun development experience. If you've never used React, it's probably frustrating to start but once you get over that learning curve, I think you might enjoy it. With React, another cool thing with React coming to work or in WordPress Core now with Gutenberg, you can actually use the same components that you're using to build Gutenberg blocks to render your content in a Gatsby theme. So instead of having to build this, React component for Gutenberg and a PHP render component for your theme, you can use the exact same component in both cases. Some other pros, I think, all JavaScript, I think it's pretty nice to work JavaScript front-end, JavaScript back-end, the build process, you can share some snippets of code. Another pro I would say is it's decoupled from WordPress so you can iterate much faster. You might not even have to touch a WordPress server to be able to build an entire Gatsby site. Depending on your needs. Some cons, there is a build step. So content is not immediately available. When you click publish in WordPress and then go visit your WordPress page, the content's available. Here, you have to trigger a build step. So normally, like with Netlify, for example, you can send a web hook that says, hey, Netlify, rebuild my Gatsby site, which is then again to go through that build step of querying your WordPress content and rebuilding the pages. For a site like this, I think it's like a 20-second build so it's really pretty quick, which might be as fast as your cash clearing on your WordPress site anyway. But if you're on a really big site or a site that really relies on fast-moving content, like if you're a newspaper, probably not at the moment the best choice for you because every time somebody clicks publish, you'll have to wait for that build to complete. But if you're a marketing site that changes content, a couple times a day or less, and it's not super time-sensitive, Gatsby might be worth it for you for the security benefit, the cheaper hosting. You can move your WordPress site to cheap hosting because you don't have the public traffic hitting it anymore, just whoever's managing the content and then host your public site for free with Gatsby. At the moment, it's no incremental build, so back to that step. If I publish one page, I can't just publish that one page to Gatsby after rebuild the whole site. The Gatsby folks are working on making that better. They recently got like $3.5 million of funding. It's an open source project, so they've got a pretty good team working on problems like that. Another con, this was also a pro, but it's all JavaScript and it's decoupled from WordPress. So you have to now learn two things maybe. You have to know WordPress if you're handling both sides. And decoupled from WordPress, plugins that would normally hook into your content or to render things or do other things on the front end won't affect Gatsby, right? You're in complete control now with the front end. You can't enqueue scripts to a not WordPress site. So anything that would have been happening on the front end of your WordPress site, if you want it, you'd have to rebuild it in Gatsby. So conclusions. I think Gatsby is a fantastic static site generator. I think the developer experience is great. And WP GraphQL is comprehensive API for all your WordPress data needs, not just Gatsby. If you take anything out of this, I think take the WP GraphQL can allow you to fetch your WordPress data in a very easy and efficient way. You can use it outside of WordPress like this in Gatsby. You could use it inside of WordPress like to hydrate a dynamic Gutenberg block or, in my case, I even talked at Zach's workshop last summer about using WP GraphQL for the data layer for Gutenberg blocks, right? So yeah, here's some resources. Got Gatsby's website, WPGraphQL.com. We launched a new doc site for WP GraphQL last week. Got the open source plugin. The demo that we walked through, both the WordPress site link is here and the Netlify hosted Gatsby site, GraphQL.org to learn more about GraphQL and React.js to learn more about React. Like, that's all I got. Do we have time for questions, I think? Yeah, go ahead. Yeah, sure, let me go back to the beginning. So slides.com slash Jason Ball be a HL-1 slash WCPHX-2019. So good question. Question was, is the WP GraphQL plugin like a wrapper over the REST API? And the answer is no. So it talks directly with the WordPress server just like the REST API does, but it's a lot more efficient. So with the REST API, if you say you want posts, you're getting all the fields of the posts, the server's executing to resolve that, it's applying filters on the content and on the excerpt, even if all you want is the ID. So with GraphQL, it only executes the functions necessary to get you the data you need. So if you're not asking for the content, it'll never run filters like apply filters to content where if it wrapped the REST API, it would have to go through all that extra processing which it actually was born out of ill performing REST where I work. So yeah, it doesn't, but it adheres to many of the same principles. So if you register a post type and you say show and REST, you can register a post type and say show in GraphQL and then you give it a GraphQL type name. So like show in GraphQL, true, and then GraphQL, what is it? GraphQL single name posts, GraphQL plural name posts, and then it'll be in your API. Yeah. Yeah, so we have docs here, docs.wpgraphql.com shows you how to register a post type to show it in your GraphQL API and even how to filter other post types that maybe a plugin added for you. So you can expose that and then you can now query a custom post type. Yeah, that is correct. After the build is over in the example I showed you would not need a live connection at all. You could, if you wanted to, like things like comments or form submissions, you could maintain a live connection so you could render your static page and then on the client, on the client of the Gatsby site, you could then make a GraphQL request back to load comments. Information that's not essential for rendering the initial page or you could do like form submissions through GraphQL mutation. That's one thing I didn't cover. You can do mutations through GraphQL so you can write data back to WordPress as well. Yeah, so WP GraphQL is, yeah, it's a WordPress plugin so it runs on your server. So it uses, behind the scenes it's still using WP Query, WP Tax Query. So it's a PHP plugin that just exposes access. For like private data though, like let's say you had a draft post or whatever, the model layer will prevent it from being returned if you don't have access. But yeah, so like one quick, quick example, like for settings, if I wanted to query settings, which is, I don't have an example. But if I wanted to query settings, and I think my time is up, so this would be my last one. So if I wanted to query general settings, I can ask for the title and like the email. The email's private, right? I'm logged in right now, so you'll see it. If I tried this from outside as a non-authenticated user, XQ, so if I'm not authenticated, I don't think this one's working. I don't have that environment set up. But anyway, if you're not authenticated, a private field like email address wouldn't be returned to you. So since I'm authenticated here, it's returning to me. So at each field level, you can get a combination of public and private data and the private data would just be nulled out with an error, so it won't like break your app. Like we're REST, it's usually like you get everything or nothing. So all right, cool. I'll be here all weekend, so come chat if you have questions.