Build a Headless WordPress App with Next.js and WPGraphQL

Workshop from:
React Summit
React Summit 2022
Bookmark

In this workshop, you’ll learn how to build a Next.js app that uses Apollo Client to fetch data from a headless WordPress backend and use it to render the pages of your app. You’ll learn when you should consider a headless WordPress architecture, how to turn a WordPress backend into a GraphQL server, how to compose queries using the GraphiQL IDE, how to colocate GraphQL fragments with your components, and more.



Transcription


So yeah, let's let's get started then since we're a few minutes past the hour. So thank you for first and foremost for being here for tuning in for this Workshop. I'm really excited about it the title of this Workshop as you're well aware already is a build a headless WordPress app with next.js and WP graphql. So what we'll do is. Let's see. Yeah, so we'll do is I have a few slides to go over all I'll share my slides on introduce myself and then go through a few topics such as like, what is headless WordPress. Why might you want to consider it and after we get through those slides then we'll dive into the, you know live coding Workshop part of it where I'll have you actually, you know cloned down a next JS application get that up and running are your local machine and then we'll see how we can get that hooked up to a WordPress back end so that we're pulling data from Network, press backend via graphql and using it to render the pages of our next JS app and we'll walk through a few different types of types of pages and see how each one is built. So I hope you really enjoy it and get a lot out of it. All right. So build a headless WordPress app with nextgess and WP graphql. All right, so to start off all I'll introduce myself. So my name is Kellen mace. I work at a company called WP engine which is one of the most popular hosting platforms on the web for WordPress sites specifically and and it's you know relevant to to this audience and this talk is the fact that WP engine recently. We launched this new hosting platform called Atlas which is meant which is geared toward headless WordPress sites even so you can with with a single, you know account and in a single hosting provider, you can host both the WordPress backend as well as your front end JavaScript application all in the same spot, which is pretty cool. So check out Atlas if that sounds interesting to you. My Twitter handle is here is here as well. If you want to get in touch with me after the conference. I might DMS are open. So please like if you're diving into this stuff and have some questions, please reach out and let me know here. So with that we'll dive in. I know I start with just kind of disembly disambiguating or you know calling. Drawing attention to the differences between traditional WordPress and then headless and why you might want to go one way versus the other as I said. So let's do that. Oh, yeah, before we do though. I just just one slide here. And that is clone the app repo. I wanted to put this right at the top of the slide deck here just because it might take a minute depending on your internet connection for you to clone down this repository and then you can follow the steps in the readme there. They'll they'll tell you to to, you know CD inside of the directory of this project and then run npm install to get the dependencies installed and so on. So if you do that now that'll save you a minute you want to get to the live coding portion later and then you have to wait for the dependencies to be installed and so on so you can go ahead and grab that that link in the slide. On this line. All right. So with that let's talk about traditional or monolithic WordPress. So as many of you on the call probably already know WordPress has been around for a while. It's the word world's most popular content management system at this point. The statistic is pretty mind blowing. It's like WordPress has achieved about 43% market share on the internet. So that's the percentage of sites online that are running that which is just just Mind by boggling to think about and traditional WordPress. WordPress has a lot of jobs. It's responsible for providing the admin interface that your content creators log into when they, you know, create and edit and manage their content. It's responsible for saving the that data to the database and then when requests come in from, you know website visitors WordPress is all sort of responsible for pulling the data out of the database and then templating it out using its theme API as HTML and finally Responding to that request. So it wears quite if you had some does a lot of jobs and in many cases on the web. This is this is a great setup and works really well, but more and more people are choosing to adopt a headless or decoupled architecture. So we'll talk about that next year. So that looks something like this. Where you have WordPress is still used so you can see it on the left of this slide here, but it's used really only to provide that nice admin experience for your content creators into store the data, but it doesn't handle any rendering it doesn't return, you know any HTML to the site visitor instead. You have a friend application that does that and that's you know, next Jazz in our case on the workshop is what we'll we'll use for that. So you have next Jazz and it handles, you know, querying the data from WordPress and using that. To render out HTML pages that site visitors are served and in between here, you have to have some kind of API layer. So you need some way for your JavaScript front-end and your WordPress backend to communicate with one. Another one way to do that is to use the rest API. It's just built into native WordPress. I would argue though that a better choice these days is WP graphql. So that's the logo that you see here at the bottom. WP graphql is a free open source plugin for WordPress that turns any WordPress site into a graphql API, which is very powerful. So then you get all the benefits of graphql like if you want to In a rest API architecture if you wanted to query for blog posts and users and categories and something else you might have to hit multiple rest API endpoints just to aggregate, you know, just to get all the data that you need which can be time can consuming and and take you know, cause a performance hit with wpgraphql. You have the benefits of graphql where you can enter your WordPress data graph at any point. And then from there query. However, you want you can say I want the first 10 blog posts and for each of those authors. I want their name and other you know posts they have written and for each of those I want the categories and kind of compose these nested queries and get all of that data back in a single Network request, which is very powerful and as other benefits too, but that's you know, I would say one of the main ones this is what kind of a decoupled architecture looks like and this is the thing that will actually building today. All right. So next question after you've you know heard me talk about traditional versus decoupled is Okay, but why why would I you know choose one versus the other what are the benefits there? Right. So let's cover that next real quick. So some of the benefits of going headless or or for a decoupled architecture would be the these so your content creators get to keep their CMS. If you talk to many like marketing teams at many companies, they really love and know and you know rely on WordPress and they want to keep using that as they're preferred CMS, so they get to with a headless setup. Performance and scalability. It's you know Frameworks like next yes make it very easy to get very fine grained and say I want this route to be fully static. There's other route to be server-side rendered this other route. I would do some client side rendering you get, you know, very fine-grained control over, you know performance and how each of your pages is built and it can scale very well as well. Third one is platform agnostic back end. This is kind of an interesting one to think about so with a headless or decoupled approach your WordPress backend. It just serves up pure Json data. So that means you could have a web client like a nextgess app that pulls that Json and renders it for the web client. But if you wanted to you could also build an iOS client in Android client a desktop client and all of these apps could Source their data from the same gate the same graphql endpoint, you know the same Json data that the web client uses other platforms could use and consume as well. So that makes it pretty powerful if you have you know, multiple platforms that you need to support. Next one is easy to pull data from multiple sources. This would be like at build time when your static pages of your set are being built. Let's say if you want to pull some data from WordPress some data from Salesforce and data from the YouTube api's data from contentful or whatever else. Yeah. It makes it modern Frameworks like next make it very easy to do that to Source data from all these you know sources and it's Stitch it all together into your HTML Pages. Next one is increased security. I've seen site architecture as well where they'll do something like they'll have a JavaScript front-end. This serves the website to their site visitors love the WordPress back end where they're content creators manage content and then that WordPress back back and the lock it down so that only certain IP addresses are allowed to even connect to that WordPress install and log in to manage the content anyone else on the entire internet who attempted to, you know, navigate to the WordPress admin to try to get in. Disallowed since they don't have you know, one of those allowed IP addresses for example in traditional WordPress. You couldn't do that because everyone needs to be able to access, you know that web address where WordPress lives because it's doing all the rendering right your site visitors need to visit that when you have a decoder approach. That's no longer the case. You can do some tricks where you lock down access to the WordPress. Admin while letting your site visitors, you know, see the front end Javascript app here. And last one on this list is improved developer experience. I would argue, you know, these days many of us in the web development Community are really really appreciate and like to build in a component-based architecture. So since you're at the react Summit, I'm gonna assume you, you know, like react and like like building in a component architecture and you get all of that right if you go for a headless approach, then you can choose a front end framework to make make things easy and then build in components and have you know, a really nice developer experience. Which can be another perk? All right, drawbacks go through this side and then I'm gonna check the chat here and see if we have any questions one is additional complexity. So you do have a few more miss a few more moving pieces instead of just WordPress. Now, you have the WordPress site which serves up data and then you have your front end application which consumes that data so a few more, you know moving pieces there to manage. Next drawback would be it requires recreating some built-in WordPress features. So some examples here would be user authentication and post previews. In traditional WordPress a content creator can create a new draft blog post, you know type a little bit of content and then click a button to preview that post and see what it would look like on the front end if it were published, right so that kind of thing you don't get for free. If you decouple your friend from your back end now you you know, you don't have a way of authenticating the user and knowing if they're allowed to view a unpublished draft of a post. For example, there are some pre-built Solutions people have created in WordPress to bring that functionality to headless but just know that it's not something that is kind of out of the box, you know that you you have to put a little thought into how am I going to you know, add this feature to my decoupled architecture. Third one here is you can't use WordPress plugins to add visual elements some people like, you know full control over their over their own website. So if you build a site for like the the, you know, small shop down the street or something and they want to be able to manage the site themselves. They might want the ability to add a install WordPress plugin and add a image slider or something like that to the front end of the site, but and you can't do that anymore with the Headless approach. You can't simply activate a plugin that adds visual elements to the page because all of those digital visual elements are controlled by your decoupled Javascript app, right? So that makes sense. This may not be icon or a drawback though, depending on your project, you know, many times. You don't want the client themselves adding all kinds of, you know, visual elements to the page all the time and Potentially taking performance and that kind of thing. So this could be seen as a pro as well because you have things more tightly locked down and controlled as far as what gets rendered. The last one I have here is you can't use the new full site editing features. So WordPress WordPress 6.0 just dropped and it has new full site editing features that are geared toward that person. I mentioned where the website owner themselves wants kind of full control over the website in the ability to you know, create layouts on their own using kind of a page builder kind of experience. So that's what's the full site editing features that are coming to Wordpress. They kind of enable that kind of workflow. If you go for a headless or decoupled approach though that you wouldn't be able to do that because again, the rendering is all controlled by the front end Javascript app, so that could be a job drawback for some projects but having that tight control over what you trended could also be a pro as well as I mentioned. All right. Let me pause for a moment and I'll pop open the chat and see what we have. All right. Reading through the comments here. Yeah, I can absolutely pop the GitHub link. in there, so let me just do this. All right. So I pop the link to the GitHub project in in the chat. You shouldn't need that direct link though because you should be able to open the slides that I had shared at 10. Oh well 10:05 might my time, but I identify in the chat. Well, let me copy that one again as well. going to The slides there we go. So I put the link to the slides in the chat as well if that's upload anyway. Let's see. Oh, I see a few of you shared the GitHub link as well. Thank you for doing that. Save me the trouble, okay. All right. Let's continue with this then I just have a yeah a couple more. So that was really it for the slide as far as like what how headless WordPress is different from tradition WordPress and then the benefits and drawbacks. I'll resume the slide show. Now the next thing after the benefits of drawbacks here was let's code. So at this point we can actually, you know, dive into our workshop and talk about what we're going to build together today. All right. So this is what we'll cover. So here's Workshop content. I'm calling this the setup portion. So what we'll do is we'll crack open our finished application and get it up and running in a browser and we'll look at both the pages that it has as well as the code. That you know that powers each of those pages. So for number one, we'll take a tour of the pages of our finished app. Number two. I will see how we can turn WordPress into a graphql server with the wp graphql plugin. Number three is get set up for local development and some of you who clone down the project and follow the steps in the readme I've done some of that work already. So I'll save you some time once we get to that step. Number four is a configure Apollo client. That's the graphql client that we're going to use in our next JS app to pull data from our WordPress backend. So once we're done with this stuff our setup portion, then we'll get into the build features portion. So we'll cover these things here. So number five on the list is compose a graphql query using the graphical IDE. So I'll show you how you can do that and then six through nine. Here are all about implementing specific pages of our application. So we have the blog index page or blog landing page. We have this single blog post page number eight. We have a single category page number nine will be a fun one. That's our search page where people rather than you know, pre-rendering a page of a static page ahead of time like we could with some of these other Pages the search one will be, you know, rendered on the fly. So as the user type something in and hits the button will fire off a request, you know in real time to our back end to find matching blog posts and then re-render the page to show the matching blog posts. So we'll see how we can do that. And then number 10 if we have time if we get to it, we'll see how to leverage graphql fragments this way we can reduce. Reduce like boilerplate, you know and having having a parts of our graphql queries disassociated with the components that actually use them. So with graphql fragment that allows us to have a single rack component and co-locate the data that it needs with the component itself. So it makes your code base like very nice and in organized so see how we can do that. If we again if we have time to get to step nine. If not, though, if we are step 10. If not though, please get through step step 9. I think it'll still be, you know, hugely. Hugely beneficial and helpful Workshop to see how you build out, you know, each of the pages that we'll cover here. All right, after that my the very last slide on this deck is just helpful links. So as we go through the workshop, I'll reference these things. So number one. I've already referenced right? That's the next GS app repo but the numbers two through seven here are things as we go. I'll just reference the links on this page. So you can click these to open them to dive into things here. What we'll do first is clone down that repo as I said, so hopefully most of you have done that already, but if not, you can click the link to open this code repository. You'll need to just follow the steps in this read me here. So clone down the repo you'll CD into the directory and run npm install to install the dependencies and actually the rest I'll do with you here. So let's dive in so on the command line here, you can see that I've I've cloned down this project myself right here to my desktop and now I'll run Npm install just make sure all the project dependencies are installed. Okay? And then once they are we'll continue with the rest of the steps here. So it says create a new DOT envy.local file in the root folder with this as its contents. Okay, so let's do that. So open up our project in a vs code window. And there's resize this for us. There we go. Okay, so following the directions here. I'll all right click over here and just go to new file and name it dot Envy dot local. Inside of this we're going to put an environment variable. So I'll copy this. Right there and then paste that into this file. So this points to the graphql endpoint that our next GS app is going to use when it pulls data from a WordPress backend site. All right, we'll talk more about that in a little bit you there's an alternative here. If you're somebody you already uses WordPress. I want would want to pull data in from your own site. You could do that. So if it says if you want to point the next yes app to a local WordPress install swap out. You know that with the domain for your local WordPress site, so you can do that, you know, either either now or or later on your own if you want to swap it out and see what it looks like to pull data from a different WordPress site. This is the only thing that you would need to to change here. All right. Let's see. If you do choose to use a local WordPress install. Make sure you have wpgrfql installed and activated. All right, and then you run run PM npm run Dev to get the app up and running at localhost 3000 and you can stop at any time by hitting control C. All right. So, let's see how we can do that. So that kind of command line we'll do npm. run Dev There we are and then I'll just click this link here to open localhost 3000. We'll see our application and all of its Glory. So here we go. Headless WP app. Alright, so this is what we'll explore here. on the head back to our sequence of events. Okay. So yeah. The first thing we'll head head through now is the tour of our finished application. Please check which check the chat here. All right. So Kyle is your your question here. Is there a preferred hosting partner with this architecture or can you pick and choose IE AWS? Yeah, so great question. You can there are many options out there some popular. Apps for for hosting the front end application. Well, let me step back for for just a minute here. There are two options one is like you need to host your node.js based, you know, front-end JavaScript application. You need to host that somewhere but then you also need to host the WordPress site somewhere else. Those could be the the same host or they could be different hosts. I mentioned at the beginning of the presentation that my company WP engine. We have a product called Atlas. So if you use Alice it allows you to host both and manage them from a single dashboard. What you could do is create a new Atlas. App environment and just call it your production app environment and say for my front end app. Here's the repo to it and for my WordPress backend, I want to create a new one, you know on your wpng platform and then hit a button it'll create both of those the friend in the back end, you know the point to one another and use graphql as the data layer and you can manage both from a single dashboard, which is kind of nice. We're the only host I know of who does both of them hosts both of them. Otherwise, if you didn't, you know want to go with with atlas. There are other providers out there so netlify and versal render.com or a few really popular ones for hosting your front end Javascript app, and then for the WordPress back and as you said you could you know if you wanted to Host that on AWS or on digital Ocean or linode or other managed, you know hosting posting providers in the WordPress space, you know, like siteground or Bluehost or anything else you could do that as well. So you could have, you know, front end up on netlifier or so and your backend app on digital Ocean or AWS or whatever and as long as you configure that you to point to one another like by doing what we're doing here, you know, we're specifying the graphql and point where your WordPress lives then that would be another option for you as well. Let's see Alex. Yeah, and you're right. You're right. So you could host even host the front end and AWS as well. Yeah. So if you're somebody who's very technical and knows how to post, you know, node.js apps. I need to AWS and certainly you could do that as well. You know host the the front end app on AWS as well. That's true. Excellent question. Okay. Let's keep rolling here. So next step is a tour of our finished apps. Let's take a look at how this thing is built here. So with the app that I gave you ahead of time. I didn't do a whole. A whole lot to it. I'm just added some pages and components. That will will walk through here. So let's start with like this this homepage here. If you all views next GS to probably recognize this is just kind of their you know, welcome screen that that the framework uses. Let's over head over to blog though and see what that looks like. So you see with this blog page and it has a grid of blog posts. Right here that are linked. So let's see how that works. And maybe in the chat, okay a thumbs up if if y'all are able to load the slash Blog Page and like this is what you see. That are good. Well, we do that let's dive into it. So I'll open up pages in The Code editor and then go to blog here and this is what that page looks like. Cool. Thanks for the thumbs up. Alright, so here's the blog page you can see right now. We're cheating. None of this is real data here. All right, it's dummy data. So what we're doing in this file is we have this. directory right here They bump up the size actually with the structure here called dummy data with an index file inside of it. You see it just has a bunch of hard coded. You know posts data data here. So it mimics the structure of the data will we'll get back later when we do actual graphql queries, but for now you see that this is just hard coded dummy data. So what are blog page does is it pulls out the posts from that dummy data file? And then inside of get static props? We tell the next Jazz. Hey at build time when you're building out this page send through a prop to the component called posts. And here's where you get where you should get the data from the this, you know these posts that we imported from our dummy data. And if you look at the component here, it does just it does just that right. It receives the props these structures that to pull out the posts. Then it renders this post list component. And that's the one responsible for you know showing our posts. On a list here. So I'll control click through to that so we can see that so post list is pretty simple. It's just a UL here and we map over each of the posts. And you know put one of make each one of those in Li with a postcard inside of it and I'll click through to postcard. And likewise, it's pretty simple too. Right just destructures the posts prop it gets to pull out title excerpt URI featured image and then just has an article tag and renders some of the content, you know of the of that blog post like that. So that's how the blog post is written here. All right. So our job is to change this is to rip out this dummy data right here in Fetch actual data from a WordPress backend and use that actual data to render the list of posts. We'll see these change instead of the Latin titles here, you'll see this page re-render which once again working with the actual, you know, blog post data from our WordPress back end. So that would be pretty cool to get that up and running. All right. So we've looked at the blog page now. Let's take a quick tour through the single blog post page. So I'll click on one of those and we'll see, you know, an individual blog post page here sort of front-end app. That would be inside of pages. I'll go to this dot URI. JS file here as well. If you're not sure what this is like why the brackets are here with the dot dot is just the next JS convention. So back in our slides the on the link. Page here. You can see you can see their documentation. So like number number six here if you're wondering like why we created that dot env.local file and I said that we are storing an environment variable inside of that if you're wanting wondering like word that come from why are we doing that? This is the answer here number six, you know shows you in the next track box how to create environment variables and likewise if you're wondering, you know, why how the routing the file based routing here works like with the this catch-all route URI, you could check out the next yes docs to see how that that all works. But basically this just is a catch-all route. It tells next yes anything that doesn't match one of the other ones like slash blog or slash search if it's something else use this as kind of a catch-all to render our other pages. So we're using that ourselves to render our single post page. So back in our front end application. What it does is very similar to the last page so you can see that we're importing post from our dummy data and then down below inside of get static props. We're passing in you know, that single post as the props that are component should receive and inside the component or destructuring post to pull out date title content author and so on and then using that to render our list here. So with layout component which just gives the page a bit of margin and padding and in a Max width and so on and inside of that we have article tag with all this stuff so you can see that here's the title of the blog post. Here's you know, the the author's name on. and then a formatted dates that's where we get this kind of meta information here below that we have the content of the blog post, you know, all of this HTML it gets rendered out and then at the very bottom we say if we have categories then display a categorized as Heading let me scroll down here categories as and then you know map of each of the categories and just display those on the list. That's how the single blog post Pages written. And I'll keep on cruising here in the chat. Let me know if any of this is is confusing or you know needs a little more explanation. So we've seen blog. We've seen a single blog post. Now. Let's look at the search page that might be interesting. So here's search and it is broken you might notice that this doesn't work at. All. Right. And again, that's because this is all just dummy data. So if right now I type The word the for instance I can. Click search and submit this form all day long, but my data, you know isn't going to change and that's because this is all dummy data at the moment if we open up our search page. We're pulling posts yet again in from our dummy data. and yeah, and then using that so inside of this data object, we're building where it's passing in. The posts and further down we have our form at the top here for the person to type in the search term, you know that they want to search for and then below that and we're rendering things. So right now it's broken because we render our post list and then we give it data post that nodes. You know, which ultimately came from our dummy data file. So that's where that's why this is all just dummy data. Once we get done with this file. It'll it'll actually work as expected. So you'll be able to type, you know a particular word within. One or more blog posts here hit search and it'll fire off a request from the client to the WordPress backend and then re-render the list to show the matches here. So that's about it for the for the tour. There's a category page. We didn't look at but we can say that for later. That's Here if you click on a single single category, we do also have this page where it shows just the title of that category that you're interested in and then the blog posts that that are assigned to that category. So we'll build that one as well. All right. Yeah, so with that I'll pause check the chat chat right now. So I just see a bunch of Thumbs Up So I must be doing fantastic. But please let me know. Like I said if anything needs more explanation. Let's see. All right. So Alex, it's a good question. Alex is asking where is the xss protection handled? So access is cross-site scripting. So that's a good question react escapes HTML. on its own so when you go to render something with with react if the string contains HTML, you know certain HTML characters where a cross-site scripting a cat Could Happen. We're like some Rogue JavaScript running on the page like a Chrome extension or something. You know, if that Chrome extension is trying to inject content into the page and there's some unescaped characters react does handle that. However, when you're dealing with a CMS, sometimes there are other other considerations you have to make you have to tell react to to just trust certain content content if that makes sense. So since we're on that topic, I'll just do all in this for for a second here. So one example would be the content. So back on our single blog post page right here. I mentioned to you that all this HTML for the content came from WordPress. So if we didn't trust this data You know, if we if we wanted to Pat give this data to react it would try to escape it as it usually does. Let me show you what that looks like. So if we just passed in content like this. You say that see if we can get it every render. You should see a bunch of HTML tags. Yeah, this is what you're at your your site would look like right because this is the HTML. Content that makes up that blog post. So this is what it looked. Like if you let react do its escaping that it usually does it Escape all this HTML here. So you have to decide for yourself like do I trust this HTML that came from I see CMS, you know, and hopefully hopefully you do WordPress is Is used by millions of people and has lots of eyes on it in terms of security. So it I would say it can be, you know, trusted to the output HTML of it safe. So a few options and if you decide you're going to trust HTML content and tell react not to escape it on the page. You have a few options one would be to use Dangerously set inner HTML. I'm sure some of you have seen this before. so react yes, if you do this, if you if you have a self-closing div like this and you say dangerously set inner HTML and then inside of this you pass in an object with the key of double underscore HTML colon and a value of whatever that HTML is in our case that's content. Like that, this will be one way to handle it. So this tells each this tells react. Don't try to escape this, you know HTML for cross state scripting protection for instance. So if I say that and then look at it now you can see you know react is it's bypassing that That escaping and just rendering the the markup that I was given. So this is one way to do it in our application. I was letting a library I do it. I have this HTML react to parser right here, which comes just with a parse function. This is another way to do it instead of you know doing it yourself with the self-closing div in our application. I was just running the content through the parse function. That this issue that this react based. HTML parser uses to escape that All right. So Alex, let me know if that answered your question. So it is. Say a WordPress does its own WordPress does its own escaping of HTML that it produces and your front end application? You have to tell react. Hey this this thing, you know the string that I'm about to put on the page. It's already escaped HTML. I trust it. So don't try to escape it and just render it. All right, cool. Cool. Yeah, excellent question there. All right, so let's keep going then. So we just got through with our Tour of the finished application, right? So let's let's dive in deeper. Now the next step on our list of things that cover is turn WordPress into a graphql server with WP graphql. So I'll show you all how to do that. But we won't actually you won't actually need to run a WordPress site yourself and your machine instead would use we'll just connect to WordPress site that's live on the internet. So you can see here. I'm I'm using a free app here called local for running WordPress sites locally on my machine and I will just start up like one of these. Sites and then go to the WordPress admin screen. So let me log in. To this site and I'll just show you a couple things. All right. So here we're in the WordPress. Admin how to turn your WordPress at WordPress back into a graphql API is by enabling that WP graphql plugin I mentioned so that's here. You can if you don't have this on your site, you know, you just click add new right here and go ahead and search the WordPress plugin directory for WP Graphql and then just find it on the list. So there it is WP graphql. So you would install and then activate that and you'd see that on your plugins list. Right here. All right, once you've done that that gives your site a graphql endpoint that you're decoupled front end can hit so if you're wondering well, what is it? Where is that graphql endpoint? Right? What you do is in the sidebar here, you can go to graphql and then on the settings page right at the top it just shows you. You know what the graphical endpoint is you could customize it, but the convention is just used slash graphql here. One note too. Anybody who's if you're driving some notes you want to do this on your own on your own WordPress site. One thing I would make sure to do on this page is on your local environment to enable graphql debug mode here. This is hugely helpful, where in your front end application if some queries you're trying to fire off our failing instead of getting very opaque unhelpful. You know debug messages coming back if you enable this and you'll get you know much more much more helpful debug messages. So just a note there. If you're running WordPress site and doing this kind of kind of thing definitely enable debug mode. It'll help you out on your local. So let's look at this endpoint. Then I will go ahead and command click on this to open it in a new tab. You'll see I just get a Json response back. If I try to visit this directly in a web browser just says graphql request must include at least one of these parameters query or query ID or whatever. That's because I haven't provided a query right? All I did is Is send a get request in a browser to this endpoint but didn't provide any data. So this is the expected output there. All right. So that's how you do this on your own WordPress site for us though. We're going to use. A predefined graphical endpoint. So let's see. It's only close this. this stuff we don't need to look at that anymore what we're gonna use instead is This endpoint here. So speed number five on the list of of links if you go ahead and open that in a new tab. Oh, there you go. So I should just send you to this content dot dotographical.com slash graphql. So this is the endpoint we're going to use so that you don't have to worry about running your own, you know, local WordPress site. If you notice this is the same one that we had popped into our DOT env.local file here, right? That's where this this came from. So we'll go ahead and use this for the rest of the workshop, you know as the site to pull our WordPress data from all right sales number two. That's how to turn WordPress into a graphql server with the wp graphql plugin It's All Pause here. Check out the chat. And see if there any questions here. Let's see. So is it safer to avoid dangerously set inner HTML and instead use a parser library in most cases? No, if you if you look at some popular like parser libraries that are out there including the one we're using in this project. They themselves use dangerously set inner HTML actually. So if you like under the hood at the source code of those they might try to depending on what the HTML looks like. They might try to render it another way but as like a last resort or fall, but fall back for rendering the the content, you know, they themselves would use dangerously set inner HTML to to achieve the same thing. So so no, I wouldn't say it's it's more or less safe. A parser can be helpful if you want to swap things out. So let me take you let me do a Show you a quick detour here. So I maintain this site with my team at work developers.wp engine.com. We have like lots of resources articles videos and all kinds of stuff on doing this kind of thing doing headless WordPress. And so one of the articles that I wrote recently is on working with Gutenberg data, and it kind of speaks to this question. That we're talking about right now. So it's this blog post. I wrote Gutenberg and headless WordPress colon render blocks as HTML. So if I open up this blog post page, I'll show you one. How are syntax highlighting is actually broken at the moment. This is a bad demo. I'm sorry. But anyways, this is the section I was I was thinking of so use a parser to convert some blocks to components. So this is something that you might be interested in. So like in nextgess. It you know, you want to use the next yes link component for instance so that you get the client side navigation for any internal links. But out of the box what WordPress will give you, you know, if you have any internal links inside of your your content, it'll give you just a regular anchor tag, right? So the result is in your front end application. If someone were if someone's in the middle of reading a blog post and then they click something that's an internal link if that's just an anchor tag, you'll get a full page reload, right? It'll still work. It'll still send them to the next page but it defeats the purpose of using a single page app framework like next JS. It's capable of doing the you know, really quick client side navigation. So in this blog post I go through how to swap out, you know, those anchor tags for your internal links how to swap those out with link component so that you get the nice quick client side navigation. So that would be one example of like when you would want to use a parser Beyond just escaping HTML like we're doing like we're doing here so I'll put that I'll put this blog post. At case of any of you are interested in. What I'm talking about this post can be can be kind of helpful. Yeah, I'll just put this site there as well. If you're interested in any of our like walk through videos and so on. All right, excellent questions. Let's see. So M as another question. Does this endpoint cash queries? This is an excellent question as well. So WP graphql that we're using. Here is what we're using for our API layer right to allow WordPress to talk back and forth through our next us front end it. it when you had a phrase this it can leverage any any existing caching Solutions. That you know that you can use on the WordPress backend such as redis or memcached if either of those are used like an object cache then WP graphql will also see speed gains from that. So if you have a certain query that, you know, every user who hits a certain a certain page of your site if you have a certain query that's always run then what redis would do is it would see that database query and then cash it in memory. So the next time a request comes in it would serve up, you know the response to that from memory, so it'd be much much quicker. So yeah, you can use, you know, existing caching database caching Solutions like redis or memcache those would work to cash and speed up your graphql responses. I'll go a step further though one really exciting thing is Jason Ball who's the creator and maintainer of geographical and another guy Mark they're working on a feature called persisted queries right now for graphical and this is gonna take the caching story to the next level what this looks like. Is a request comes in for a query and then and then after it gets resolved that gets saved in some kind of it. It could be saved in memory cash like redis or memcachd but beyond that that the Json response is stored can be stored like on a CDN. So that means you could distribute, you know the responses to your graphql queries, you could distribute them all over the world at data centers using a CDN. So that means some user who's in Tokyo, you know in Japan or something if they're trying to visit your site and firing off a graphql query that query would hit their local data center, you know within within Japan see that. Oh, we have a cash response for this this query that's still valid, you know immediately return that so this round trip, you know going to the origin server wouldn't even be necessary anymore, you know, just serve up their responses right from the nearest, you know CDN data center. So that's right up your graphical is headed which is very Exciting to me. This would be what I'm describing is similar to other Solutions like like graph CDN is a popular product that does this kind of thing where it takes graphql responses and then caches them like across the group globe and a CDN, but pretty soon native support for that that kind of thing persisted queries will come to wgrfql. So I'm really excited about that. That'll make like I said pick the caching game like to the to the next level so so stay tuned for that. If you're interested, you could you know, follow their the blog here or follow the Twitter account for updates. All right. Okay. I think that's it for questions. Let's keep rolling on the conference. These are excellent questions. So thank you so much. Let me know if you have more. All right. So what have we done? We did tour of our app we've seen how you can turn WordPress into a graphql server by using the wpgraphical plugin next. Yeah, get set up for local development. So some of these sites some of these steps we've done already right? That would be These steps here in the readme so we walk through these already. Yeah, so we're good there one more thing. I'll mention though. Is this bottom section here checkpoints. So this is very important for our Workshop. Let me blow up the text a bit. So this says you can check out these commits and get to get caught up if you fall behind at any point. All right, so as we dive into the code and you're actually you know meshing on the keyboards making these updates to the site trying to get get things to work. If you fall behind at any point in the group is, you know done with one done implementing one page and we're ready to move on to the next one and you feel like you're kind of falling behind. It's not a problem at all. What you can do is just run on the command line run get check out and then just paste in this Commit hash right here and that will get you up to date. So the first one here would be this is the commit. After we create the blog index page, this is the commit for after we create the single block post page and so on. So if any point, you know, you feel like you're following behind just just don't feel bad at all. Just go ahead and check out this commit and I'll get you caught up with the rest of the group. All right, if everybody follow the steps, you know, you have your env.local file there and you run it and npm run Dev. You should be You know in the same same spot, I am here looking at the front end application can anybody in the chat you give me like a thumbs down or something if it's if it's broken and you you weren't able to boot up this application? Just let me know. I'll stay tuned for those. All right, so I think we're set up for local development here. Next thing is configure Apollo client. So if you're doing this on a real world project, I recommendation would be to use some kind of a graphql client in your JavaScript application that makes so somebody asks the question earlier about caching and the answer I gave was about like how to cash responses they come back from the server. Apollo clientele will do a different kind of caching and that's in memory caching of of queries on the client. So that means so the reason the reason that's cool is if somebody is on a certain page in a query is fired off and they are a responses received. Let's say they navigate away from that to a different page and then they come back to that page. Right. What Apollo will do is it'll it'll see that some data is needed and then check its own cash and say oh have we fetched the same? Yeah, have we fished the same exact Data before if so, just get it immediately from the cash and render that component, but if not, then it would actually make a network request to fetch the data. So that makes it nice as the client navigates around the or as the user navigates around the site. Apollo will just pull things from its cash if it's already gotten that data before and then only take the time to do the request if it's if it's either never gotten the data before or it's too old, you know, it's the cash is not valid or whatever else. So the caching is one big feature, but there are other reasons why you might want to use a client like Apollo Apollo client. So so go through like how to configure that this would be the next step for creating a headless WordPress site. So in our Links Page here, if you open up number four is the Apollo client get started docs. They're really only a few steps to this, but I'll show you like what you would need to do. Here. All right. So this page says get started with Apollo client and it tells you that you need to install a few packages. So you need to do npm install Apollo client and then graphql. We've already done that in our project. Here, but if you hadn't, you know, you need to install those. Next step is to initialize Apollo client. So you need some code that looks like this. Let me blow this up again. There we go. So you need to call new Apollo client instantiate a new client and then just give it a few pieces of data. You tell it here's the URI for the graphql back end that I want to use for pulling my data from here's the kind of cash. I want to use so here we're saying store store the responses in memory. So use the in-memory cache that Apollo client has So this we have set up in our app is what as well. I'll show you where that was done. So if you go to the underscore app that JS file on our code base. This is where the provider lives. And let's see I guess yeah, we should open this one. All right, so inside of lib and then Apollo client what I did was I just created this apolloclient.js file. It is pasted this in really. Here and say, you know, I just did the same thing something we want to instantiate a public client. We are going to use the in-memory cache about Apollo comes with but for the URI, you can see that I'm pulling it from our next public WordPress API URL So what this does is it tells next yes to pull it from our environment variable file. So remember when we create dot emv.local we specify this next public WordPress API URL and then gave it something there. Inside of this file. We're just pulling pulling through that value. So this allows you to have that be dynamic. So what you could do is like on your local environment, you could have this set to one endpoint, you know, or maybe on staging because staging site you can set this to the graphql endpoint of your staging site. So that's what it would use but then on your production environment, you know, it would it would reference the graphic on point of your production site, for example, so that's it using using this in your code why that's useful because depending on you know, which environment you can pull from a different WordPress backend. So that's kind of the setup that I would recommend there. So after creating that file and just exporting that client that we create we have to actually use it. So in the Apollo Docs if I scroll down A bit here. It just says connect your client to react. So it tells you to do something like this where you have this Apollo provider that it gives you and expects a prop of client where you just pass in this client that you created. That's exactly what we do in this app and underscore app. We just import Apollo Provider from react and we go ahead and wrap our whole application in that and then pass through the client. So that means so this under the hood. This uses react context. These are the context API to make this all provider available across your entire thing. That means you'll be able to run graphql queries on any page or from any component. So that's really it once you've done that you've passed through the client you've created as a provider then from then on, you know, we'll be able to run all the queries. We need in our Pages here. Yep, so the docs go more in detail about how to use some of the hooks and things that Apollo provides, but for now for our setup, that's really it what we just just covered. Alrighty, so that was it for all the setup steps. I know you I know you haven't dove into the code and actually built anything yet. So hopefully you don't you don't mind that and you've been kind of patiently listening through this stuff. But that's where we're headed that the very next step is. Let's dive in and start coding here with with step five after we've done like our our setup stuff. So I'll pause there and check out the chat from it. See if you have any questions. Okay. Yeah, somebody joined late and just needs the link to the slides and somebody else provided it. Thank you so much. Let's see. So Victor asked why didn't you use typescript? So typescript is awesome. but for this for a project This simple I would argue it's not not really necessary. There's very little going on. You know, we're just fetching data from from a back end and then rendering to the page, you know, it's not highly interactive and it's not like a large code base where you would lose track of which objects have which properties and so on that's when typescript in my experience has been typescript really comes in handy is really valuable where you have a large complex project, you know, and you want that you want that type checking to happen to make sure you're not overlooking things or making mistakes for a workshop like this though. I don't want people who are new to who might be new to like react or modern JavaScript. I don't want to add an extra layer. Another reason not to use typescript in this demos. I don't want to add an extra layer of complexity for them to deal with, you know, if they are just trying to Trying to trying to learn like how to query afford data from WordPress back in a render to the page. If I add oh and you have to add all these type annotations everywhere, you know, that might be a bit confusing for them to learn so I would say like if typescript if you do have a complex project where type checking would benefit you definitely look into typescript and you know, you can take the knowledge that you you gain in this Workshop as kind of a first step or a foundation on how to do has this word WordPress. And then once you learn typescript, then you can layer typescript on top of this and add, you know, you type annotations to get the the benefits of tech. So yeah, that's that's why we're not using it for this project. Somebody asked else asked. Why is Apollo client needed in a real-world project but not on the current example. So this app? Does use it or will use it as soon as we wire it up? So that's kind of our job. So instead of blog right here. You can see I've I'm importing two things that we're not using yet. So like on our blog page on the site. I'm importing gql from Apollo client and also importing the client that we created inside of this lib. In a folder right here this thing that we saw I'm importing both of these but if you notice we're not using these yet at the moment and that's because our data is just coming from this dummy data file. So our job will be to rip these lines out so that we're not using W data and actually use, you know, Apollo client to do the data fetching. So so that's helpful. So so yeah, that's where we're headed. We will be using Apollo client for for this project All right. Great, I think that's about. It for the chat then so let's keep rolling. All right. So on the slides we have composed a graphql query using the graphical IDE. So one thing that's easy to overlook here is the eye in this word, right? You might glance at this quickly and think oh, it's graphql. Actually not it's graph iql pronounced graphical, right and graphical is a popular Javascript app that's used for composing graphql queries. Um, let me show you one. I'll show you one example of it. So remember this, you know WordPress site that I had started up earlier just to show you what it would look like to install and activate the wp graphql plugin. If I go back to the WordPress admin, it actually provides a graphql IDE for you right in the WordPress admin. So if you do this on your WordPress site, what you would be able to do is hover on graphql go to graphical IDE. And it gives you this really nice IDE environment that you can use the composure queries. And it's going a little slow here. This is not a great demo. What's happening? Okay, I don't know why that it took it took long time at that time to load up. I'm not sure why but this is what graphical looks like. So it's it's really helpful, you know app for composing queries so you can do stuff like this. Let me show you if I go to query composer and I open this here you can Give your query a name. So I'll say, you know, get posts like that and then inside of this you can. Make sure you can start you can see the whole graphql data graph and start checking boxes indicating like what data you want back. So if I wanted blog posts you can go posts. And for each of the the nodes of that post I want back. Let's see. so the date of that blog post and the content of course, we're gonna want the title of the blog post which would be here. You can see that as I click these boxes. It composes the query for me in this pain right here, which is which is super handy. So then once you've selected all the fields that you think you want for this page of your front app that you're building and your query looks good. You can hit this play. I can't icon to execute this and see on the right hand side what your friend Javascript app would get back if it were to fire off this identical query. So let's do that. I'll hit the play button. And there we go. So here are the note the post nodes that I get back since the each of these objects is here's the date. Here's the content of the blog post. Here's the title of that post. So this is super handy, right? You can keep keep modifying this and keep checking boxes until your query looks good. And the data coming back is what you you need for this particular, you know page or component of your front end app. So once you're happy with it, thank you. Just highlight all of this this query that you have had written and paste it in your front end app. And that's what you tell Apollo to fire off and then you you know, you know the shape of the data that you can expect to come back. This is super handy. So this is one example of the graphical IDE that the wp graphql plugin gives you so you can use it here right inside of the WordPress admin for us though. We're gonna use a free hosted version of graphical to build our queries. so back on our Links Page, that would be number seven here. So if you click on number seven on the Links Page and open this up. That'll send you to this page to unlock graphical online.com. This is a cool little Free hosted version of graphical that you can use so for us we can guess what are we gonna use for our graphql endpoint URL here? If you guessed the one from our EnV file you win you are correct. So let's do that. We'll copy this whole thing from the.emv.local file. That's the graphql endpoint we're going to use and we'll paste that here and then hit this button. Alright and you can see it looks pretty similar to what I showed you in the WordPress. Admin, you know, we still have the query Explorer. You still have this area to compose our queries and in this area to see the results of those right? Yes some other options like to cheat to add headers or whatever if you'd like to all right, so we're set up now to use that endpoint to this content site. and if you're curious, this is what the that wordpressate actually looks like so if we try to Just go to this domain. You see that it's a it's a WP graphql. WordPress site, it looks like this if you like WordPress handle the rendering using a particular theme. I think this is like the What 20 20 22 theme or something like that? Then this is what it would look like instead. What we're doing is saying we want to hit the graph the graphql endpoint to get just raw Json back because we're gonna handle all the rendering in our next Jazz app. So that's kind of where that came from. All right. So back in the hosted graphical here. Let me know if you all were able to go to this link and then paste in this graphql endpoint because we're going to be spending some time here composing our queries. Can we give me a thumbs up if you made it to that point? In the chat and you're here. All right cool seeing some symptoms up. All right. So let's figure out what we need. Here, so going back to our to-do list. Where were we here? All right. So compose a graphql query using the graphical IDE. So let's actually do that. Right. We'll dive in now and do some coding. so as I showed you before you you could check some boxes here to compose these queries so we can go to posts, you know, and it starts building the queries for us or I'll show you how there's another auto complete feature. Um, so everybody let's try to do this just this together here. So everybody opened the Explorer if it's not already open you can hit this button here. To open the graphql graphical Explorer and once that's open scroll down until you see posts. Right there and then click to expand posts and they're going to click again on nodes because we're interested in getting each of the individual post nodes. So click again there. So you should see this the queries, you know, it starts composing the query for you. And we're going to get a few pieces of data. so just pause bear with me one second here. All right. So let's start getting the data that we will need for our blog page. You want your second get set up here. Okay, I think we're ready. All right, so back here. We were going to do posts and then nodes and then inside of there. We're going to need. some pieces of data I'm sorry one. I checked out the wrong committed my finished app that has the fields. I'm using a cheat sheet here. There it is. Okay. So now I know which feels to tell us to query. All right. So the queer we're going to try to compose here is the one we need for our blog post page as a reminder. That's this one. Right? We're gonna compose a query to tell Apollo client ultimately tell dope geographical that the query we want to run is for the most recent blog posts here. So, let's see how we can build that. All right, so we'll need post nodes and then inside of this we're going to We're going to check some boxes. So I'll do the first one I'll do is database ID. So inside of nodes if you scroll down and find to the D's and click database ID, you'll see that it pops that into the list next. We'll get the title. Let's scroll down to the t's And click for title, right? If you like this workflow of clicking in the boxes or checking the boxes, you know, this this works great. Another trick is you can use control space. So I use this a lot. So for example, if you're like nested if your curse there's nested like this. Somewhere inside of your queries. I'll hit enter to get a new line and from here if I hit control space I get auto complete here so you can see I can use in the arrow keys. I can go up and down and then as I type this list will get shorter and shorter, you know, try to auto complete the thing I'm typing. So the next thing we're gonna get is excerpt so I'll try to type that so if I type e x you can see already, it's near the list down to exhibit thinks I'm you know, it thinks it knows what I'm trying to type if the highlighted one is is correct. That's the one you want if you enter You see it pops in excerpt for you. So this can be a quick way. I find that if you're somebody who doesn't if you feel like you don't know what the graphql schema looks like very well that WordPress gives you then the checkboxes are really handy because you can visually see all of them. Otherwise, if you've done this kind of thing before and you're somewhat familiar with the graphql schema, that's when doing, you know this auto complete to just drill down to the thing that you want quickly. That's when it is more helpful, I think. So we'll get excerpt the next thing is URI. So you are I That's the URI or your the URL of the blog post. For example. The next thing we'll get is featured image. So this one it will have some nested Fields inside of that. This is our first time seeing this so here's featured image in the Explorer and you can see that it. Is a drop as a drop down here. So if I expand this here's featured image. It tells me. It's gonna throw in there saying oh you need a selection of subfields inside of this to tell it to tell graphical, you know, which Fields you want. So in our case, we'll just get a few of them on. The featured image node, so featured image and now click on node. Like that, so you should be at this point and then inside of node. We're just going to get two fields. So the first is Source URL. So there you go. So scroll down to the S's and then check Source URL. So that's the URL where this image actually lives this actual, you know jpeg or ping or whatever. That's the URL to it and then for accessibility reasons, we need our alt text as well. So I'll scroll up. And click the checkbox next to alt text just like that and this is really it for for our query here. Yeah, I can show you. We'll pop in maybe one variable just to specify the number of pages. But for now if you've built this up go ahead and click the play button to execute this and then see what you get on the other side. You should be looking at something like this where you have each of the post nodes and then inside of there you have. What is the database ID? What's the title? What's the excerpt URI it featured image for some of these you might notice is null right? You might think. Oh, is this a mistake? This is a bug or something, but it's not all that means is this particular blog post doesn't have one. There is no featured image attached. So we'll need to account for that in our front end JS app we'll need to say you know, is there front end. Is there a featured image? If so, then go ahead and you know render to the page. Otherwise if there isn't one then don't attempt to render it, so I'll have to account for account for that. All right, and graphql is super cool because it is very explicit about what every single value could possibly be. So if you if I hold down command, I want to Max if I hold down command and then click on. featured image Right here. It pops open the schema documentation and you can see you know what the type of this thing is. So the type of node. right here for Featured images is this media item Type in graphql and if I click through to that you can see all of the fields that it has. So here's like, alt text all the types that all texts could possibly be so it's always a string for example, but other things in here, you may see that well, it could be it could be null sometimes other times. It could be a string and so on so it's very it's very handy for you know, the fact that it's so explicit so you can know exactly what the possible types are in your front and JSF. All right. So this is this is it for composing our first query with one exception like I mentioned let's pass in one variable here for how many posts so the default is 10, I believe so this will give us 10 blog posts. Let's say we want a few more on our front end app. What we can do is pop open some parentheses here. So after posts pop up with some parentheses and you see our options at this point are after before first last where so you do some like pagination and some filtering options. If you want to only get certain posts. So in our case, let's select first and we'll say we want the first 18 posts instead of just the first 10, which is the default. We'll just bump it up a little bit. So you want the first 18 posts if we're doing pagination we could say after and say get the first first 18 after You know after the one on page three or whatever for further on list, but just to be explicit we can say after null meaning start at the at the at the beginning, you know with the most recent post. So we'll leave at that just to be extra explicit. Let's say after null So reading a post the first 18 of them after nulls or starting at the beginning of the list. So now if we fire that off we should get 18 or however many there are if they're only if there are only two blog posts that you might only see two on this list, but we're getting all of them up to you know, Max of 18 there. All right. So let's I'll go to the chat again. Let me know. How you're doing? Can I get some? Thumbs up, you know I'll do dividing line in the chat. There we go. Okay some thumbs up if you're able to compose this query and then check the box to execute it and see the results on the other side. All right, cool. Great. Yeah, so this is a query that we need in our front end app and there were gonna use to fetch our data. So this is exciting. Let's actually make use of that now so pop back open vs code or whatever code editor you're using and like I said a few times our job is to rip out the dummy data and get this actually working with, you know, real graphql data. So let's do just that it's our front end page. Bye-bye. Friend pager. You're gonna break. Yes, we do this right. So I'll have you highlight these lines with the dummy data and delete them and then as soon as I save that Your friend Apple crash and burn if we try to reload it here since it doesn't have the data it expects. Right? So let's fix this by giving it the actual data from the WordPress backend. So show you how to do that now. So what we need to do is use this gql. It's this is a tagged template literal is what it is from Apollo client inside of that. We're going to Define what our query is. So let's do this right above where the blog component is type this we'll do const. And then get posts in all caps just like that equals G Q L. and then two back ticks just like that and then a semicolon after it. So if you read through the documentation on Apollo client, it'll you'll see this convention use it tells you, you know to use this gql tagged template literal and then pass inside of the back text the query that you'd like like to run. So that's where this is coming from. So inside of the back text, I'll just hit enter. Which way twice to make a little space and what we'll do is we're going to return to graphical and copy this whole thing that we had composed. Right here. I'll copy that and then paste it between these back ticks like this. I'm getting syntax highlighting here because I have a certain vs code extension installed. I have this one Apollo graphql. So if you you know, if you like working with with graphql and Apollo and want the syntax highlighting Within These gql tag type of literals and other features, then you could you install that if you want the Apollo graphql, but otherwise if you're seeing a solid, you know salad text here if it's all white to whatever that's still fine. I'll still work work. Just great. All right. So we've defined the query that we want here maybe one other change instead of just calling it my query. I like to be a little more explicit. So we'll just call this like get posts like that. So then if if in the browser console Apollo client is like throwing errors or whatever. It's referencing a certain query that's broken does the name that we'll see It'll say the name of the query that failed is get posts. So we'll know you know, which one that is. That's why we we give it a name there. All right. So this is it for defining our query by. By Crane's query passing through gql that'll that'll turn it into what's called AST abstract syntax tree. That's ultimately what Apollo client, you know expects to receive and can use to to process the the query. So with that we actually use this const we've defined here, right? So that would be the next step. So let's do that. We'll scroll down a bit. So go to get static props here. And anybody's not super familiar with nextgas get props is the next Jazz convention that they give you they say that if you export any sex async function from you know, your component file called getset props, then anything inside of this next just will run at build time. So it'll affect you any data fetching and anything you want to do at build time and then pass these props through to the component when it when it renders on the next JS server. So this is not something that the site visitor or whatever have to wait for. You know, this is done ahead of time when the page builds. This is a perfect spot for us to do our our data fetching. So we're gonna make use of our client that we had created that so at the top of the file. Remember we had imported this client from lib a poly client just like that. That's the thing we're going to use. So at the top of this we'll just hit enter a couple times. And then we'll Define another constant. So do const response. So type that equals well, wait await the response of this so we'll wait client dot query. All right, so I'll start with just that. So this means we're taking the Apollo client instance. We had created and then calling the dot query method on that and we're going to pass in info about the query that we would like Apollo to run and then we'll get the response back. So inside of these parens then we're going to pass in an object. So go ahead and open some curly braces like that hit enter. And then we're gonna say query colon. And this is where we pass in the query. So for us that was get posts all caps just like that. so that passes in this query that we had built up at the top. All right. So once you get the response back from that we have to actually make use of it. So instead of this post posts thing so delete that and then instead we're going to drill down to our blog post we're going to do a response dot data dot posts dot nodes. Just like that. I'll give you a second to tap all that. So if you're running your app, like how you would know to drill down that far graphql is really cool in that. How you like structure? You know that the levels of nesting here how you structure your query did the response it comes back will match that which is very cool. So if you look at here, we had query posts nodes and the field the response is data post nodes and then the fields Right, so it follows that same structure. So that's where this posts and the nodes comes from it comes from our own query because we said what posts and then nodes right? And that's where our our post would live. All right. So we're trying to drill down to each of our individual post nodes or passing that as a prop called posts into our component our component then is destructuring that pulling out that list of posts and trying to render our list of posts on the page. So I will save this file. And then return to the front end and we'll cross our fingers. As I am, there it is. It's working so you can see no more Latin. We had the Latin titles, you know with our dummy data no more Latin titles. This is the actual live, you know data coming from a real WordPress site. So this is super cool, right you can see we have the titles in excerpts being displayed here and these are linked. So if I click on one of these and I'll try to send me to you know the single page for For the blog post that I had clicked. And we specified a Max of 18 as well. So if you count these up there should be you know, 18 of these. Once you get more advanced, you can do pagination stuff where you could even either do infinite scroll or just load more in right away when the user Scrolls down or have a load more button and load more. But but for us we'll just we'll just stop here and display the 18. All right. So check the chat real quick. So Vaca, I see so type error cannot read Property Data of undefined. Okay. So it sounds like that's coming from. this point in in the code right saying that you're trying to drill down to data, but but response this thing is is undefined. Let's see. I don't know why that would why that would be one of the first things I would I would try is just you know console logging. This I'd probably just do. You know console log. The response here say that and then if you open the terminal you should see. That data printing out. So I'll try to reload my blog page. We'll see if it prints out. Yeah, it does. So if I try to reload my blog page with that console log statement in place, you can see that this is what it prints out for me. So you need data posts? And inside of that there's my you know array of nodes and a few other things loading false Network status seven. So this is what is expected in that response. If you're if you're getting something different than it must be an issue with Apollo client, you know not being configured. Properly so I would just do some checks like make sure on the on the repo here make sure you did all of these. steps just right and you're defining this environment variable inside of the Dot Envy file and just like this I still exactly like that. Yeah, and that you know, this is tight typed as it should be just like that. So hopefully that's enough if you're not able to get it working. Then you can always use this checkpoint here. So so we're done implementing the blog index page. So so vodka in the chat or anybody else if you you know, we're struggling here and had issues getting the blog post page working at this point. You could run get check out and then paste in this commit hash and that should get you, you know back up just up to speed so you should be able to to I would try I would try get check out, you know that commit hash and maybe doing commits command C or sorry control. So you just to just to kill the next year server and npm run Dev again to get that back up and running and at that point you should see you know, the blog page working like this. All right. Oh amazing fixed good. Happy to hear it. Cool. Okay, we'll keep rolling then. So hopefully you're all having fun. So number five was we saw how we could compose a query using graphical. And we accomplished number six as well implement the blog index page by using that query. We had composed we told next yes to run that build time and then type that you know as props into our component use that to render the page. Right. So on to number seven now so implement the single blog post page. so as a reminder, let's open get rid of my debugging lines there real quick Okay, as a reminder, let's just take a look at our single blog post page. That was this dot dot URI catch-all. route here So if you go back to that. We will see. Yeah, we'll just remind ourselves what this looks like. So again, we're pulling out the dummy data. You know called post. And inside of get static props, we're just sending post through. You know as the as the props and that's what we're using to to render the content. Let's just dummy data at this point. So here we'll follow that same pattern where we're going to, you know, rip out our dummy data and then go build a query to use instead. I'll go ahead and delete. That dummy data and it's head back to our hosted graphical instance here to build another query. So one cool thing I'll show you is you can Define multiple queries here that's allowed as long as each one is named like this one. We called our You know get we had called our get posts query. Like that and you can have multiple here as long as they each have a unique name so you can do query get. post singular and then have inside of here. have You know. Have another query and then when you go to execute it graphical, which ask you well which one you just drop down say do I execute use post or use posts? And you just tell it which one you want to run? So that's one cool way. If you don't want to delete, you know, the thing you had worked on building the first time if you want to kind of leave it in place or you're testing or whatever. It's okay to have multiple as long as they unique names and they can run them each of them for us though. Let's just delete these and start from a clean slate. So this one will be this will be a fun one because it'll be a our first graphql query that accepts a variable. So in the last one, we just said give us the first 18 blog posts. And that's it. You know, I guess technically we had a variable because we said, you know, the number 18 is how many we want but this one will be a real variable where we'll pass in the slug the URL slug. The user is visiting. We'll use that to look up the particular blog post. That's the correct one who's data we need if that makes sense. Let me show you I'll just let me just put the data back for a second just so I can show you what I mean. So happens is if somebody is on the blog page here and then they try to click through to one of these posts. Is the URL structure it sends them to? You know, we have like the date here and then adding end to end test to Wordpress. We have this whole thing, which is called the slug in WordPress. So we have like this date structure and then the slug after it and this whole thing all of this the date plus all of that is called the URI, and that's the thing. We're going to actually use to look up the blog post. We're going to tell a WordPress. Hey find the blog post that has this whole thing as its URI WordPress will find it in the database and then provide the title content, you know all the data that we asked for. So this is what we're going to use as our variable we send in to to our query that we're going to build here. All right, so let's do it. Okay, so here. Let's create a new query to get a single blog post then it's over in the court over in the graphql Explorer. Let's go down to the P's. Element. Oh P and find post singular. So click on that and already you're just like last time you'll start building the query for us and even knows that post requires an ID because yes, oh well, which which post do you want so we'll have to address that here. so for the ID Yeah, you could if you want it for testing purposes, you could pop in a value here. Even if you type a value then that's the thing. It would use as the ID for us though. We want this to be dynamic. So it'll pass in a different, you know variable for each each blog post. So I'll just I'll just leave that off for right now. I'll show you how to turn that into a variable. Actually, I guess we could. I guess you could just use this one. Let's see if we can get that working. for demo purposes All right. So if I say that's the ID and I have curly braces. As I get the title, is that actually work. Yeah, it doesn't. Yeah, the ID isn't so let's not attempt to do that right here. I'll leave I'll leave ID blank for now. We'll just focus on the fields that we need. So your query should look like this we can we can rename it though instead of my query you could do you get post? for instance I think I call it get post by slogan or inner project. Yeah, okay. So let's continue with the fields the fields then so inside of this we want to get the date, that's the first field. So if you scroll down to the D's we'll click on. date Right there. Oh, and I still have Yes, I'll need Title and date. So both of both of those the title I click tomorrow. We'll leave that and then grab the date as well. We want the content of this blog post. So in the Seas, we'll check the box for Content like that. We want the author. And here again, we see this is not a checkbox but has a drop-down so we'll need some nested Fields inside of this. So click the author drop down and then node and for that author node. We're just going to get that person's name so that we can display who wrote it. So let's scroll down to name and click that checkbox. So there we are author node name. Looking good. The last thing we need is the categories for this blog post so scroll up. to the Seas Where am I am still inside of authors? Oh. My mistake, okay. So we sees on this list. The nesting levels are confusing me. There we go. Here's the categories. I'm looking for inside of this. We're gonna go for the nodes. So for each of those category nodes, we're just gonna select two things the slug and the name. So inside this one now. You can check the boxes for Slug and name or again. If you're somebody who you know likes using the keyboard like autocomplete what you could do instead at this point is pop over to curly braces and do command space. Slug enter command space name enter to autocomplete those those fields as well. Either way, you know works works great. All right instead of my query get post by slowly. I think in our app is what we oh he had called it and here's our composed query. So if we attempt to fire this off, it will crash and burn because we don't have an ID says the ID input is invalid. Those are passing just an empty string here need to get it something valid, right? So we should be able to get this working. using this Oh, I think I forgot a slash. Let me just attempt this once and if it works, I'll pop into the chat you can use it too. So I'll try to pass this for the ID. Like that, and then we need to tell it what id type as well. So I'll do comma and then control space you can see that. In addition to the ID one of the other variables I could provide is the type of ID and that's because there are multiple ways that WordPress could identify a blog post you can use it's database ID. You can use it URI you can use it slug a few different identifiers. Um, the default is the What's called the global ID in graphql land, but instead we're going to look it up by its URI. So I'll do for ID type. Get a little crowded. I know but for ID type here, I'll do control space again. And here's my options. This is a graphql union. It's called where it just has these four options only you have to choose you want to one of these or an email rather is it you know, so are we looking at my database ID or it's ID or it's like or it's URI. So in our case we're saying your eyes the one we want like enter. And that will add URI. Alright, so that should be it we're saying here's the idea to use and the type of ID is URI, so let me just try this once and then I'll paste it to you if it works. All right, so hit the button and we'll try to execute this. Shazam there it is. All right. So this works. Because you're right now we're hard coding this. So if we were to highlight this entire thing and go patient into our app. That the problem right since every single page would just pull from this particular blog post. We need to make this Dynamic here by accepting a variable. So that's what we can work on next here. So to accept a variable. We can do it. Like using this section down below so see query variables here. If we if you click down there if it's collapsed like that if you should be able to click on it and drag it upward. like that inside query variables, you can pop open some curly brackets here and and I'll type in. Our variables let me get rid of these. from here, and if I do ID Colon, we'll need to do afterwards to make this Dynamic is to use a variable with a dollar sign. So the ID that we're going to pass in is our URI. So we'll do like this say for the ID person is variable called URI comma and then our ID type this thing we can hard code right since we're always going to look it up by It's ID. So that part of it. I'm comfortable, you know hard coding but not this URI here. So it's saying the variable URI is not defined by this operation here saying you're not accepting. You're not accepting this variable. So we need to go ahead and do that now. So at at the end of this line, you need to add some parentheses to say. You can see already my error, you know squiggly lines are going away. So this point we can say you're going to expect a variable and the variable you're going to accept is your eye. But URI. In graphql, we have to be going to be very explicit about the type the type of argument we passed and so we'll do your eye colon. And then we have to tell the type is an ID. With an exclamation point so if you go you can go look dig into the graphql specification if you want to see like all the supported types and things like that, but this ID is one type that's that's been defined. For us and then the exclamation point means it's required so it can be you know, some graphql queries. You can have an optional argument where like you could pass in but you don't have to in our case though. We are a exclamation point because this is always required for our query to be able to run. All right. So now we have our query defined. It's expecting URI. And then when it runs the query it's going to pass in that variable at this point. It's going to use it. As you know, this ID to pass into the post. So now down in query variables if I pop over my curly braces and and do control space you can see here yet again. I get auto complete it. It is looking at my query it knows that. Oh, it looks like you've defined a variable called URI. So that's probably the one you want to you know, Define in this career variable section and it's right right. So I'll highlight URI and enter, you know popping URI here. And again at this point we can try. Using this long string. So let me put this in quotes. Like that, and we'll try to fire that that off so this simulates. You know a query variable being passed into the query and then used so let me try this this out now. So I'll hit play. There we go. It worked again. Yeah, so we're still getting the database back and this gives us a nice flexible, you know and dynamic query to use where you can just throw any URI at it and it'll you know, look up a different post depending on which you are I was posted it was passing. So this is good. This is everything that we need for our single blog post page. So let's go ahead and use this now. All right. So back in your code editor go ahead and open up URI right here and we will follow our same pattern from before. So we're going to delete these dummy data lines. We don't need those anymore and we need to Define our query. So this time instead of defining our query like right above the component. We do it maybe further down. So it's closer where we actually use it. Yeah, like right above get static props. Let's do that. It'll be easier to see you'll be able to see the component here and then see where we where we use it right below as well. All right, so at this point right above get static props, we're going to define a constant again, so do const And then get post go ahead and type that in. And just like last time we're going to set that equal to this gql. tagged template literal and with a colon at the end of it. tag Temple literals, if you're not familiar, you could like Google that and find the Mozilla docs on what those are but they're kind of like a type of function that expects a string so you can think of gql as a function and it's you know passing in the string that's inside of these back ticks and then using that as it's argument, All right. So inside of that this is where we're going to paste our query so go back to graphical and this whole query we had composed. Copy that and that is what we're gonna paste in. at this point so get post what we're calling it. All right, we have to actually make use of this. So one thing we're doing here is we're getting the URI from next JS the next JS has this context. Argument that gets passed in here and we're drilling down we're saying for the current page context. We want to drill down to the params drill down to the URI and then join those together with with a slash just because by default it separates all of the it's easy slashes here and tries to break them up. So what we're gonna do is just join them so that we have we're left with just a single string to work with that's how the join is there. So after you do that we receive, you know, retrieve the URI that that we're given. Um, we actually try to look this up. So we'll use a Paul client again at this point. So hit enter a couple times and we'll get our response back from Apollo. So type constant response. equals We're going to await the response and then we're going to call client dot query just like last time. So go ahead and type that and then inside of query we're going to pass in that object like we did last time so pop open some curly braces. And here we need to tell it which query to use right? So in our case, that's the one we defined Above This git posts. I'll copy that and that's the thing that we're going to pass in as our query. But unlike last time we're not done just yet. We need to hit enter one more time and then Define and then pass in the variables that we would like this query to use. So go ahead and type variables here colon. And then this is an object. Where we need to pass in any variables to use so in our case, that's URI. So this URI that we had pulled out of the current Pages context that URI is the thing that we need to pass in at this point as the variable. All right. So once you've composed all that now, we're telling a power client. Here's the query to use and here are the variables to pass in and you know, we're awaiting the response that comes back. So at this point, I just have a check to see like was a post received or not. So we need to Define. We need to check check if it was and try to pull the post out. Let's do const. post equals and they'll try to drill down to this this would be response. dot data dot post like that and remember this data structure Here this level of nesting is just the same as what we had defined. So this would be the data and that would be post. That's why it's just data and then dot post so try to drill down to that level. But if there's some error if we weren't able to look up, you know, the static props, then this could possibly be undefined right like vodka said in the in the in the chat for the last query. He was getting like an undefined message that could actually happen here pretty easily if somebody just goes to our front end app and does this right, if they if they, you know, typically invalid or try to and go to some page where The URI is invalid. This could very well fail here. So let's go ahead and check for that. So we'll use optional chaining in JavaScript to do that. So we'll say response question mark If so, keep going try access the data. And then we'll say if there's data then keep going and try to drill down to the post. So if at any point along this chain here something is is undefined. Then that would make post undefined. So our check here it says if post is falsely meaning it's you know, it's it wasn't defined then go ahead and returned not found true. And this will tell next Jazz to render our 404 page for this app saying this page wasn't found. Otherwise we make it past this check and post is truthy. That means we found it. Right so that point we're saying we're passing props through to our component and here's the prop to use. It's this post that we got back. All right, so I think that should do it. Let's see if we get this working. So save all of that. and let's see if we can get this working. So just gonna do a little sanity checks on my app is still running on the front end. So we try to click through to this post. How about Building a bookstore. There we go. It worked cool. So we have no more Latin on this page now, right instead of our Latin title and the dummy dummy data content now when somebody visits this URL building a bookstore, they're getting that actual, you know, blog post data. So I was written by that person this date. Here's all the content and any categories it's assigned to be at the bottom so you can see we have two actually now. tutorials and WordPress Very cool. So that's it. So that was our first graphql query that accepted an argument. So hopefully that was like an interesting thing for you to you to see and then we I got this copy over into our app and wired up to to render the, you know individual blog post pages. So that was we conquered number seven. How we feeling? Give me some thumbs up thumbs down in the chat. How did you do with number seven there? Excellent seeing some thumbs up. Let me see how I do it on time. Okay. Yeah, pretty good. I think so. Keep keep going here. All right. So if you're still with me and you want to see some more action, let's keep plowing through. Let me see. Okay. So at this point, we we just finished number seven. As I said on the list right influence single blog post page. So next we need to implement our single post or our single category page, okay. So as a reminder at the end of our single blog post page we have these. linked right tutorials in WordPress of the click on tutorials It's still that dummy data right still says the wrong category name and has the dummy data here. So let's wire this up so that it actually works. All right. So back in our front end app. Where do we need to look? To find this that would be so instead of pages and then category we have this slug Dynamic route here. So if somebody tries to navigate you slash category slash some slug like that, then that you know would would map to this file right here. All right, just like just like we've seen many times before pulling out the dummy data and then passing that through inside props to our component. So that'll be our job to rip that out. All right. So just like last time we need to compose a query and I think this one we could probably go even quicker since you all are Pros by this point at a graphql and queries and all of it, right? So, let's see what we can do. So we are going to define a query and let's call it get category. So go ahead and head back to the graphical IDE here with me and type query get category just like that. and with some curlies and let's see. Yeah, how about this time? We'll do the variables first since that's fresh in our mind from last time because this one again will will accept a variable that's going to use to to look up the category. So instead of get category or after you category will open up some parentheses and we'll say we're going to expect. sorry, yes, speak there we're gonna accept a slug ID like that with the dollar sign colon, and the type of this thing is an ID. With an exclamation point just like that. And then we're also going to pass in. Oh, hang on. here mistake Okay for this one will accept. two all right, we'll just slug ID and then slug name and that thing is going to be a string. with an exclamation point here just test something with this query I think about might be able to simplify it. Let me see some category. i d Is I'm just gonna do some live coding myself here to see because I think we actually don't need both of these variables. I think we can get away with just just one. I want to confirm that real quick though, so that the ID type Is Slug and inside of that I'll just get the category name. So, let me see if I can actually get this working with just the one. Variable like that. So down in query variables, I'm gonna pop open some curlies. Do you control space to get my auto complete, you know hit enter for slug ID now. I'll try to pass in a valid. Slugs like this tutorials. I'll just copy that. and try to use that as an ID. Alright. Yeah, that works. So yeah, I think my in the original code base I was passing passing to for certain reason but don't actually need to oh, no, we do. I'm sorry. I'm probably confusing everybody at this point. I see why I was doing it. all right, so we're going to go back to We're gonna go back to our two is because we have a nested query for for post. Anyways, okay, we're gonna include slug ID and then slug name right Okay. I have changed my mind three times. Now. You think I'm crazy. Sorry. I think we can just use the one that's like that. So here's what we're gonna do. We're gonna do get category. We're gonna pass in just just the slug ID. Like this and then for the slug ID will pass in tutorials. Okay, so that that works for getting us the name back and now we need to get the posts within within this category as well to this point. If you start typing p o s, you know, you'll see that all complete pop up. Please hit enter and then we'll need a a sub selection here. So some fields in essence inside of posts. So I'll Open up some curlies and inside of this we need to post nodes. I'll type nodes open that up how to control space again to get my auto complete and start T. Start typing database ID. That's the first one we need. Next one is the title. of the post next one is the excerpt. There you go. Next one is the URI. Like that and the next one will have yet another sub-selection that would be our featured image. So if you start typing featured image there and then pop open some curlies inside of that. We'll say for the featured image node we need two things just the source URL and then the alt text the same as the last last time we tried this Yeah, I just all text like that. All right, so that's pretty cool. So we're creating for a category getting the name of that category and then saying and for the posts associated with this category, here's all the data that we you know need about them. So let's attempt that. There we are. Okay. All right. Sorry. I was waffling back and forth there trying to decide if we needed the second argument, but I think this whole this will work great for us. All right. So this is working out really well. So we have the name of the tutorial that we'll use to display at the top of the the page there to tell people, you know, this is which category and then we also get, you know, our array of nodes back with the info that we asked for here. Cool, I think this will. This will work. Well, let's check in the chat. Everyone's doing well. Okay, so let me know if you have any in trouble with this if you're able to compose this. Query though, then that should be exactly what we need. So let's head back to our category and then slug Jazz page here. And we will make use of this. All right. So first step you're just like last time we will last two times. I will rip out the dummy data. We don't need that anymore. And then down right above get static props here. This is where we'll Define our query. All right. So, you know the drill by this point, we'll do const get category. We'll call it all caps. like that and then gql with our back ticks so start with that. and then Inside of our backticks. That's where we're going to paste this whole thing. So we'll copy the whole query that we had composed. And paste that inside of our backticks. Right and next we need to actually make use of it. So you can see here see here yet again. We're you know drilling down to context and then params and then slug to pull the slug out of the URL, you know for the page that the users currently on now I need to use that to To look up our category. Alright, so right below this I'll hit enter a couple times. I'll do const response equals. Oh, wait client dot query. Like we've done several times before. And then inside of this we're going to pop open our curly braces. And I bet you can guess we're gonna do next. For the query we're gonna pass through this thing. We just built right? So the query to use we're gonna say use that. Query and then we hit enter and pass in the variable that it expects. So I'll say variables and that'll be an object the variable that it expects is the slug ID, so I'll pass. Just like ID. and the thing that we're going to pass in is Is this slug that we had pulled out of the params? Yeah, okay. Yeah a better name we could have chosen. Call this just slug probably might have been a better choice than it would match what we're pulling out here. But naming is hard and this will work great because what it actually maps to is is passing as the ID. Field, you know input feeling graphql. So anyways, this should work great for us. We're passing in the query here. And then for the variables passing in the slug for the current page. All right, and just like last time we need to check to see is this category valid we're able to find this page. So I'll do that very similar to what we did last time. We'll do const category equals response dot data dot category So try to type that out, but just in case it was invalid some of these might be undefined. So like last time we'll use optional chaining and do question mark. and then question mark right there. So if we can't drill all the way down we'll know that's invalid and render our 404 page. Otherwise, if it's not falsely then we'll pass that through to our component as prompts. All right. That's what we'll actually render on the page. So I think we're good. with with this one, so I will save that and we'll see how we did. All right, so I'll reload tutorials. There we go. Yeah, it's working. So now when I visit slash category / tutorials I get proper name. For you know for this category that the users visiting and then the posts within it are all ones that are in that category. We do a little check I guess again, like open a post. Scroll the bottom and then yep sure enough. It's all these are within the tutorials category Well, cool that was it for the tutorials page. How you feeling? Can I get some thumbs up thumbs down everybody. Doing good. Thumbs up. Thank you. Cool. Thank you. All right, I'm feeling good. We've accomplished a lot right? You know, I don't know two hour period or whatever we've you know, created our blog index page or single post page or single category page. We're not even done yet. Next is that search page? So this one should be fun. Like I said because it this is our first page where we're doing client side requests up to this point. We've just been doing build time requests. So inside of you know, get static props here the next yes provides. We've been firing off queries, you know at build time on the next year server when the page is being, you know, pre-rendered being built. That's when we've been firing off our data requests, but for the search page we can't do that, right? We don't know what the user is gonna Try to search for ahead of time. So we have to do on the Fly graphql requests from the browser to hit our WordPress backend and then re-render the list. It's also something should be cool to see how that works. All right. So our first page our search page then I'll close out of my open. Tabs here in vs code and then we'll to remind ourselves. We'll head back to the search page see what that looks like. So that's this page. And again, like we saw last time it doesn't work. Currently you try to submit the form. all this wages stays Unchanged right. So inside of pages will open up search. here that is and we'll get this working. Okay. Yeah, let's compose our query first then I think that'll be that'd be helpful. Alright, so like we have before let's head back over to graphical so we can wipe out. My career variables and our query here so we won't need those anymore. Next we're going to do a new one for searches. So let's do this. So type the word query and then do type search. posts it's like that so query search posts. This one will expect an argument of course because we need that users search term that they want to use so we'll do dollar sign. Search term colon. And then the type of variable that we want to accept here is a string so to capital S string and we want to say that it's required for this query to be able to run. So I'll pop on the exclamation point to tell graphql. This must be be passed in. All right. So with that we'll open some curly braces and then on the next level we will go ahead and query for posts and use that search term. So I'll start typing posts right here. And inside of those parentheses, we need to use our where argument so there's some other options here for doing like pagination. Like I mentioned you could do give me the first 10 after this other post or whatever do cursorbase page. We're actually gonna make use of the where argument though, which is used for filtering posts and saying instead of all of them filter down to just the post. Both in this category or that match the search term or whatever. So we'll do that. I'll do where. colon And then this is an object here. So instead of where the expects an object inside of here here all the ways that you could filter, you know a post. So for us, we're gonna do it by a search if I start typing that it'll autocomplete search Colon, and this is the point where we want to make our query Dynamic and pass in that search term that the user head given us. So for the search here, we'll pass in search term. All right, and then from there we need some curly curly brackets after. The posts and here will drill down to the nodes. Open more curlies at this point. We need a few of our fields. So database ID the first one. Next one is title. Let's type title. Next one is excerpt. Next one is URI. Next one is featured image and this is has subselections. We'll do a Curly's and then for the node on that featured image just like last time we'll do Source URL and ALT text. Alright and just a side note here. You might be looking at these fields going. Man, we type this so many times this featured image thing that always has a node and always has social URL and all text. We've typed that like three different times already, right? It seems like like there's some repetition there and you're right there is and that's where later in the workshop. We'll get into using graphical fragments. That's what they can help solve. It's where you you know, like part of a query somewhere in your code base. You've defined as a fragment and then you pull that in and inject it into the points within other queries where you want to use them. So so stay tuned for that to see how you can you can kind of reduce some of the repetition with your queries. All right. So this should do it for us. I believe if I try to fire this off though. Is it gonna work? The answer's no, right because we haven't provided this search term that it expects here. So down in query variables. I will open up some curlies do control space to get the auto complete and it'll tell me. That it thinks I want search term which I do and here this is really freeform. Right? It's kind of fun because we can search for anything at this point so The graphql endpoint we're using is for a WP graphql blog and they probably talk about cool. Headless WordPress topics like react. How about right? So I'm going to type react here. That's we're going to search for and fire this off. So there we go. Look at first post building app using react and the graphql AP plugin for WordPress Right just so happens to be a post-written by me on the on the wpfql blog. So this is cool. Our search works to find posts with react, you know, we can we can try to find edge cases. Like what if I just type type bunch of gibberish and attempt to search here. There we go. So I get I still get a successful response but the you know nodes that come back is just an empty array. So to keep that in mind on our front end and say, you know, if we if we ran the search and that nodes raise empty, maybe fall back to just displaying a message saying no results found right, but for for other topics as you like graph graphql or something like that for the topics, it seems to work great. to find the matches So this is cool. That's exactly what we need. You could compose it like this if you like search being on a separate line, or you could just put these on this on the same same line if you prefer that look, but either way this is the query that we need. So let's go make use of that then inside of search.js so we'll rip out our dummy data. As usual at the top here and we're gonna Define our new query so we'll do const. We'll call it search post. Or posts. I mean all caps like that. equals gql right, you know the drill by this point and then inside of our back ticks is where we're going to paste our query we built. so copy that paste that in there we go. And now we're gonna make use of this but we're not going to do it at build time. Like I said, if you notice in this file, there is no get static props. That's because we don't we don't need it. We're gonna run these queries on the fly from from the client. So to do that we're going to use a hook that Apollo client provides. So that's why at the top here. We're pulling in this use Query Hook from Apollo client. They have their own docs. If you go look up the Apollo client dock they have used query use lazy query use mutation and you know all the documentation on how to use the those hooks but in this, you know in this Workshop, you'll get a feel for using the most common one, which is the use Query one for running client side graphql requests. So that's what we're gonna use. So I'll show you how inside of our component instead of having this dummy day. We were using we were setting const loading is always false concear is always false and then for the data, we're passing in our dummy data instead of all of this, we're gonna use actual, you know, the real loading error and data values that the use Query Hook from Apollo gives us back. So we're gonna delete all of this stuff and instead use use Query. So whoops what happened there? Okay, so start by typing const and then we're going to destructure some things that we're going to get from use Query. So we're gonna do we're gonna pull out. That loading State we're going to pull out it an error if there was one and then we're going to try to access the data. So those three things are gonna destructure and pull out of the results of Are called to the use Query hook? Whoops. There you go. Is like that? All right, and then use Query accepts two arguments. The first one is the query and the second one is any options that you want to want to Define. So for us if you scroll up our query is search posts. Right. That's the name. So I'll copy the name of that. Constant and I'll paste it here. So I'll tell you query which query to run and now we need to. Pass in the options array as well to tell it, you know about our variables we need so pop open some curly braces just like this. Inside of there. We'll do variables colon. And open up an object inside of here. We need to provide the search term. So we're going to do is store that search term in react State like this. I'll show you how that works in just a minute. But so I'll copy search term and that's the thing that we're going to pass in. To our query right there as as the search term. One other thing we're gonna pop in here is this notify on network status change that comes with Apollo. That's a lot to type. But if you start typing n o t should pop up for you when you set that to true. All right. And reason for that is The if you don't set this to True Apollo will only set loading to false. The first time the query is run. If you I know that's weird, but that's how that's just how it works. So if you run the query once loading will be, you know, true while it's while it's being resolved and then set defaults. And then after that point if you rerun the same query and pass different variables loading would just stay false unless you do this unless you say notify a network status change true then loading will talk to toggle between true and false every time which is what we want. So that's kind of a weird Quirk, but but that's why that is specified here. All right, so that's really it so our use Query hook will tell Apollo to run this query on the client and we're passing in the query in the variables. We need and getting all this stuff back. All right below. This have post line should still work. Just fine. You see what we're doing here. We're trying to drill down to data that post that nodes and Dot length and there are casting that to a Boolean. So if that's if either the data was undefined at some point in here and that would get casted to false. So we don't have posts or if length is empty right remember when I ran that query and I passed in a gibberish, you know word where the nodes array was empty if that's the case where post that knows that length is a length of zero and in that case happens be false, right since we don't have any. Otherwise if we drill down to this level and length is true truthy when we cast it to a bully and like it's one Two Three or some other positive integer then have posts will be true there. All right, we see further down like where we're using that so let's look at this actual page for a minute and see how this thing works. So you saw at the top already we're using reacts use State. It's passing an empty string or staying when this component first loads, there is no search term right? Just just keep that empty and there were You know pulling out of that the current search term and then the function we need to to be able to set that. we're providing the user with this form here at the top of the page where they should be able to type something and then when they click search we have a submit Handler here. We're saying when the person types something and then submits the form. We're preventing the default, you know form submission on the web. We're using this form date is just built into you know, the web platform here. We're saying we want new form data for this particular, you know element or yeah for this HTML element that that was submitted. We're pulling the data out of that and then do object Dot from entry to pull out each of the individual, you know values for the inputs, which in our case was this one here the search input and then once we've done that we've pulled out the values they were drilling down to the search term value and calling our set search term function here that we got from you state to set that now as the new Search term value as soon as we do that as soon as this is set to the new value react will re-render this component and the search term variable will be new right it'll be updated and reflect this the new search term and then Apollo will see that in its new and it's used query click here. It'll see all this search term value. Is this new you know this new value after the rerender happens. I better go ahead and fetch this data and then, you know provide the new loading error and data States now. Yeah, so that's how that all works the user submits the form. Which sets search term to something new and then use Query fires off a request using that new thing and that, you know triggers a re-render of our our list of posts here. All right, and then below that we just have for display purposes. We just have a few options. So we say are we currently loading then display, you know a loading message or do we currently have an error? Then say an error has occurred. You can do more robust air handling here, of course and and drill it dig into like error Dot message and display the actual layer that came back for us. I will just say an error has occurred frowny-face. If we don't have posts then we're saying no post found or finally if we make it all the way down here then we know. We're not loading. There is no error. And we do have posts right? So if we make other down here we go ahead and try to render our post list and past those in there. All right. So with all that. Talking out of the way. I will save this. And hope for the best. Hooray, I think it's working. All right. So when this page first load so this is this is how it looks now with our working search page. So in this page first loads you see we get a momentary loading. And then the results pop in. You could do a few things there. You could like fetch the default list ahead of time on the server and show that. Until the user makes their first query and then slap it out with the results or something to avoid that momentary loading or just not show any results until they perform a search right could do that a few different ways, but we set up right now as soon as the component mounts it, you know fetches the post using the current search term which in our case is empty string, right? So just searches like all posts the hair results. So let's try to Update this now. If I do if I do the word react search loading? And there it is I get the results back for react. That's cool. If I do my gibberish string again. You know something like that search. No posts found as expected. Like that, so this is cool. We have our working search page now. All right, it's all pause here and check the chat. See how we're doing. Oh Patricia. Yeah, absolutely. Sorry, you had to wait ages for this. He said could you show the code once more for the response? Was that for our search component or? The probably not right that would have been the one before it the category page. Was it this one? Yeah, sorry about that if I went through it a bit too quickly there. Cool. You got it. Thank you. Yeah, I'll pause at the moment at this point to you to remind the group if at any point you you feel like you fell behind or you didn't type something. Quickly enough or whatever else. We do have these checkpoints, right? So at this point, we just finished the search page. So if you want to get caught up to us at this point, you could just type get check out with this commit hash right there to your code base up to you know, the current one. And if anything screwy after that point, you could just hit control C to you know, kill your next GS app and then npm run deviated back up and running and then you should be should be good to go right up with the rest of the group at that point. All right, so we have a working search page. So now you know what it looks like to run queries from the client. Which is very cool. Yeah, we can even see that just to geek out for a minute on our search page here. You know, you can even go to network and you can either show all or tell it to filter it by. Fetch request and you can see each of these graphql requests fired off. So again, if I do get toward react search Oh, you know why? Okay, so there's actually a good lesson. I didn't see network request. Who knows why I can somebody tell me that in the chat. For some reason I didn't have to search any of that. I didn't have to. Fire off a request to This Server. Yeah, exactly, right? Yeah. I see people saying cash. That's exactly right. So I have I have the Apollo devtools installed here. So if I go to Apollo and then search posts you can see like here's the query. And if I go to cached data, you can see what Apollo has. Has cash. Yeah, so here it is. So Apollo has cash data for this query. In its in memory cache already, right? So when I when I typed react and hit search it it just checked its cash and saw. Oh I have you know, these seven post nodes here already in my cash from you know previous from times when the same query was previously executed. I'm just gonna return these immediately so that's why There was no loader at all and just immediately popped into view and also no network request. at all to the to the back end for for that one sounds cool. If I do something we haven't searched what I do view or something like something like that search. So now you see that there is an actual. graphql request here It's kind of cool. You can see what it you know, what it looks like. The headers or silence. So here's the payload that was sent. It's kind of interesting. You see operation name the query which is that whole string that we had provided and invariables which was the variables you could pass along and then you can look at the response that comes back and see that, you know, it's data posts nodes. It's in that same shape again that we had defined. We wrote the query. It's in that same same shape here when it when it comes back. Yeah, so that's kind of interesting. So if you're somebody who wants to work with this stack, you know, you might want to check out the Apollo Dev tools. They can be handy sometimes for seeing you know, what's currently in the cache and you can even like compose and fire off queries on the Fly here for quickly testing things or whatever so that can be kind of handy as well just paying attention to the network requests here. If you're doing anything client side like this they can see, you know, when the client the requests are being fired off and what those payloads look like when they when they get sent. Once up. All right. I'm looking back at the chat again. Let's say So Victor, can we query data through gql the same way for plugins and WordPress? Yes, you absolutely can there if they're in the graphql schema, that would be the caveat there. So if you go to WP graphql.com and then click on extensions right here. Says WP graphical can be extended to integrate with other WordPress plugins. Here are a list of dogeographical extension plugins. Many of these plugins are maintained by Community contributors. So here you can see some popular ones. So somebody mentioned in advanced custom Fields, right? One of the most popular plugins in all all the WordPress space, which is actually they announced yesterday. It was acquired by my company WP engine just bought Advanced custom Fields as well as the number of other plugins that delicious brains had been maintaining anyways, there is an official or there is a w here graphql for advanced custom Fields extension here. So what you need to do is just install two things WP graphql itself. And then this extension as long as you do both of those and have those activated then it provides some some new features in the UI for ACF where you could you can define a field Group, you know with all your fields in it and there's a checkbox at the bottom says expose in in W exposing graphql. So if you check that, you know, and then save your field Group at that point it adds, you know, this extension adds all the fields for ACF to the graphical schema. Then when you're in graphical like this and you're you're trying to query for the data about posts, you would just see all of all of the fields from ACF. You would see you know, there'd be there at your disposal. Yeah, so that's that's there for AC up a number of other things ninja forms woocommerce gravity forms. You know number of other things so so you can check out that list if that's helpful. Yep, my pleasure. Let's say yeah yoast SEO that's another one. Yoast is used on like every WordPress site, right? You're the WordPress space. You know, how prevalent data that isn't. Yeah. Ash Hitchcock was really active. He builds a lot of Gatsby Gatsby sites for his clients. I know he built a yoast SEO extension for graphical that a lot of people use So Yost is there on the list too? Yeah, so Stefan you're asking. How long is it kept? How long is data kept in the cache? Is there anywhere to clear the cache from the back end would make a change in the CMS? Yes, excellent question. Apollo client lets you define. cash policies Yeah, so it gives you all kinds of options. You can customize like how you want to to do caching Yeah, so we can spend a minute checking this out if we want to. customize the ideas I'm sure remember that. Where the page? Let's see Apollo client cash policy. A few of them are named like Network. Cash first I think is the name of another one. Fetch policy. There you go. I was calling it cash policy, but it's actually yeah called Fetch policy. And see supported fetch policies. Okay, here we go. Yeah, so what you can do in in your friend Javascript app, if you're working with a pile of client you can you can Define what fetch policy you want to use so you can do cash first which tells Apollo to create the cash first and then fall back to the network cash only only ever use that cash and network network only. So if you do this on it basically tell the follow never cash anything out with a freshest data. You know, don't cash it at all. You can do that. No cash or stand by the a few different options there. So this is how you can have some control over. You know what it's What it's caching and and install and for how long you know, there's some options for that beyond that though like you're asking about cash invalidation, right? It's like well if I if some data has changed, how do I clear that clear the cache, you know and tell Apollo to re-fetch it and you can do that as as well, so I'd be like when you do a mutation If we can find the doctor real quick. let's say yeah, here we go. So re-fetching queries or refetching after update. Yeah, so you can do this if You have a mutation that you're doing your friend JavaScript app or the users like adding a to-do in this case or making some like update to the data. You can tell Apollo client after this mutation executes. you know run this this callback function you give it a callback function and say that you want to you know, refetch a certain thing. You give a certain query and say after this mutation executes the attitude do and refetch this query over here. That that is responsible for fetching the list of tutus. Right? So if you do that, then it knows okay, I'll refresh that list and then react will re-render the listed to Do's to show you know, the the updated list which includes the new one that they had just added to the list. Thank you stuff like that. It's the user themselves like making making mutations. You can tell apocal client to like Blow Away part of the cash or or refetch part of the cash so that it gets the the new data there as far as other any other caching of of just server data that you can control it like the fetch policies. So if you want to Google Just fetch policies and look at Those that page that we looked at that's how you control that. All right. Yeah, I think we're I think we're good then. We're doing for time we can we can dig into our fragments if you still trying to think we have 30 minutes remaining. Yeah, my pleasure Stephen. Hope that was helpful. Their docs are really really good. I found a Polish docs if you see I dig into those. Can typically find your answer. All right. Yes at this point we can dig into some of the Some of the fragments stuff unless I see in the chat that the group wants to go down other rabbit holes that I'm happy to do that. I got a rabbit hole. Good. What happens in WordPress is down. This is an interesting question. Yeah, so if you're doing this decoupled architecture that looks like This right? It's a good question. Like well what if next yes tries to use this API layer to contact WordPress to get through data WordPress has downtime, right the server is not there. So this can be handled a couple ways one way is I in next Jazz you can If you're using like it's incremental static regeneration feature to to like regenerate your pages on a time interval it will if it fails to regenerate the page, it'll just keep serving up the stale page actually which is which is a really cool feature so you can tell next.js. If you're not familiar, if you just Google next yes incremental static regeneration. If you Google that if you're not familiar, they'll you know explain kind of what that is, but it's basically tells next yes. I want this to be a static page. But it should only last for a certain amount of time you specify and say regenerated every 10 minutes every hour once per day or whatever whatever you want. And on the interval next Jazz will if all the stale while revalidate model where it'll request comes in it realizes the page is no longer valid, you know that time duration has elapsed it'll still serve up that stale page to that one. You know that one last user within in the background. It'll kick off a process to refetch the data and regenerate that page as soon as that new page new versions available. It swaps out the new one for the old one. So then any new visitors coming to the site would get that new version of the cash page. So to them it's still it's still the very quick, you know response times as though it's it's a static page, but you can add some dynamism there and like Refresh on interval by using this feature. But anyways, if you're doing that kind of thing next year will not swap out the old cash page for the new one if it fails to do any of the Hatching W1 solution to this. So if WordPress had downtime and next yes is trying to you know reach out to Wordpress and regenerate the page for a blog post or whatever and it's unable to It's fine. It would just keep serving up the stale page until you know at a later point when WordPress is back online and it tries again at that point it just you know, start regenerating the pages again, so that's a really cool robust solution where you can have your front end app. Just fall back to the cash Pages, you know, whenever your data sources in our case WordPress like happened to be down. So that's when call solution. It doesn't handle every case. Of course though like our search page. Right if like if somebody goes to the search page and try to perform a search and the WordPress is down at that moment. Like of then of course we can't. You know can't really do anything about that because we need the actual, you know data from WordPress. So that's you do there would be to follow to fail gracefully, right? Like on our search page. We just have if an error. happen in our case Apollo would call this like a network error like it tried to send the request to the backend API and got a you know either 500 air or it was offline or whatever else. So you just fall back, you know fail gracefully to say. Oh, sorry unable to perform searches at this time or whatever and just display a message like that. So yeah, definitely a real concern if WordPress goes down. But but yeah doing the like the static rendering of pages can can really save you sometimes from from that being a problem. Yeah, good question there. Okay, we can dig into some query or some fragment stuff for a little bit then graph. Graphical fragments are really cool. Let me show you what they are. At a high level. So let's say we so we have the search post query that we had composed. Right like that. What were you able to do with query with fragments is kind of break up some of this and and Define it other places. Let me show you what I mean so I can type fragment. And we'll give it a name. So this will be so fragment featured image. I'm probably gonna get the syntax wrong for this thing. I want to get myself. You get my cheat sheet so I can look at my own. My own app and the syntax here. Post list yeah. Oh, yeah, okay. At a refresh myself on this syntax. Okay, so featured image is Is the fragment where we're going to Define and actually let's do a different one that will actually use in our in our app said this kind of fictitious one I was going to do on the search page. Let's just dive right into it. We'll start with a real lens like on the Blog Page, how about all right. So back in our app. Let's clear things out start fresh backing up. We'll go to the blog index. Oh, no. Yeah, they're slash Blog the slash Blog Page like that, right? There's the one already got the first 18 posts and displayed them on a grid right this one. Let's say like these these nodes here. We don't want this data to live here because actually if you look at this component how much that data does it care about? None, right. It just grabs the post and sends them straight through the post list component. This component actually doesn't care about all the fields that were defining here. The only reason we're putting them in this file. Is because we need that data eventually Downstream for the Post list component. So one really powerful pattern is to co-locate. Your components data needs with the component itself. So what you could do is You know at create some fragments so that this data lives, you know and is defined maybe with this post list component if it's the one that cares about that data or otherwise with this post card component, it's the one that cares about some of that data. Why not just to find a fragment in the same file. Where we Define those the fields that we need and then immediately below it inside of the component go ahead and destructure and use those same Fields like wouldn't that be a wouldn't that be a nicer more organized code base for us? Right and that's a fragments allow you to do. so we can do that like with our with the blog the blog page and then post list and then postcard let's start with like postcard since that's the most granular I guess that's like the It doesn't render anything else, you know, it just gets rendered by pulse lists, which gets rendered and turned by blocks. Let's let's start with like postcard. I'll show you what I mean by creating these these fragments. This is what you would do like above this thing you would do. So we'll export a constant from this file. We'll do export const. And any of you who want to try out fragments like you can type this along with me, you know, we'll work through this together. It's like we have the other pages. So I do export const and then in all caps will do Post. card fields like that gql All right our usual song and dance like that instead of defining defining a query inside of here. Now though. We're going to define a fragment. So we're gonna type fragment. Postcard Fields like that. On post so this is um, the graphical specification says that if you want to Define fragments, you have to tell telegraphical what type it's on. So we're saying there's this type in the graphql team schema called post and the fields are going to Define are the fields, you know that we would like data back on that type if that makes sense. If you're not sure on like what what these types even are you can see them in in the docks right here. So if I do it if I do a query for like Pause to get the nodes and then feature those. I get the title or something. Let's say that this is a query. I've composed here and you're wondering yourself. What graphql types are behind this this thing here? If you you know command click on post that'll pop open the documentation. Right here or nodes, you know, you can see that nodes is an array of this post capital T post type. In the graphql schema, and if you click on that. and that in turn would tell you all right that the post type here is all the you know data within it author category blah. So that's where this comes from. We're saying on this capital P post type in the graphql schema. We're gonna Define a fragment with some fields for data that we care about that's where this comes from. It's our fragment is named this. It's on the post type so next open some curly braces. open the Curley's inside of this we we need to ask ourselves. Like what does this component actually care about what are its data needs, right? So you can see it needs the title. Let's type that it needs the excerpt. Take that. It needs URI. All right, and then also needs featured image and that's the one remember we need a subselection. So I'll do curlies and then the node. curlies and on that the source URL And the alt text. Alright, so now that we've defined this fragment we see how nicely organized this is. It's like here this component's data needs. It cares about title extra URI feature image and then here's the component title excerpt URI feature featured image. It just goes ahead and uses all the same data that's defined above which makes things nice and organized. So we're exporting this from this file, but not using it anymore. So so we need to go ahead and do that. So postcard Fields Title X review or so let's say so they could do that here. Yeah, I'll show you this first. So here they are right if we go back Upstream here to blog title, except your eye featured image. This component in this file doesn't actually care about any of this data so we could I'm just remove. all of this stuff and get it from the fragment instead. So let me show you what that looks like. So, that'd be import. Let me grab the name of it import postcard field. So don't type this because we won't actually leave this fragment here. I was doing this for demonstration purposes. So just hold off on the typing if you're following for a minute. So if I import that fragment from postcard like this And I just take a minute. Where was that close card? Okay. So now we've imported our fragment. so we need to insert this thing inside of inside of this tag Temple. Literally we can do that just by sticking it at the end of you hit enter. And then use this syntax this in JavaScript, you know tells this tells JavaScript on it like interpolate. So some some data here inside of this string. So open that up to interpret interpolate some data and then we'll paste in the name of our fragment here. So imported it and then interpolated here now we go ahead and use this inside of this this query. So instead of getting for each of our nodes instead of getting just the database ID. Now, we can use our fragment that we named. So the Syntax for that is three dots and then the name of the fragment so dot dot and then we can grab the name. So we called it postcard Fields. So I'll copy that. here postcard Fields. So this is telegraphical to like, you know spread or inject the post the fields that we had to find in that fragment at this point in the query, right? So I'll say that hopefully I did everything right. Let's see. Blog I think so. Let's try to do it without so I'll remove. I'll remove this all together. And then it should break. Yeah, there you go. So fragment postcard field is never used plus it doesn't have any, you know the data that it needs isn't there. But if I go ahead and use our fragment, it's spread those fields or inject them at this point in the query. And give that a save now. It works right? This is nice for organization. Like I said your components and their data requirements can be co-located in the same file so that they're like easy to manage. So if you're ever in the future if you're ever making changes this postcard and you realize oh, you know what I need another additional piece of data on the post. Then you just you know hop above here and you know pop in any additional fields or make the changes here and then your component go ahead and make use of them right away without ever like leaving this file, which is really nice. All right. I said hold off on typing this though. And the reason for that is that we've skipped a level we have post list. here that I think we're going to use let me look at my finished product. Yeah, so if you want to get technical We could go even further with this because right now we're saying for each of the post nodes. We need the database ID, but if you look below this component doesn't care about the database ID either. It cares about nothing other than just the collection of posts really is all it cares about because it's just gonna pass that along, you know, so even this database ID this component doesn't care to care about so if we want to continue with this pattern of breaking things up into fragments we can do that for the Post list as well. So let's do this. I'm going to delete. some of this stuff so no longer use this fragment in this field. at all that's gonna leave it in this state for now. So now you continue if you're typing along with me you continue can continue at this point. So, all right. So we Define our fragment here. and really postcard It gets rendered at this point inside of post list. So this is where you know we would need. We can put the fragment for the Postcard inside of another component, which is this one for post list. Let's create one for this file. to So type that so if you're following along you take this type this with me so export const. This will be post. post list fields like that equals gql All right, enter a couple times open that up and this will be another fragment that we're defining so fragment. You know frame it. posts list fields There you go. What on post right? So if you define the type like we talked about Open some curly braces and really all this component cares about. Is the database ID because it uses that as the key prop right? So that one we can. Define here database City everything else though. It's just passing through to postcard. So this is where we can do this thing where we import. postcard fields from this adjacent component here from Postcards if you type that import postcard fields from postcard, we'll take this fragment and interpolate it. inside of this fragment here So hit enter and we'll do this dollar sign curly syntax to interpolate some data. I'll paste that in so now we can actually make use of this very inside of this other fragment inside a postcard. I'll just grab its name. Right, and they remember the Syntax for this is just the three dots. So I'll say inside this other fragment right next to date where database ID is I'm going to Dot. postcard fields right All right, and now this postcard feels we we can in turn export it and ultimately use it on the blog page. So, let's see how we can do that. So back in the blog page now. We can do. And check the chat. Okay, I think we're doing good. Let me know if you have any questions as we go through this fragment stuff inside of the blog page now we can import. Post list fields from post list and we can actually put on this line here. So we're already importing this component from that file. So now we just want to import something else. We need to come we do comma and then curlies and the other thing we want from that some file. is this Const that we've defined here, right? So that's the thing that we're also importing from both list. And this thing like we saw before we're going to enter. And interpolate so that we have access to it inside I've get posts. Now as we saw before, we don't even need database ID at this point anymore. All we need are the is the post-lit. List Fields fragment. So I'll copy the name of this fragment and then Dot. pause list fields All right. I'll say that. save that and postcards already saved let me See if it works. Yeah, so everything's still works. Hopefully you see the the flow here. So starting at the highest level like blog. We're saying here. This component's data requirements. Really? All it cares about is the collection of posts, right? So you look at it's you know the query we Define here. It just says I want a collection of posts as far as what each of the nodes have it's just deferring it's saying whatever post-list fields that component says it needs. That's what you should get graphql. Right? It's kind of differing that decision making to this post-list Fields components. So if we head over there we say all right post list Fields. What do you need now? What are your data requirements? It tells us I care about this database ID. That's the particular. That's the specific field that I need, you know to render the render my data as far as any other field on this, I'm deferring that decision making go over to postcard, you know that and look at the fields. It needs. I'm deferring that, you know any other decision making over the postcard and they say, okay sounds good. Let's do that. Let's head over to postcard. Postcard component. What do you need? What are your data requirements? Right and it says I need these specific fields on the post object for for to meet my data needs. Right. So then you can just take all these and go ahead and render those out inside of the component. So hopefully you think this pattern is kind of cool and kind of powerful. It allows you to as I said several times to co-locate your component's data needs with the component itself. It makes things really easy to manage. I found like as your code base moves and changes and grows. It's like as long as you have the fragment here with the data needs that and that kind of maps to what the component itself is using then it becomes pretty easy to keep these two in sync compared to if you had these data needs defined. You know, like several several components up in the component tree. They're defined somewhere else far away or whatever. This makes it nice and nice and close to the source of where they're actually actually used. All right. That's it for the components are the fragment stuff. I believe if you check out. This last one the last check one here if you check out fragments. It uses them everywhere. So it uses so not only for the blog page but also like the single. The single page here, it breaks up like some of this stuff. That the single post page breaks that up into fragments and then composes composes those those together as well. Maybe the category page as well. So yeah, if you want to see I'll stop there with our one example that we did with like the blog page how to define fragments and compose them together. But if you want to see some other examples like you could just you know, check out. This commit here from our checkpoint to see the then that would be like the final. final application at that point Yeah, so I think we're nearly at time a couple minutes left. I'd love to hear some questions though. I like I mentioned I work at a WordPress specific company WP engine and I do headless WordPress stuff like all day long. So I've thought about this stuff and have been you know, my team produces all kinds of resources on this developer site if you want to check out any of our any of our content This is like this is my world where I live so I hence the reason I signed up for this particular Topic at react Summit. So Victor he says which CMS do you prefer? Yeah. It's a great question. I personally have had spent like A very very long time in the WordPress space. I know it really. Well. I've never launched another production. project using another CMS I I Really like some of the modern headless cms's that are popping up. I think are interesting, you know, like contentful insanity and prismic and some of those I think they're like interesting and they have some cool modern. you know modern ways of doing of doing like content modeling and then getting back the data for That's already already in the format. You know that you would need to render render react components and things like that. It's kind of built with like a decoupled front-end mentality from the ground up. You know, I think that's kind of cool and kind of powerful. So certainly like what a lot of the CMS are doing the one downside with those those like they're all proprietary one exception would be strappy strappy is is an open source one like the JavaScript base one that you can check out strapi. I haven't checked out strappy. Yeah, but I like, you know the fact that it's open source and and you know free of licenses or whatever is cool. So everyone maybe it to check out but all the other ones I mentioned contentful prismic Sandy. All those are proprietary which makes me a little nervous. It's just like if I build, you know some site for my client or whatever some business if I build a site using their CMS, and then they decided to quadruple their prices or change their license. So that parts of it aren't you know parts of it aren't accessible anymore. Like they can do that at any time. So I do like that WordPress is like free and open source where if you build something on top of headless WordPress You know, it's always free and open source. You have to worry about you know. You know the company behind it tripling their price or licensing changes or whatever like I was saying, so I do like that part of it but strappy like I said might also have some of those same advantages. So WordPress. The other thing of it is it's so robust at this point in so many like marketing teams and people like that really love it for like it's editing. Interface, you know and that the experience it gets like content creators. So it allows you to if you do have this WordPress allows you to still give those people their preferred CMS that they love working with but also, you know have fun as a Dev on the front end and build component based, you know apps using like react and spell to another tech so yeah, I can't I can't speak like to super deeply on comparisons but But yeah, I just like I admire some of the stuff other CMS are doing but most of my experiences and in the WordPress world at this point, Nicole or nickel. Says have you used next Jazz's static site generator? Does it make sense fetching the data from the WordPress API while building the static site. And have a headless CMS. Maybe not even on the web. Just a local ad this WordPress and SSG next year. Next year is just wondering. Yeah, you certainly could do this. So. Yeah, so you're referring to using Nexus option to generate a fully static site. Right where we have all of all the pages of your site just end up being HTML files that you could distribute across the seat see a CMS or a CDN rather and you know, fully static prewriter rendered sites. Yeah, you could do that if you have nothing Dynamic on your WordPress site. You know if you don't have like a commenting system or contact forms. You know or other types of forms that users would need to fill out and interact with it where you might need a server to like intervene, you know to do that stuff. If you have none of that and your site is just purely Static content like meant for consumption then. Yeah, that might be a good that might be a cool option and like you're saying he you're even referring to like running WordPress site locally, you know, so next Jazz when it when it runs it runs a build you access your local WordPress site. You know to build out all the pages. and then Deploy, those static pages to the to the web and WordPress itself wouldn't even need to be online and you're right. You could certainly do that. Yeah, you know you probably wouldn't want to for some production client, you know to have the WordPress site living. I like one person's machine or whatever like probably wouldn't be the best idea there. You know, I would want to host that somewhere with some WordPress host. But yeah, it's like a personal project and you you know, it's for your own site and you're like I have back up some of my computer so that WordPress database like I know I already know it's backed up and I'm not worried about It going anywhere then. Yeah, you could certainly do that. That'd be cool.
173 min
04 Jul, 2022

Watch more workshops on topic

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career