Build a Headless WordPress App with Next.js and WPGraphQL

Rate this content
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.

173 min
04 Jul, 2022

Comments

Sign in or register to post your comment.

Video Summary and Transcription

Let's get started with the workshop on building a Headless WordPress app with Next.js and WP GraphQL. We'll cover the benefits and drawbacks of a headless approach, explore the finished application and blog page, and implement features like search and single blog post pages. We'll also learn how to turn WordPress into a GraphQL server, set up Apollo Client, compose GraphQL queries, and use fragments. The workshop discusses caching, cache invalidation, and the use of Next.js as a static site generator. Various CMS options are compared, including WordPress, Contentful, Sanity, Prismic, and Strapi.

Available in Español

1. Introduction to Headless WordPress

Short description:

Let's get started with the workshop on building a Headless WordPress app with Next.js and WP GraphQL. We'll cover topics like what is Headless WordPress and why you might want to consider it. Then we'll dive into the live coding workshop where you'll clone a Next.js application and connect it to a WordPress backend using GraphQL. We'll also discuss the benefits of a headless architecture and why you might choose it over traditional WordPress. So let's get started!

So yeah, let's get started then since we're a few minutes past the hour. So thank you, 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 Build a Headless WordPress app with Next.js and WP GraphQL. So what we'll do is, I have a few slides to go over. I'll share my slides, introduce myself, and then go through a few topics, such as what is Headless WordPress, why might you want to consider it.

And after we get through those slides, then we'll dive into the live coding workshop part you actually clone down a Next.js application, get that up and running on your local machine, and then we'll see how we can get that hooked up to a WordPress backend so that we're pulling data from that WordPress backend via GraphQL, then using it to render the pages of our Next.js app. And we'll walk through a few different 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 let's build a headless WordPress app with Next.js and WP GraphQL. All right. So to start off, I'll introduce myself. So my name is Kellan 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 it's relevant to this audience and this talk is the fact that WP Engine recently, we launched this new hosting platform called Atlas, which is geared toward headless WordPress WordPress sites even.

So you can, with a single account and 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 as well, if you wanna get in touch with me after the conference. DMs are open, so please 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 a kind of disambiguating or calling, drawing attention to the differences between traditional WordPress and then Headless, and why you might wanna go one way versus the other, as I said. So let's do that.

Oh yeah, before we do that, 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. But for you to clone down this repository, and then you can follow the steps in the readme there. They'll tell you to 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 once you get to the live coding portion later. Then you won't 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 slide.

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. So we're 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. That's the percentage of sites online that are running that which is just just mind boggling to think about.

In traditional WordPress, WordPress has a lot of jobs, it's responsible for providing the admin interface that your content creators log into, when they create and edit and manage their content, it's responsible for saving the data to the database. And then when requests come in from, you know, website visitors WordPress is also 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 a few hats and does a lot of jobs. And in many cases on the web, 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 and to 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 front-end application that does that and that's Next.js in our case on the workshop is what we'll use for that. So you have Next.js 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 back end to communicate with one another.

One way to do that is to use the REST API that's just built into native WordPress. I would argue though that a better choice these days is WPGraphQL. So that's the logo that you see here at the bottom. WPGraphQL 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. In 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-consuming and cause a performance hit. But 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 posts they've 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 it has other benefits, too, but that's I would say one of the main ones. This is what kind of a decoupled architecture looks like. And this is the thing that we'll actually be building today.

The 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 for a decoupled architecture would be 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 their preferred CMS. So they get to with a headless setup. Performance and scalability, you know, frameworks like Next.js make it very easy to get very fine-grained and say, I want this route to be fully static. This other route to be server-side rendered. This other route, I would do some client-side rendering. You get your 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 backend. 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 Next.js app that pulls that JSON and renders it for the web client. But if you wanted to, you could also build an iOS client, an Android client, a desktop client, and all of these apps could source their data from 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 site are being built, let's say, if you wanna pull some data from WordPress, some data from Salesforce, data from the YouTube API, some data from Contentful or whatever else. It makes it...modern frameworks like NOCS make it very easy to do that, to source data from all these, you know, sources, and then stitch it all together into your HTML pages. Next one is increased security. I've seen site architectures where they'll do something like they'll have a JavaScript frontend that serves the website to their site visitors, call it the WordPress backend, where their content creators manage content. And then that WordPress backend, they'll 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, WordPress admin to try to get in would be 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 see the front-end JavaScript app here. And the last one on this list is improved developer experience.

2. Headless WordPress: Benefits and Drawbacks

Short description:

When using a headless approach, you can choose a front-end framework to build in components and have a nice developer experience. However, there are drawbacks, such as additional complexity, the need to recreate some built-in WordPress features, the inability to use WordPress plugins for visual elements, and the inability to use the new full site editing features. Let's now dive into the workshop content, starting with the setup portion. We'll explore the pages of the finished app, turn WordPress into a GraphQL server, set up for local development, and configure Apollo Client. Then, we'll move on to the build features portion, where we'll cover topics like composing a GraphQL query, implementing specific pages, and leveraging GraphQL fragments if time permits.

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 going to assume you, you know, like React and 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 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 slide, and then I'm going to check the chat here and see if we have any questions. One is additional complexity. So, you do have 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 and a post, 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. So, that kind of thing, you don't get for free. If you decouple your front-end from your back-end, now you don't have a way of authenticating the user and knowing if they're allowed to view an 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 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 plug-ins to add visual elements. Some people like, you know, full control over their own website. So, if you build a site for, like, 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 a WordPress plug-in and add a image slider or something like that to the front end of the site, and you can't do that any more with a headless approach. You can't simply activate a plug-in that adds visual elements to the page because all of those visual elements are controlled by your decoupled JavaScript app, right, so that makes sense.

This may not be a con or a drawback, though, depending on your project, you know, many times you don't want the client themselves adding all kinds of visual elements to the page all the time and potentially tanking 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.

And last one I have here is you can't use the new full site editing features. So 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 and the ability to, you know, create layouts on their own using kind of a page builder kind of experience. So that's what these 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, then 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 drawback for some projects but having a tight control over what gets rendered could also be a pro as well, as I mentioned.

Alright, so let me pause for a moment and I'll pop open the chat and see what we have. Alright. Reading through the comments here. Yeah, I can absolutely pop the GitHub link in there so, let me just do this. Ah, alright, so I popped the link to the Github project 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.05, my time, 10.05 in the chat. But let me copy that one again as well. The link to the slides, there we go. So I put the link to the slides in the chat as well if that's helpful to anyone. Let's see, oh I see a few of you shared the Github link as well, thank you for doing that. Saved me the trouble, okay. Alright, let's continue with this. Then I just have a, yeah a couple more. So that was really it for the slides as far as how Headless WordPress is different from traditional WordPress and then the benefits and drawbacks, I'll resume this slideshow now. The next thing after the benefits and drawbacks here was let's code. So at this point we can actually 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 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 setup for local development. Some of you who clone down the project and follow those steps in the readme have done some of that work already, so that'll save you some time once you get to that step. Number four is configure Apollo Client. That's the GraphQL client that we're gonna 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 pre-rendering a static page ahead of time, like we could with some of these other pages, the search one will be rendered on the fly. So as the user types something in and hits a button, will fire off a request 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 boilerplate, and having parts of our GraphQL queries disassociated with the components that actually use them. So with GraphQL fragment, that allows us to have a single React component and co-locate the data that it needs with the component itself. So it makes your code base very nice and organized. So we'll see how we can do that if we, again, if we have time to get to step nine. If not, though, if we did, or step 10. If not, though, if we just get through step nine, I think it'll still be hugely beneficial in a helpful workshop to see how you build out each of the pages that we'll cover here. All right, and after that, 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 nextjs 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. And we'll need to just follow the steps in this readme here. So clone down the repo, you'll cd into that 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 cloned down this project myself right here to my desktop, and now I'll run npm install just to 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's just says, create a new.env.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. Let me just resize this for us. There we go, okay. So following the directions here, I'll right click over here and just go to new file. I'll name it.env.local. And inside of this, we're gonna put an environment variable. So I'll copy this right there and then paste that into this file.

3. Tour of Finished Application and Blog Page

Short description:

The GraphQL endpoint is used by our Next.js app to pull data from a WordPress backend site. If you already use WordPress, you can pull data from your own site by pointing the Next.js app to a local WordPress install. Make sure you have WP GraphQL installed and activated if you choose this option. To run the app locally, use npm run dev and open localhost 3000. You can host the front end and WordPress backend on different hosts, such as WP Engine's Atlas, Netlify, Vercell, or other providers. Tour the finished app, starting with the homepage and the blog page, which displays a grid of linked blog posts. The blog page uses dummy data, but we'll replace it with actual data from a WordPress backend. The blog post page pulls posts from a dummy data file and renders them using components like post list and post card. Our task is to fetch actual data from a WordPress backend and use it to render the list of posts. Let's continue with a tour of the single blog post page.

So this points to the GraphQL endpoint that our Next.js app is gonna use when it pulls data from a WordPress backend site. All right, we'll talk more about that in a little bit. There's an alternative here if you're somebody who already uses WordPress and would wanna pull data in from your own site, you could do that. So if it says, I want to point the Next.js app to a local WordPress install, swap out that with the domain for your local WordPress site. So you can do that, either now or later on your own, if you wanna 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 change here.

All right, let's see. If you do choose to use a local WordPress install, make sure you have WP GraphQL installed and activated. All right, and then you run npm run dev to get the app up and running at localhost 3000. And then you can stop it at any time by hitting Control C. All right, so let's see how we can do that. So back on the command line, I'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 in all of its glory. So here we go, headless WP app. All right, so this is what we'll explore here. Head back to our sequence of events.

Okay, so yeah, the first thing we'll head through now is the tour of our finished application. Let's check the chat here. All right. So Kyle, I see your question here. Is there a preferred hosting partner with this architecture or can you pick and choose, IE AWS? Yeah, so great question. There are many options out there. Some popular apps for hosting the front end, well, let me step back 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 same host or they could be different hosts.

So I mentioned at the beginning of the presentation that my company WP Engine, we have a product called Atlas. So if you use Atlas, it allows you to host both and manage them from a single dashboard. So 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 back end, I wanna create a new one, you know, on your WP Engine platform and then hit a button and it'll create both of those. The front end and the back end, you know, that point to one another and use graph QL 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 wanna go with Atlas, there are other providers out there. So Netlify and Vercell, render.com are a few really popular ones for hosting your front end JavaScript app. And then for the WordPress back end, as you said, you could, you know, if you wanted to host that on AWS or on digital ocean or Linode or other managed hosting providers in the WordPress space, you know, like SiteGround or Bluehost or anything else. You could do that as well. So you could have front end app on Netlify or Vercell and then 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, where you're specifying the GraphQL endpoint 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 AWS as well. Yeah, so if you're somebody who is very technical and knows how to post, you know, Node.js apps on AWS, then certainly you could do that as well. You know, host the front end app on AWS as well. That's true. Excellent questions. Okay, let's keep rolling here. So the 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 just added some pages and components that we'll walk through here. So let's start with like this homepage here. If you all have used Next.js you probably recognize this is just kind of their, you know, welcome screen that the framework uses. Let's head over to blog though and see what that looks like. So you see we have 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, can I get a thumbs up if y'all are able to load the slash blog page and like, this is what you see. That look good? While 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. All right, 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, let me bump up the size actually. We have this directory here called dummy data with an index file inside of it. You can see it just has a bunch of hard coded you know, posts data here. So it mimics the structure of the data. We'll get back later when we do actual GraphQL queries, but for now you see this is just hard coded dummy data. So what our blog page does is it pulls out the posts from that dummy data file and then instead of get static props we tell Next.js, 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 should get the data from this, you know, these posts that we imported from our dummy data. And if you look at the component here it does just that, right? It receives the props, destructures 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 lists is pretty simple it's just a UL here and then we map over each of the posts and, you know, put one of each one of those an LI with a post card inside of it. And I'll click through to post card 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 it just has an article tag and renders some of the content, you know, 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 and fetch actual data from a WordPress backend and then use that actual data to render the list of posts. So we'll see these change instead of the Latin titles here. You'll see this page re-render. Once we get it working, with the actual blog post data from our WordPress backend. So that'll 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 an individual blog post page here. So our front end app. That would be inside of pages. I'll go to this dot dot dot URI.

4. Exploring Search and Single Blog Post Pages

Short description:

In this part, we explore the search page and the single blog post page. The search page is currently broken as it relies on dummy data. We discuss how to handle XSS protection when rendering HTML content from a CMS like WordPress. React escapes HTML on its own, but there are considerations when dealing with a CMS. We explain the options for handling HTML content, such as using dangerously set inner HTML or using a library like HTML React Parser.

js file here as well. If you're not sure what this is, like why the brackets are here with the dot dot dot, this is just the Next.js convention. So back in our slides, on the link page here, you could see their documentation. So like number six here, if you're wondering like why we created that dot env dot local file and I said that we were storing an environment variable inside of that, if you're wondering where'd that come from, why are we doing that, this is the answer here. Number six shows you in the next docs how to create environment variables. And likewise, if you're wondering how the file-based routing here works, like with this catch-all route, you could check out the next yes docs to see how that all works. But basically this just is a catch-all route that tells Next.js 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 frontend 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 that single post as the props that our component should receive. And inside a component, we're 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 a max width and so on. And inside of that, we should have an article tag with all this stuff. So you can see that, you know, here's the title of the blog post. Here's, you know, the, the author's name on, and then a formatted date says where we get this kind of meta information here. Below that, we have the content of the blog posts. You know, all of this HTML 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 page is written. And I'll keep on cruising here. In the chat, let me know if any of this 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, 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, we're passing in the posts and further down, we have our forum 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 we're rendering things. So right now it's broken because we render our post list. And then we give it data.post.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 actually work as expected. So you'll be able to type in a particular word within one or more blog posts. You know, 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 tour. There's a category page we didn't look at but we can save that for later. That's here if you click on a 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 are assigned to that category. So we'll build that one as well. All right. Yeah, so with that, I'll pause, I'll check the chat right now. So I just seen 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 XSS is cross-site scripting. So that's a good question. React escapes HTML on its own. So when you go to render something with React, if the string contains certain HTML characters or certain HTML characters where a cross-site scripting attack could happen, where some rogue JavaScript running on the page, like a Chrome extension or something. 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 considerations that you have to make. You have to tell React to just trust certain content, if that makes sense. So since we're on that topic, I'll just dwell on this for a second here. So one example would be the content. So back on our single blog posts page right here, I mentioned to you that all of this HTML for the content came from WordPress. So if we didn't trust this data, if we want to 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, let me save that. See if we can get it to re-render. We should see a bunch of HTML tags. Yeah, this is what 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 would escape all of this HTML here. So you have to decide for yourself, like, do I trust this HTML that came from my CMS? And hopefully you do, WordPress is used by millions of people and has lots of eyes on it in terms of security. So I would say it can be trusted to output HTML if it's safe. So you have a few options. And if you decide you're gonna trust the 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 have a self-closing div like this and you say dangerously set inner HTML, and inside of this, you pass in an object with a key of double underscore HTML, colon, and the value of whatever that HTML is, in our case that's content, like that, this would be one way to handle it. So this tells React, don't try to escape this HTML for cross-site scripting protection, for instance. So if I save that and then look at it, now you can see React is, it's bypassing that escaping and it's rendering the markup that it was given. So this is one way to do it. In our application, I was letting a library do it. I have this HTML react parser right here, which comes just with a parse function. So this is another way to do it. Instead of doing it yourself with the self-closing div, in our application, I was just running the content through the parse function 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, so yeah, WordPress does its own escaping of HTML that it produces. In the frontend application, you have to tell React, hey, this string that I'm about to put on the page, it's already escaped HTML, I trust it.

5. Turning WordPress into a GraphQL Server

Short description:

To turn WordPress into a GraphQL server, enable the WPGraphQL plugin. It provides a GraphQL endpoint for your decoupled front end to hit. The GraphQL endpoint can be customized, but the convention is to use '/graphql'. WPGraphQL can leverage existing caching solutions like Redis or memcached to speed up GraphQL responses. A feature called persisted queries is being developed, which will allow caching responses on a CDN.

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 dive in deeper now. The next step on our list of things to cover is turn WordPress into a GraphQL server with WPGraphQL. So I'll show you all how to do that. But you won't actually need to run a WordPress site yourself on your machine. Instead we'll just use, we'll just connect to a WordPress site that's live on the internet.

So you can see here I'm using a free app here called local for running WordPress sites locally on my machine, and I will just start up 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 of things. All right, so here we're in the WordPress admin. How to turn your WordPress backend into a GraphQL API is by enabling that WPGraphQL plugin I mentioned. So that's here. If you don't have this on your site, you can just click add new right here and go ahead and search the WordPress plugin directory for WPGraphQL and then just find it on the list. So there it is, WPGraphQL. So you'd install and then activate that and then 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 your decoupled front end can hit. So if you're wondering, well, what is it? Where is that GraphQL endpoint, right? What you could 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 what the GraphQL endpoint is. You could customize it but the convention is just use slash GraphQL here. One note too, anybody who's, if you're jotting some notes and you wanna do this on your own WordPress site, one thing I would make sure to do on this page is on your local environment is 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 are failing, instead of getting very opaque, unhelpful debug messages coming back, if you enable this and you'll get much more helpful with debug messages. So just a note there if you're running WordPress site and doing this kind of thing, definitely enable debug mode and 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, it just says GraphQL requests must include at least one of these parameters, query or query ID or whatever. And that's because I haven't provided a query, right? All I did is send a get request in a browser to this endpoint, we didn't provide any data. So this is the expected output there.

So that's how you would do this on your own WordPress site. For us though, we're going to use a pre-defined GraphQL endpoint. So let's see, I'm gonna close this stuff, we don't need to look at that anymore. What we're gonna use instead is this endpoint here, so this would be number five on the list of links. If you go ahead and open that in a new tab. Oh, there we go. So that should send you to this content,.wpgraphql.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 local WordPress site. And if you notice, this is the same one that we had popped into our.env.local file here. That's where this came from. So we'll go ahead and use this for the rest of the workshop as the site to pull our WordPress data from. All right.

So that was number two that's how to turn WordPress into a GraphQL server with the WPGraphQL plugin. So I'll pause here and check out the chat and see if there are any questions here. Let's see. So is it safer to avoid dangerously set innerHTML and instead use a parser library? In most cases, no. 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 innerHTML actually. So if you look 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 a fallback for rendering the content, they themselves would use dangerously set innerHTML to achieve the same thing. So, no, I wouldn't say it's more or less safe. A parser can be helpful if you wanna swap things out. So let me do, show you a quick detour here. So I maintained this site with my team at work, developers.wpengine.com. We used to have like lots of resources, articles, videos and all kinds of stuff on doing this kind of thing, doing headless WordPress. 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. Oh yeah, our syntax highlighting is actually broken at the moment. This is a bad demo, I'm sorry. But anyways, this is the section 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 Next.js, you know, you wanna use the Next.js 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, if you have any internal links inside of your content, it'll give you just a regular anchor tag. So the result is in your front-end application, 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, then they'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. That's capable of doing the 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 a link component, so that you get the nice, quick client-side navigation. So that would be one example of when you would wanna use a parser beyond just escaping HTML like we're doing here. I'll put this blog post in the chat in case any of you are interested in what I'm talking about. You know, this post can be helpful. Yeah, I'll just put this site there as well if you're interested in any of our walkthrough videos and so on.

So M has another question. Does this endpoint cache queries? This is an excellent question as well. So wp-graphql that we're using here, this is what we're using for our API layer, right? To allow WordPress to talk back and forth through our ConnectedJS front end. It, I want to think of how to phrase this. It can leverage any existing caching solutions that you can use on the WordPress back end, 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, every user who hits 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 cache it in memory so that 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 memcached, those would work to cache 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 wp-graphql, and another guy, Mark, they're working on a feature called persisted queries right now for wp-graphql. And this is going to take the caching story to the next level. What this looks like is a request comes in for a query, and then after it gets resolved, that gets saved in some kind of, it could be saved in memory cache like Redis or memcached, but beyond 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 in Japan or something, if they're trying to visit your site and fire enough of GraphQL query, that query would hit their local data center within Japan, see that, oh, we have a cache response for this query that's still valid and immediately return that. So this round trip, going to the origin server wouldn't even be necessary anymore. Just serve up the responses right from the nearest CDN data center. So that's where WP GraphQL is headed, which is very exciting to me. This would be what I'm describing is similar to other solutions, like GraphCDN is a popular product that does this kind of thing where it takes GraphQL responses and then caches them like across the globe in a CDN. But pretty soon native support for that, that kind of thing, persisted queries will come to WP GraphQL. So I'm really excited about that. That'll make, like I said, take the caching game like to the next level.

6. Setting Up Apollo Client and Checkpoints

Short description:

We've covered the setup steps, including turning WordPress into a GraphQL server using the WP GraphQL plugin and setting up for local development. Checkpoints are available in case you fall behind. We recommend using Apollo Client for a real-world project to enable in-memory caching of queries on the client. The Apollo Client configuration involves installing the necessary packages, initializing the client with the GraphQL backend URI and cache type, and connecting the client to React using the Apollo Provider. TypeScript is not necessary for this simple project, but it can be beneficial for larger, more complex projects.

So I'm really excited about that. That'll make, like I said, take the caching game like to the next level. So stay tuned for that if you're interested, you could, follow the blog here or follow the Twitter account for updates.

Alright, okay, I think that's it for questions so let's keep rolling on the conference. These are excellent questions, so thank you so much. Let me know if you have more.

Alright, so what have we done? We did a tour of our app. We've seen how you can turn WordPress into a GraphQL server by using the WP GraphQL plugin, next Git set up for local development. So some of these steps we've done already, that would be these steps here in the readme, so we walked 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 in Git to get caught up if you fall behind at any point. Alright, 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 things to work. If you fall behind at any point and 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, Git checkout, 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, and just remember that this is the commit after we create the blog index page, this is the commit for after we create the single blog post page, and so on. So if at any point, you know, you're feeling like you're falling behind, just don't feel bad at all, just go ahead and check out this commit and that'll get you caught up with the rest of the group. Alright, but if everybody followed the steps, you know, you have your env.local file there and you ran npm run dev, you should be, you know, in the same spot I am here looking at the front end application. Can anybody in the chat, can you give me like a thumbs down or something if it's broken and you weren't able to boot up this application? Just let me know, I'll stay tuned for those.

Alright, so I think we're set up for local development here. Next thing is ConfigureApolloClient. So if you're doing this on a real world project, my recommendation would be to use some kind of a GraphQL client in your JavaScript application. That makes, so somebody asked the question earlier about caching, and the answer I gave was about like how to cache responses to come back from the server. Apollo Client though will do a different kind of caching, and that's in-memory caching of queries on the client. So that means, so the reason that's cool is if somebody is on a certain page and a query is fired off and a response is 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 see that some data is needed and then check its own cache and say, oh, have we fetched this same, you know, have we fetched this same exact data before? If so, just get it immediately from the cache and render that component, but if not, then it would actually make a network request to fetch the data, so. 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 cache if it's already gotten that data before and then only take the time to do the request if it's either never gotten the data before or it's too old, you know, it's the cache is not valid or whatever else so. So caching is one big feature, but there are other reasons why you might wanna use a client like Apollo, Apollo client, so. So we'll 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. Alright, so this page says, Get started with Apollo client. And it tells you 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 to instantiate a new client and then just give it a few pieces of data. You tell it, here's the URI for the GraphQL backend that I wanna use for pulling my data from, and here's the kind of cache I wanna use. So here we're just saying store the responses in memory. So use the in-memory cache that Apollo client has. So this we have set up in our app as well. I'll show you where that was done. So if you go to the underscore app dot JS file on our codebase, 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 Apollo client dot JS file and just pasted this in really here and say, I just did the same thing so I'm saying we wanna instantiate Apollo client. We are gonna use the in-memory cache 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.js to pull it from our environment variables file. So remember when we created dot ENV dot local, we specified this next public WordPress API URL. And then gave it something there inside of this file we're just 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 a set to one endpoint, or maybe on staging, if you have a staging site, you could set this to the GraphQL endpoint of your staging site. So that's what it would use. But then on your production environment, it would reference the GraphQL endpoint of your production site for example. And so that's what using this in your code, why that's useful, because depending on 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 it expects a prop of client where you just pass in this client that you created. That is exactly what we do in this app, in 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, uses the context API to make this Apollo provider available across your entire site. 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 pass through the client you've created as a provider. Then from then on, 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 covered. Alrighty, so that was it for all the setup steps. I know you haven't dove into the code and actually built anything yet. So hopefully you don't mind that and you've been kind of patiently listening through the stuff, but that's where we're headed. The very next step is let's dive in and start coding here with step five after we've done our setup stuff. So I'll pause there and check out the chat for a minute, see if we have any questions.

Okay, yeah, somebody joined late and just needs the link to the slides. Oh, 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 really necessary. There's very little going on. We're just fetching data from a backend and then running it to the page. It's not highly interactive and it's not a large code base where you would lose track of which objects have which properties and so on. In my experience, that's when TypeScript really comes in handy and is really valuable where you have a large, complex project and 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 React or modern JavaScript, I don't want to add an extra layer, another reason not to use TypeScript in this demo is I don't want to add an extra layer of complexity for them to deal with. If they are just trying to learn how to query for data from WordPress backend and render to the page. If I add all, and you have to add all of these type annotations everywhere, 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 can take the knowledge that you gained in this workshop as a first step or a foundation on how to do Headless WordPress. And then once you learn TypeScript, then you can layer TypeScript on top of this and add your type annotations to get the benefits of TypeScript. So yeah, so that's why we're not using it for this project. Also asked, why is Apollo client needed in a real world project, but not on the current example.

7. Using Apollo Client

Short description:

We'll be using Apollo Client to fetch data instead of using dummy data. Let's continue with the workshop.

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'm importing two things that we're not using yet. So like on our blog page on this site, I'm importing GQL from Apollo Client. And also importing the client that we had created inside of this Lib 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 dummy data and actually use Apollo Client to do the data fetching. So I hope that's helpful. So yeah, that's where we're headed. We will be using Apollo Client for this project. Great, I think that's about it for the chat then. So let's keep rolling.

8. Composing GraphQL Queries with the GraphQL IDE

Short description:

To compose a GraphQL query using the GraphQL IDE, you can use the graphical app. It provides a nice IDE environment where you can compose queries by selecting the desired data fields. As you select the fields, the query is automatically composed for you. Once the query is complete, you can execute it and see the data that your front-end app would receive. This is a helpful tool for building queries and getting a preview of the data that will be returned.

All right, so on the slides, we have compose a GraphQL query using the GraphQL IDE. So one thing that's easy to overlook here is the I in this word, right? You might glance at this quickly and think, oh, it's GraphQL. It's actually not, it's graph IQL, pronounced graphical. Right, and GraphQL is a popular JavaScript app that's used for composing GraphQL queries. So 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 composer queries. And it's going a little slow here. This is not a great demo. What is happening? Okay, I don't know why it took a long time at that time to load up, I'm not sure why, but this is what a graphical looks like. So it's a really helpful 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, let me get rid of some of this stuff. You can start, you can see the whole graphical data graph and start checking boxes indicating like what data you want back. So if you wanted blog posts, you can go posts. And for each of 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 pane right here, which is super handy. So then once you've selected all the fields that you think you want for this page of your front-end app that you're building and your query looks good, then you can hit this play icon to execute this and see on the right-hand side what your front-end JavaScript app would get back if it were to fire off this identical query.

9. Crafting GraphQL Queries for Front-End Apps

Short description:

In this part, we'll compose a GraphQL query using the graphical IDE. We'll start by checking the boxes to build the query for the most recent blog posts. We'll include fields like database ID, title, excerpt, URI, and featured image. This will allow us to get the necessary data for our blog page. Let's dive in and start coding!

So let's do that. I'll hit the play button and there we go. So here are the post nodes that I get back. So you can see 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. You can keep modifying this and keep checking boxes until your query looks good and the data coming back is what you need for this particular page or component of your front-end app. So once you're happy with it, then you can just highlight all of this, this query that you have had written and paste it into your front-end app. And that's what you tell Apollo to fire off. And then 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-graphical 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 GraphQL 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, open this up, that'll send you to this page. So that's graphicalonline.com. This is a cool little free hosted version of GraphQL that you can use. So for us, who can guess what are we gonna use for a GraphQL endpoint URL here? If you guessed the one from our EMV 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 gonna use. And we'll paste that here and then hit this button. All right, and you can see it looks pretty similar to what I showed you in the WordPress admin. We still have the query explorer. We still have this area to compose our queries and in this area to see the results of those. And you have some other options like 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 WordPress actually looks like. So if we try to just go to this domain, you can see that it's a WPGraphQL WordPress site. It looks like this. If you let WordPress handle the rendering using a particular theme, I think this is like the 2022 theme or something like that. Then this is what it would look like. But instead what we're doing is saying we wanna hit the GraphQL endpoint to get just raw JSON back because we're gonna handle all the rendering in our Next.js 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 gonna 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. I'm seeing some thumbs 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 could check some boxes here to compose these queries. So you can go to posts, starts building the queries for us, or I'll show you how there's another autocomplete feature. So everybody, let's try to do this, just this together here. So everybody open the Explorer. If it's not already open, you can hit this button here to open the GraphQL Explorer. And once that's open, scroll down until you see posts right there and then click to expand posts. And then we'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, 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. Sorry. All right, so let's start getting the data that we will need for our blog page. Give me a moment, just like a minute setup 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. I admit I'm a finished app that has the fields. I'm using a cheat sheet here. There it is, okay. So now I know which fields to tell us to query. All right, so the query we're going to try to compose here is the one we need for our blog post page. So as a reminder, that's this one, right? We're going to compose a query to tell Apollo client and ultimately tell WPGraphQL 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 posts, nodes. And then inside of this, we're going to check some boxes. So we'll do, the first one we'll do is database ID. So inside of nodes, if you scroll down and find to the Ds, click database ID, you'll see that it pops that into the list. Next we'll get the title. So scroll down to the Ts and click for title, right? If you like this workflow of clicking the boxes or checking the boxes, you know, 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 cursor is nested like this, you can just scroll somewhere inside of your query. So I'll just hit enter to get a new line. And then from here, if I hit control space, I get auto-complete here. So you can see I can using the arrow keys, I can go up and down. And then as I type, this list will get shorter and shorter and I'll try to auto-complete the thing I'm typing. So the next thing we're going to get is excerpt. So I'll try to type that. So if I type ex, you can see already it's narrowed the list down to excerpt. It thinks it knows what I'm trying to type. And if the highlighted one is correct, that that's the one you want. And if you'd 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 check boxes 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 U-R-I, that's the URI or 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.

10. Querying Featured Image in GraphQL

Short description:

Here's how to query the featured image in GraphQL. You can get the source URL and alt text of the image. Remember to handle cases where the featured image is null. GraphQL provides explicit information about the possible types of values, allowing you to know exactly what to expect in your Front-End JS App.

So this is our first time seeing this. So here's featured image in the Explorer, and you can see that it has a dropdown here. So if I expand this, here's featured image. It tells me it's going to throw an error saying, oh, you need a selection of subfields inside of this to tell GraphQL 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 gonna get two fields. So the first is source URL. So there you go, so let's scroll down to the S's and then check source URL. So that's the URL where this image actually lives, this actually, you know, JPEG or PNG 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 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? A featured image for some of these you might notice is null, right? You might think, oh, is this a mistake? Is it 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, is there a front-end, is there a featured image? If so, then go ahead and render to the page. Otherwise, if there isn't one, then don't attempt to render it. So have to 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 I hold down command, I'm on a max, if I hold down command and then click on featured image, right here, it pops up in the schema documentation and you can see what the type of this thing is. So the type of node right here for featured images is this media item, type in GraphQL. 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 Alt Text could possibly be, so it's always a string, for example, but other things in here, you may see that, well, it could be Null sometimes, other times it could be a string, and so on. So it's very handy for the fact that it's so explicit so you can know exactly what the possible types are in your Front-End JS App.

11. Composing the Query and Setting Pagination

Short description:

Let's pass in a variable for how many posts we want to retrieve. By default, it's set to 10, but we can increase it to get more. For example, we can select the first 18 posts by specifying 'first: 18' in our query. If we want to start from a specific post, we can use the 'after' parameter. In this case, we're starting from the most recent post by setting 'after: null'. This way, we'll get the first 18 posts from the beginning of the list.

All right, so 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 open some parentheses, and you can 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. So 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 were doing pagination, we could say after and say get the first 18 after the one on page three or whatever further on down the list, but just to be explicit, we can say after null, meaning start at the beginning with the most recent post. So we'll leave it at that just to be extra explicit, we'll say after null. So we're getting a post, the first 18 of them after null, so we're starting at the beginning of the list. So now if we fire that off, we should get 18 or however many there are, if there are only two blog posts, then you might only see two on this list, but we're getting all of them up to a max of 18 there.

12. Fetching Real GraphQL Data

Short description:

Let's define the query we need in our front-end app to fetch real GraphQL data. We'll use the gql tagged template literal from Apollo Client. We'll define the query, name it 'get posts', and pass it through gql. Next, we'll use the query const we've defined to fetch data from the WordPress backend using Apollo Client's query method. Once we get the response, we'll drill down to the blog posts and pass them as a prop to our component. Finally, we'll save the file and see the live data displayed on our front-end app.

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, I'll do a dividing line in the chat. There we go. I get 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 the query that we need in our front end app and that we're 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've said a few times, our job is to rip out the dummy data and get this actually working with real GraphQL data. So let's do just that.

So our front end page, bye-bye front end page, you're gonna break as soon as we do this, right? So I'll have you highlight these lines with the dummy data and delete them and then as soon as they save that, your front end app will crash and burn if we try to reload it here since it doesn't have the data it expects. So let's fix this by giving it the actual data from the WordPress backend. So I'll show you how to do that now. So what we need to do is use this gql. This is a tagged template literal is what it is from Apollo Client and inside of that, we're gonna 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 and all caps just like that equals gql and then two backticks just like that and then a semicolon after it. So if you read through the documentation on Apollo Client, you'll see this convention you use. It tells you to use this gql tagged template literal and then pass inside of the backticks the query that you'd like to run. So that's where this is coming from. So inside of these backticks, I'll just hit enter twice to make a little space. And what we'll do is we're gonna return to graphical and copy this whole thing that we had composed right here. I'll copy that and then paste it between these backticks 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 like working with GraphQL and Apollo and want the syntax highlighting within these GQL tag type of literals and other features, then you could install that if you want the Apollo GraphQL, but otherwise, if you're just seeing a solid text here, if it's all white or whatever, that's still fine. It'll still 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 in the browser console, Apollo Client is like throwing errors or whatever, it's referencing a certain query that's broken, there's the name that we'll see. It'll say the name of the query that failed is get posts. So we'll know which one that is. That's why we give it a name there. All right, so this is it for defining our query. By creating this query, passing it through GQL, that'll turn it into what's called an AST Abstract Syntax Tree. That's ultimately what Apollo Client, you know, expects to receive and can use to process the query. So 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 who's not super familiar with Next.js, get static props is an next jazz convention that they give you. They say that if you export an async function from your component file called get static props, then anything inside of this, Next.js will run at build time. So it'll effect, do any data fetching and anything you want to do build time and then pass these props through to the component when it renders on the Next.js server. So this is not something that the site visitor would ever have to wait for. This is done ahead of time when the page builds. So this is a perfect spot for us to do our data fetching. So we're going to make use of our client that we had created then. So at the top of the file, remember we had imported this client from lib, Apollo client, just like that, that's the thing we're gonna use. So at the top of this, we'll just hit enter a couple times and then we'll define another constant. So we do const response, we type that. Equals. We'll await the response of this. So we'll await client.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.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 going to say query colon. And this is where we pass in the query. So for us, that was getposts, all caps, just like that. So that passes in this query that we had built up at the top. All right. So once we get the response back from that, we have to actually make use of it. So instead of this postposts thing, so delete that. And then instead we're going to drill down to our blog posts. We're going to do response.data.posts.nodes. Just like that, I give you a second to type all that. So if you're wondering in your app, how you would know to drill down that far, GraphQL is really cool in that how you structure, the levels of nesting here, how you structure your query, the response that comes back will match that, which is very cool. So if you look at here, we had query, posts, nodes, and then the fields, the response is data, post, nodes, and then the fields. So if we drill down that far, 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. Cause we said, we'll add posts and then nodes, right? And that's where our posts would live. All right, so we're trying to drill down to each of our individual post nodes. And we're passing that as a prop, called posts into our component. Our component then is destructuring, and 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. Shazam, 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 data coming from a real WordPress site. So this is super cool, right? You can see we have the titles and excerpts being displayed here. And these are linked. So if I click on one of these, it'll try to send me to, you know, the single page for the blog posts that I had clicked.

13. Implementing the Single Blog Post Page

Short description:

We specified a max of 18 as well. If you get more advanced, you can do pagination stuff. If you're getting a type error, try console logging the response. Make sure Apollo client is configured properly. If you're still having issues, use the provided checkpoint. We're done implementing the blog index page. Let's move on to implementing the single blog post page. We'll build a query to use instead of dummy data. We'll use the URI to look up the blog post. Create a new query to get a single blog post. Let's go to the GraphQL Explorer and find 'posts singular'. Let's create a query that gets the title and date fields. Leave the ID blank for now. Your query should look like this.

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 either do infinite scroll where you just load more in right away when the user scrolls down, or have a load more button and load more. But for us, we'll just stop here and display the 18.

Alright, so check the chat real quick. So Vaka, I see. So type error, cannot read property data of undefined. Okay. So it sounds like that's coming from this point in the code, right? Saying that you're trying to drill down to data, but response, this thing is undefined. All right. Let's see. I don't know why that would be. One of the first things I would try is just console logging. This I'd probably just do console log, the response here, save that. And then if you open the terminal, you should see that data printing out. I'll try to reload my blog page and 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 have any data posts, and inside of that there's my array of nodes, and then a few other things, loading false, network status seven. So this is what is expected in that response. If you're getting something different, then it must be an issue with Apollo client, you know, not being configured properly. So I would just do some checks, make sure on the repo here, make sure you did all of these steps just right and you're defining this environment variable inside of the.env file just like this, it has to look exactly like that. Yeah, and this is 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 we're done, implementing the blog index page. So Vacha in the chat or anybody else, if you were struggling here and had issues getting the blog post page working, at this point you could run git checkout and then paste in this commit hash and that should get you back up to speed. So you should be able to... I would try git checkout with that commit hash and maybe doing command C or sorry, control C just to kill the Next.js server and then npm run dev again to get that backup and running. And at that point, you should see the blog page working like this. Alright, 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 GraphiQL and we've accomplished number six as well, implement the blog index page. By using that query we had composed, we told Next.js to run that at build time and then pipe that as props into our component and use that to render the page, right? So onto number seven now, so implement the single blog post page. So as a reminder, let's, oh, let me get rid of my debugging lines there real quick. Okay, so as a reminder, let's just take a look at our single blog post page. So that was this dot 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 props and that's what we're using to render the content. So it'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 let'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. So like this one, we had called our getPosts query like that. And you could 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 another query. And then when you go to execute it, GraphiQL will ask you, well, which one. You'll use this dropdown and say, do you wanna execute usePosts or usePosts? And you could tell it which one you want to run. So that's one cool way. If you don't wanna delete, the thing you had worked on building the first time, if you wanna kind of leave it in place or you're testing or whatever, it's okay to have multiple as long as they have 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 a fun one because this will be 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. I guess technically we had a variable because we said 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, whose data we need, if that makes sense. Let me show you. I'll just, let me just put the data back for a second so I can show you what I mean. So what happens is if somebody is on the blog page here and then they try to click through to one of these posts, this 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 the slug, all of that is called the URI. And that's the thing we're gonna actually use to look up the blog post. We're gonna tell 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 gonna use as our variable that we send in to our query that we're gonna build here. Alright, so let's do it. Okay. So here, let's create a new query to get a single blog post then. So over in the GraphQL Explorer, let's go down to the P's, element of P and find posts singular. So click on that. And already, you know, just like last time, it'll start building the query for us. And it even knows that post requires an ID because it asks, oh, well, which post do you want? So we'll have to address that here. So for the ID, yeah, you could, if you want, for testing purposes, you could pop in a value here. Even if you type a value, then that's the thing that would use as the ID. For us though, we want this to be dynamic. So it'll pass in a different, you know, it'll give you a value variable for each blog post. So I'll just leave that off for right now. I'll show you how to turn that into a variable. Or actually I guess we could just use this one. Let's see if we can get that working for demo purposes. Alright, so if I say that's the ID and I have curly braces and say get the title, does that actually work? Yeah, it doesn't, the ID isn't. So let's not attempt to do that right here. 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 rename it though instead of my query, you could do, you know, get post. For instance, I think I called it Get Post by Slug in our project. Yeah, okay, so let's continue with the fields then. So inside of this, we wanna get the date as the first field.

14. Composing the Query and Selecting Fields

Short description:

To get the content of the blog post, check the box for Content. For the author's name, select AuthorNode Name. For the categories, select the slug and name for each category node.

So if you scroll down to the Ds, we'll click on Date right there, oh, and I still have, yeah, so we'll need Title and Date. So both of those, so title, I clicked on one of those, we'll leave that and then grab the date as well. We want the content of this blog post. So in the Cs, we'll check the box for Content like that. We want the author and here again, then we see that this is not a checkbox, but it has a dropdown. So we'll need some nested fields inside of this. So click the Author dropdown and then Node. And for that AuthorNode, we're just gonna get that person's name so that we can display who wrote it. So I'll scroll down to Name and I'll click that checkbox. So there we are, AuthorNode Name, looking good. The last thing we need is the categories for the blog post. So scroll up to the Cs and then what we have is the Cs. Where am I? I'm still inside of Authors. Oh crap, my mistake. Okay, so it'd be Cs on this list. The nesting levels are confusing me. There we go. So 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 of this one now, so you can check the boxes for slug and name, or again if you're somebody who, you know, using the keyboard likes autocomplete, what you could do instead at this point is pop open a curly braces and do command space, slug, enter, command space, name, enter. To autocomplete those fields as well. Either way, you know, it works great.

15. Dynamic Query with URI Variable

Short description:

To make the query dynamic, we need to accept a variable for the URI. We define the variable in the query variables section and pass it to the query. We specify the type of the URI variable as an ID. We can then use this dynamic query to fetch different blog posts based on the URI passed in. We define the getPost constant using gql tagged template literal and paste the query inside it. Finally, we get the URI from Next.js context and pass it to the query to fetch the corresponding blog post.

All right. Instead of My Query, get post by slug. And our app is what we 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. It says the ID input is invalid. Since we're passing just an empty string here, need to give it something valid. 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 it into the chat and 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, and 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 its database ID, you can use its URI, you can use its slug, there are a few different identifiers. The default is the, what's called the global ID in GraphQL land. But instead, we're gonna look it up by its URI. So I'll do for ID type, getting a little crowded, I know. But for ID type here, I'll do Control space again and here's my options. So this is a GraphQL union it's called, where it just has these four options only. And you have to choose one of these or an enum rather, this is an enum. So are we gonna look at a database ID, or its ID, or it's slug or its URI? So in our case, we're saying, URI is the one we want. So I'll hit Enter and that will add URI. All right, so that should be it. We're saying, here's the ID 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 I'll hit the button and we'll try to execute this. Shazam, there it is. All right, this works. Because you see right now we're hard coding this. So if we were to highlight this entire thing and go paste it into our app, that's a problem, right? Since every single page we 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 of query variables, you can pop open some curly brackets here and it'll type in our variables. So let me get rid of these from here. And if I do ID colon, what 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 gonna pass in is our URI. So we'll do it like this. So for the ID, pass in this variable called URI, comma, and then our ID type. This thing we can hard-code, right? Since we're always gonna look it up by its 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, not defined by this operation here. It's saying, you're not accepting this variable. So we need to go ahead and do that now. So at the end of this line, you need to add some parentheses to say, you can see already my error, squiggly lines are going away. So at this point we can say, you're going to expect a variable and the variable you're going to accept is URI. And in GraphQL we have to be very explicit about the type, the type of argument we pass in. So we'll do URI colon, and then we have to tell it the type is an ID with an exclamation point. So if you go, you can go 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 been defined for us and then the exclamation point means it's required. So it can be, you know, in some GraphQL queries you can have an optional argument where like you could pass it in, but you don't have to. In our case though, we are adding the 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 in to the post. So now down in query variables, if I pop up on my curly braces and do control space, you can see here, yet again, I get auto-completed. It, 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 query variable section, and it's right. Right, so I'll highlight URI and just hit enter, and then it'll pop in URI here. And again, at this point, we can try using this long string. So let me just put this in quotes like that, and we'll try to fire that off. So this simulates, you know, a query variable being passed into the query and then used. So let me try this out now. So I'll hit play. There we go. It worked again. Yeah, so we're still getting the data 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 URI was posted, it was passed in. 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 gonna 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 can do it maybe further down so it's closer to where we actually use it. Yeah, like right above getStaticProps. Let's do that, so it'll be easier to see, you'll be able to see the component here and then see where we use it right below as well. All right, so at this point, right above getStaticProps, we're going to define a constant again, so do const, and then getPost. Go ahead and type that in. And just like last time, we're going to set that equal to this gql, taggedTemplateLiteral, and with a colon at the end of it. Tagged Template 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 passing in the string that's inside of these back ticks and then using that as its argument. All right, so inside of that, this is where we're going to paste our query. So, I'll go back to graphical and this whole query we had composed, copy that, and that is what we're going to paste in at this point. So, getPost, is 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. And 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 wanna drill down to the params, drill down to the URI, and then join those together with a slash.

16. Implementing the Single Category Page

Short description:

To retrieve the URI, we use Apollo Client to query the object. If the post is received, we check if it was successfully retrieved. If it is undefined, we return 'not found true'. Otherwise, we pass the retrieved post as a prop to our component. We have successfully implemented a GraphQL query that accepts an argument and renders the individual blog post pages. Next, we need to implement the single category page. In the category file, we define the 'git category' query, passing the slug ID and slug name as variables. We test the query and confirm that both variables are necessary. We then proceed to compose the query and retrieve the dummy data, passing it through 'git static props' to our component.

I just, cause by default it separates all of these. it sees the slashes here and tries to break them up. So, what we're going to 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 we do that, we receive, retrieve the URI that, that we're given. We need to actually try to look this up. So, we'll use Apollo Client again at this point. So, we'll hit enter a couple of times and we'll get our response back from Apollo. So, type const response equals. We're gonna await the response and then we're gonna call, client.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. Is git post, so I'll copy that and that's the thing that we're gonna 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 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. Alright, so once you've composed all that, now we're telling Apollo Client, here's the query to use and here are the variables to pass in and we're awaiting the response that comes back. So, at this point I just have to check to see was the 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 then we'll try to drill down into this. This would be response.data.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.post. So, try to drill down to that level, but if there's some error, if we weren't able to look up the static props, then this could possibly be undefined, right? Like Vaka said in the chat, for the last query, he was getting like an undefined message. So, it could actually happen here pretty easily if somebody just goes to our front end app and does this, right? If they type something invalid or try to 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 to 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 undefined, then that would make post under-defined. So, our check here just says, if post is falsi, meaning it wasn't defined, they go ahead and return not found true. And this will tell Next.js to render our 404 page for this app saying this page wasn't found. Otherwise, we'd make it pass this check and post is truthy, that means we found it, right? So, at 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 can get this working. So, I'll save all that and let's see if we can get this working. So, I'm just going to do a little sanity check. So, my app is still running on the front-end, so let me 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 on the dummy data content. Now, when somebody visits this URL building a bookstore, they're getting that actual blog post data, so it was written by that person in 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 in WordPress. Very cool, so that's it. So, that was our first GraphQL query that accepted an argument. So, hopefully that was an interesting thing for you to see and then we got this copy over into our app and wired up to render the 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'd you do with number seven there? Excellent, seeing some thumbs up. Okay. Let me see, how am I doing on time? Okay, yeah, pretty good I think. So we 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 just finished number seven as I said, on the list, right? Implement 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 pages, we have these linked, right? Tutorials and WordPress. If I click on tutorials, it's still that dummy data, right? It 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 inside of pages and then category, we have this slug dynamic route here. So if somebody tries to navigate to slash category slash some slug like that, then that would map to this file right here, all right? And just like, just like we've seen many times before, we're pulling out the dummy data and then passing that through inside of git static 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 gonna define a query and let's call it git category. So go ahead and head back to the GraphQL IDE here with me and type query git category, just like that. 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. This one, again, will accept a variable that it's gonna use to look up the category. So instead of git category or after git category, we'll open up some parentheses and we'll say, we're gonna accept, sorry, can't 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 gonna pass in, oh hang on here, there's a mistake. Okay, for this one we'll accept to, all right, we'll do slug ID and then slug name, and that thing is gonna be a string. With an exclamation point, hang on here. Let's test something with this query, I think we might be able to simplify it. Let me see, so category, the ID is, I'm just gonna do some live coding myself here to see, we actually don't need both of these variables. I think we can get away with just one, I wanna confirm that real quick though. So down in query variables, I'm gonna pop open some curly, do control space to get my auto-complete, enter for slug ID. Now I'll try to pass in a valid slug. So like this tutorials, I'll just copy that, and try to use that as an ID. All right, yeah, that works. So I think my, in the original code base, I was passing two 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.

17. Building Nested GraphQL Queries for Categories

Short description:

We're going to include slug ID and then slug name. We're going to do get category. We're going to pass in just just the slug ID like this and then for the slug ID, we'll pass in tutorials. We need to get the posts within this category as well. 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 need about them. Let's attempt that. This is working out really well. We have the name of the tutorial that we'll use to display at the top of the page there to tell people this is which category. And then we also get our array of nodes back with the info that we asked for here. Cool. I think this will work well. Let's check in the chat. Everyone's doing well. Let me know if you're having any 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.js page here. And we will make use of this. First step, just like last time, we will last two times, I will rip out the dummy data. You don't need that anymore. And then down right above git static props here, this is where we'll define our query. So the drill by this point we'll do const git 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 back ticks, that's where we're going to paste this whole thing. And next we need to actually make use of it. Now, we need to use that to look up our category. Right below this, I'll do const response equals await client.query, like we've done several times before. And then inside of this, we're gonna pop open our curly braces, and for the query to use, we're gonna say use that query, and then we're gonna pass in the variable that it expects. So we'll say variables, and that'll be an object, the variable that it expects is the slug ID. So we'll pass slug ID, and the thing that we're gonna pass in is this slug that we had pulled out of the params. A better name, we could have chosen to call this just slug probably, might've been a better choice than it would match what we're pulling out of here, but naming is hard, and this will work great because what it actually maps to is passing as the ID field, input field in 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? Just like last time, we need to check to see is this category valid? Were we able to find this page? So we'll do that, very similar to what we did last time. We'll do const category equals response.data.category. 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 falsy, then we'll pass that through to our component as props. And that's what we'll actually render on the page. I think we're good with this one. So I will save that. And we'll see how we did. Yeah, it's working. So now when I visit slash category slash tutorials, I get a proper name for this category that the user's visiting. And then the posts within it are all ones that are in that category. Well, cool.

I see why I was doing it. All right. So we're going to go back to our to's because we have a nested query for posts. Anyways, okay. We're going to include slug ID and then slug name. Wait, I lied. Okay, I've changed my mind three times now. You think I'm crazy. I'm sorry. I think we can just use the one that's like a thought. So here's what we're going to do. We're going to do get category. We're going to pass in just just the slug ID like this and then for the slug ID, we'll pass in tutorials. Okay. So that that works for getting us the name back. And now we need to get the posts within this category as well. So at this point, if you start typing P O S, you'll see the auto complete pop-up. So you just hit enter and then we'll need a sub selection here. So some fields nested inside of posts. So I'll open up some curlies and inside of this, we need to post nodes. So we'll type nodes, open that up. I'll do control space again to get my auto complete and start taking database ID. That's the first one we need. Next one is the title of the post. Next one is the excerpt. There we go. Next one is the URI like that. And the next one we'll have yet another sub selection, that'll be our featured image. So if we 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 time we tried this. Yeah, just alt text like that. All right, so this is 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 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'll 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 page there to tell people this is which category. And then we also get our array of nodes back with the info that we asked for here. Cool. I think this will work well. Let's check in the chat. Everyone's doing well. Okay. So let me know if you're having any 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.js page here. And we will make use of this. All right. So first step, just like last time, we will last two times, I will rip out the dummy data. You don't need that anymore. And then down right above git static props here, this is where we'll define our query. All right, so the drill by this point we'll do const git 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 back ticks, that's where we're going to paste this whole thing. So we'll copy that whole query that we had composed and paste that inside of our back ticks. All right, and next we need to actually make use of it. So you can see here yet again, we're drilling down to contexts and then params and then slug to pull the slug out of the URL for the page that the user is currently on. Now, we need to use that to look up our category. All right, so right below this, I'll hit enter a couple of times, I'll do const response equals await client.query, like we've done several times before. And then inside of this, we're gonna pop open our curly braces, and I bet you can guess what we're gonna do next. For the query, we're gonna pass through this thing that we just built, right. So for the query to use, we're gonna say use that query, and then we're gonna hit enter and pass in the variable that it expects. So we'll say variables, and that'll be an object, the variable that it expects is the slug ID. so we'll pass slug ID, and the thing that we're gonna pass in is this slug that we had pulled out of the params. Yeah, okay, yeah. A better name, we could have chosen to call this just slug probably, might've been a better choice than it would match what we're pulling out of here, but naming is hard, and this will work great because what it actually maps to is passing as the ID field, input field in 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? Were we able to find this page? So we'll do that, very similar to what we did last time. We'll do const category equals response.data.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 we'll do a 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 falsy, then we'll pass that through to our component as props. All right, and that's what we'll actually render on the page. So I think we're good 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 slash tutorials, I get a proper name for this category that the user's visiting. And then the posts within it are all ones that are in that category. We do a little check, I guess, we can like open a post, scroll to the bottom and then, yup, sure enough. So all of these are within the tutorials category. Well, cool.

18. Implementing the Search Page

Short description:

We'll now move on to the search page, which is our first page that involves client-side requests. Up until now, we've been making build-time requests on the Next.js server. However, for the search page, we need to make on-the-fly GraphQL requests from the browser to our WordPress backend. We'll start by composing our query in GraphiQL, specifying the search term and the fields we want to retrieve. Once the query is complete, we'll pass in the search term dynamically and make the request from the browser. We'll handle cases where the search term returns no results by displaying a corresponding message. Let's proceed to implement the query in the search.js file.

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. All right, cool. Thank you. All right. I'm feeling good. We've accomplished a lot, right? In a, I don't know, two hour period or whatever, we've created our blog index page, our single post page, our single category page, we're not even done yet. Next is that search page. So this one should be fun, like I said, because this is our first page where we're doing client-side requests. So it's the first one, where we're doing client-side requests. Up to this point, we've just been doing build-time requests. So inside of, you know, Git static props here that Next.js provides, we've been firing off queries, you know, at build time on the Next.js 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's 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 rerender the list. So this one 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. We try to submit the form. All this dumping data stays unchanged. So inside of pages, we'll open up search. Here that is. And we'll get this working. Let's compose our query first then. I think that'll be helpful. All right, so like we have before, let's head back over to GraphiQuel. So we can wipe out our query variables and our query here. So we won't need those anymore. Next we're gonna do a new one for searches. So let's do this. So type the word query and then do type search posts. Just like that. So query search posts. This one, we'll expect an argument, of course we need that user's search term that they wanna use. So I'll do dollar sign, search term, colon. And then the type of variable that we wanna accept here is a string. So do capital S, string, and we wanna 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 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, gimme the first 10 after this other post or whatever, do cursor-based pagination. 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 in this category or that match this search term or whatever. So we'll do that. Now we'll do where, colon, and then this is an object here. So instead of where, that expects an object. Inside of here, here are all the ways that you could filter, a post. So for us, we're gonna do it by a search. So if I start typing that, it'll autocomplete. Search, colon, and this is the point where we wanna make our query dynamic and pass in that search term that the user had given us. So for the search here, we'll pass in search term. All right? And then from there, we need some curly brackets after the posts. And here we'll drill down to the nodes. Open more curlies. At this point, we need a few of our fields. So database ID is the first one. Next one is title, so type title. Next one is excerpt. Next one is URI. Next one is featured image. And this has subselections, we'll do a curly, and then for the node on that featured image, just like last time, we'll do source URL and alt text. And just a side note here. You might be looking at these fields going, man, we've typed this so many times. This featured image thing that always has a node and always has source URL and alt text, we've typed that like three different times already, right? It seems 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 GraphQL fragments. That's what they can help solve. It's where you have like part of a query, somewhere in your code base you've defined it as a fragment, and then you pull that in and inject it into the points within other queries where you wanna use them. So stay tuned for that to see how 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 is 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 autocomplete and it'll tell me that it thinks I want search term, which I do. And here, this is really free form, right? This is kind of fun because we can search for anything at this point. So the GraphQL endpoint we're using is for a WPGraphQL blog and they probably talk about cool headless WordPress topics like React, how about, right? So I'm gonna type react here, that's what we're gonna search for and fire this off. So there we go, look it, first post, build an app using React and the GraphQL AP plugin for WordPress, right? Just so happens to be a post written by me on the WPGraphQL blog. So this is cool. Our search works to find posts with React. You know, we can try to find edge cases like what if I just type a bunch of gibberish and attempt to search here. There we go. I still get a successful response, but the nodes that come back is just an empty array. So I have to keep that in mind on our front end and say, you know, if we ran the search and that nodes are empty, maybe fall back to just displaying a message saying, no results found, right? But for other topics, let's do like GraphQL or something like that. For other topics, it seems to work great to find the matches. So this is cool, that is 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 the 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.

19. Implementing Dynamic Search with Apollo Client

Short description:

We're going to use the useQuery hook from Apollo client to run the query on the client side. We'll pass in the query and the necessary variables, such as the search term. The useQuery hook will handle the loading, error, and data states for us. We'll render the post list based on the data retrieved from the query. If there is an error, we'll display an error message. If no posts are found, we'll display a corresponding message. The user can submit the form to search for posts based on the entered search term. The useQuery hook will fetch the data based on the new search term and trigger a rerender of the post list. We have implemented a working search page that allows users to search for posts based on a specified term.

So we'll do const, we'll call it searchPost. Or posts, I mean, all caps like that equals GQL. You know the drill by this point and then inside of our back ticks is where we're gonna 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 gonna do it at build time. Like I said, if you notice in this file there is no get static props. That's cause we don't need it. We're gonna run these queries on the fly from the client. So to do that we're gonna 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 docs they have use query, use lazy query, use mutation and all the documentation on how to use those hooks. On 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 instead of our component instead of having this dummy data, we were saying const loading is always false. Const error is always false. And then for the data we were passing in our dummy data, instead of all 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 query. So, whoops, what happened there? Okay, so start by typing const and then we're going to destructure some things that we're gonna get from use query. So we're gonna do, we're gonna pull out that loading state, we're gonna pull out an error if there was one and then we're gonna try to access the data. So those three things are gonna destructure and pull out of the results of our call to the use query hook. Whoops, there we 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 define. So for us, if we scroll up, our query is search posts, right? That's the names all copy the name of that const and I will paste it here. So I'll tell use query which query to run. And now we need to pass in the options array as well to tell it about our variables we need. So pop open some curly braces just like this and inside of there, we'll do variables, colon and open up an object inside of here. We need to provide the search term. So what we're gonna 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 gonna pass in to our query right there as the search term. One other thing we're gonna pop in here is this notify a network status change that comes with Apollo. That's a lot to type but if you start typing N-O-T it should pop up for you. We're gonna set that to true, all right. And the reason for that is if you don't set this to true, Apollo will only set loading to false the first time the query is run. I know that's weird, but that's just how it works. So if you run the query once, loading will be true while it's being resolved and then set to false. 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 toggle between true and false every time which is what we want. So I know it's kind of a weird quirk 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 and the variables we need and getting all this stuff back. All right, below this have posts line should still work just fine. You can see what we're doing here we're trying to drill down to data.posts.nodes.length and they were casting that to a Boolean. So if either the data was undefined at some point in here and that would be 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 word where the nodes array was empty. If that's the case where post.nodes.length is a length of zero, then in that case have posts would also be false, right? Since we don't have any, otherwise if we drill down to this level and length is truthy when we cast it to a Boolean like it's one, two, three, or some other positive integer then have posts will be true there. And 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 useState, it's passing an empty string. So we're saying when this component first loads, there is no search term, right? Just keep that empty. And then we're pulling out of that, the current search term and then the function we need 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 providing the default form submission on the web. We're using this form data just built into the web platform here. We're just saying we want new form data for this particular element, or for this HTML element that was submitted, we're pulling the data out of that and then do object dot from entries to pull out each of the individual 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 up the values. They were drilling down to the search term value and calling our set search term function here that we got from use 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 rerender this component and the search term variable will be new, right? It will be updated and reflect this, the new search term. And then Apollo will see that in its new use query click here, it'll see all this search term value is this new value after the rerender happens, I better go ahead and fetch this data and then 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 the use query fires off a request using that new thing. And that triggers a rerender of 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 the display? A loading message, or do we currently have an error than to say an error has occurred? You could do more robust error handling here, of course, and should dig into like error.message and display the actual error that came back. For us, that we'll just say an error has occurred, frowny face. If we don't have posts, then we're saying no posts 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 it all the way down here, we go ahead and try to render our post list and pass 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 loads, so this is how it looks now with our working search page. So when 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 swap 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 have it set up right now. As soon as the component mounts, it fetches the posts using the current search term, which in our case is empty string, right? So it just searches like all posts. To hear 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 Jibberish 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, so I'll pause here and check the chat. See how we're doing. Oh, Patricia, yeah, absolutely. Sorry, you had to wait ages for this.

20. Apollo Client and Cache Policies

Short description:

We have a working search page that allows users to search for posts based on a specified term. The Apollo DevTools can be helpful for checking the cache and composing queries on the fly. WPGraphQL can be extended to integrate with other WordPress plugins, such as advanced custom fields and Yoast SEO. Apollo Client allows you to define cache policies to customize caching in your JavaScript app. Fetch policies like Cache first, Cache only, Cache and network, and network only provide flexibility in how you handle caching.

You 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 this point to remind the group. If at any point 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 can just type Git checkout with this commit hash right there to your code base up to the current one. And then if anything's screwy after that point you could just hit Control-C to kill your next JS app and then NPM run debbing, back up and running, and then you 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 requests and you can see each of these GraphQL requests fire it off. So again, if I do, test or react search. Oh, you know why? So this is actually a good lesson. I didn't see a network request. Who knows why? Can somebody tell me in the chat? For some reason, I didn't have to fire off a request to the server. Yeah, exactly right. Yeah, I see people saying, cache. That's exactly right. So 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 cache data, you can see what Apollo has cached. Yeah, so here it is. So Apollo has cached data for this query and it's in memory cache already. So when I typed react and hit search, it just checked its cache and saw, oh, I have these seven post nodes here already in my cache from previous, from times when this 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 backend for that one. So that was cool. What if I do something we haven't searched? What if I do view or something like that, search? So now you see that there is an actual GraphQL request here. It's kinda cool, you can see what it looks like. And then here's the header that was sent on it. 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 then Variables, which was the variables we'd passed along. And then you can look at the response that comes back and see that it's data, posts nodes. It's in that same shape again that we had defined when we wrote the query. It's in that same shape here when it comes back. Yeah, so it's kind of interesting. So if you're somebody who wants to work with this stack, you might want to check out the Apollo Dev Tools. They can be handy sometimes for seeing 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 as just paying attention to the network requests here. If you're doing anything client-side like this, they can see when the requests are being fired off and what those payloads look like when they get sent. Fun stuff, all right, I'm looking back at the chat again. Let's see. So, Victor, can we query data through GQL the same way for plugins in WordPress? Yes, you absolutely can. If they're in the GraphQL schema, that would be the caveat there. So if you go to wpgraphql.com and then click on extensions right here, it says WPGraphQL can be extended to integrate with other WordPress plugins. Here are a list of WPGraphQL extension plugins. Many of these plugins are maintained by community contributors. So here, you can see some popular ones. So somebody mentioned advanced custom fields, right? One of the most popular plugins in all of 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 a number of other plugins that Delicious Brains had been maintaining. But anyways, there is a WPGraphQL 4 advanced custom fields extension here. So what you need to do is just install two things. WPGraphQL itself, and then this extension, as long as you do both of those and have those activated, then it provides some new features in the UI for ACF where you can define a field group, you know, with all your fields in it, and there's a checkbox at the bottom that says, expose in 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 of the fields for ACF to the GraphQL schema. So then when you're in graphical like this and you're, you know, trying to query for the data about posts, you would just see all of the fields from ACF, you would see, you know, they'd be there at your disposal. Yeah. So that's there for ACF and a number of other things. There's Ninja Forms, WooCommerce, Gravity Forms, you know, a number of other things. So you can check out that list if that's helpful. Yeah. My pleasure. Let's see. Yeah. Yoast SEO, that's another one. Yoast is used on like every WordPress site, right? If you're in the WordPress space, you know how prevalent that is. Yeah. Ash Hitchcock, who's really active, he builds a lot of Gatsby sites for his clients, I know. He built a Yoast SEO extension for WPGraphQL that a lot of people use. So Yoast is there on the list too. Yeah, so, Stefan, you're asking, how long is data kept in the cache? Is there anywhere to clear the cache from the backend when we make a change in the CMS? Yes. Excellent question. A Poll Client lets you define cache policies. Yeah. So, it gives you all kinds of options. You can customize how you want to do caching. Yeah. So we can spend a minute checking this out if we want to. Customizing IDs. I'm trying to remember where that, where the page. Let's see. A Poll Client cache policy, few of them are named like Network, cache first I think is the name of another one. Fetch policy, there you go. I was calling it cache policy, it's actually called Fetch Policy. Yeah let's see, supported Fetch Policies. Okay, here we go. Yeah, so what you can do in your friend JavaScript app if you're working with Apollo Client, you can define what Fetch Policy you want to use, so you can do Cache first, which tells Apollo to query against the cache first and then fall back to the network, Cache only, which is the only you ever use that, Cache and network, network only. So if you do this, and it basically tells Apollo never cache anything with the freshest data, you know, don't cache it at all.

21. Caching, Cache Invalidation, and Fragments

Short description:

Apollo Client offers options for cache control and cache invalidation. You can control caching with fetch policies and specify how long data should be cached. Cache invalidation can be done by refetching queries after a mutation. Next.js incremental static regeneration feature allows serving stale pages while regenerating them in the background. If WordPress is down, Next.js can fall back to serving cached pages. However, some dynamic features like search may not work in such cases. Fragments in GraphQL allow co-locating component data needs with the component itself, improving code organization and reusability.

So if you do this, and it basically tells Apollo never cache anything with the freshest data, you know, don't cache it at all. You can do that, no cache, or stand by. There are a few different options there. So this is how you can have some control over, you know, what it's caching, and so on, and for how long. There's some options for that.

Beyond that though, you're asking about cache invalidation, right? It's like, well, if some data has changed, how do I clear the cache, you know, and tell Apollo to refetch it? And you can do that as well. So that'd be like when you do a mutation. Let's see if we can find the docs real quick. Let's see. Yeah, here we go. So refetching queries or refetching after update. Yeah, so you can do this if you have a mutation that you're doing in your friend JavaScript app where the user is like adding it 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 callback function. You give it a callback function and say, that you wanna, you know, refetch a certain thing. You get a certain query and say after this mutation, executes, you added to do, and refetch this query over here, that is responsible for fetching the list of to dos, right? So, if you do that, then it knows, okay, I'll refetch that list. And then react will re-render the list of to dos to show, you know, the updated list, which includes the new one that they had just added. And then you can say, okay, so I got my query. I know that I'm going to run it again. And then I go ahead and I'll re-render the list that they just added to the list. So, you can do stuff like that. If it's the user themselves, like making mutations, you can tell a POP client to like blow away part of the cache or refetch part of the cache so that it gets the new data there. As far as any other caching of just server data, that you can control with like the fetch policies. So, if you wanna Google just fetch policies and look at those, that page that we had looked at, that's how you would control that.

Alright, yeah, I think we're good then. How are we doing for time? We can dig into our fragments if we still have time. I think we have 30 minutes remaining. Yeah, my pleasure Stefan, hopefully that was helpful. Their docs are really really good. I found Apollo's docs. If you see I dig into those, you can typically find your answer. All right, yeah, so at this point we could gig into some of the fragments stuff, unless I see in the chat that the group wants to go down to other rabbit holes that I'm happy to use it. I got a rabbit hole. Good, what happens when 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.js tries to use this API layer to contact WordPress to get through data. WordPress has downtime, right? The server's not there. So this can be handled a couple of ways. One way is in Next.js, if you're using like it's incremental static regeneration feature 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 a really cool feature. So you can tell Next.js, and if you're not familiar, if just Google Next.js incremental static regeneration. If you Google that, if you're not familiar that'll you know, explain kind of what that is. But it's basically tells Next.js, I want this to be a static page, but it should only last for a certain amount of time, you could specify and say, regenerated every 10 minutes, every hour, once per day, whatever you want. On that interval, Next.js will, it follows a stale while revalidate model, where it'll, if a request comes in and 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. But then in the background, it'll kick off the 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 cache page. So to them, it's still a 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.js will not swap out the old cache page for the new one if it fails to do any of the data fetching. So that'd be one solution to this. So if WordPress had downtime and Next.js 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 would 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 cache pages, you know, whenever your data sources in our case, WordPress, like happened to be down. So that's one cool solution. It doesn't handle every case, of course, so like our search page, right? If somebody goes to the search page and tries to perform a search and the WordPress is down at that moment, like then of course, we can't, you know, we can't really do anything about that because we need the actual, you know, data from WordPress. So the best you can do there would just be to follow, to fail gracefully, right? Like on our search page, we just have, if an error happened, in our case, Apollo would call this like a network error, like it tried to send the request to the backend API and got, you know, either a 500 error or it was offline or whatever else. So you just fall back, you know, and fail gracefully and say, 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, yeah, doing the like the static rendering of pages can really save you sometimes 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. GraphQL fragments are really cool. Let me show you what they are at a high level. So let's say we, so we had this search post query that we had composed, right like that. What we're able to do with fragments is kind of break up some of this and define it other places. Let me show you what I mean. So if 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. Wanna get myself. Get my cheat sheet so I can look at my own app in the syntax here. Look at the post list, oh yeah. I had to refresh myself on the syntax. So featured image is a fragment where we're gonna define, and actually let's do a different one that we'll actually use in our app. So this kind of fictitious one I was gonna do on the search page, let's just dive right into it and we'll start with the real ones on the blog page, how about? Alright, this is the one where we got the first 18 posts and display them on a grid, right? This one, let's say like these nodes here, we don't want this data to live here because actually, if you look at this component, how much of that data does it care about? None, right? It just grabs the posts and sends them straight through the post list component. This component actually doesn't care about all of the fields that we're 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 create some fragments so that this data lives and is defined maybe with this post list component, if it's the one that cares about that data or otherwise with this postcard component. Since it's the one that cares about some of that data, why not just define a fragment in the same file where we define the fields that we need and then immediately below it inside of the component, go ahead and destructure it and use those same fields. Like, wouldn't that be a nicer, more organized code base for us, right? And that's what fragments allow you to do. So we can do that, like, with the blog page and then post list and then post card. So I'll start with, like post card since that's the most granular, I guess. That's like the, it doesn't render anything else. It just gets rendered by post lists, which gets rendered in turn by blogs. So let's start with like post card. I'll show you what I mean by creating these fragments. This is what you would do like above this thing, you would do, so we'll export a constant from this file.

22. Creating Fragments in GraphQL

Short description:

In this section, we'll learn how to create fragments in GraphQL. Fragments allow us to define the specific fields we need for a component's data requirements. We'll define a fragment called 'postcard fields' for the 'post' type, specifying the title, excerpt, URI, and featured image. By using fragments, we can organize our component's data needs in a separate file and easily make changes to the fields without leaving the file. We'll also explore how to use the fragment in a query by spreading the fields using the three dots syntax. This approach improves code organization and reusability.

So let's start with like post card. I'll show you what I mean by creating 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 wanna try out fragments, like you can type this along with me, we'll work through this together. It's like, we have the other pages. So I do export const and then in all caps, we'll do post card fields like that GQL. Our usual song and dance like that. Instead of defining a query inside of here, now though, we're gonna define a fragment. So we're gonna type fragment post card fields like that on post. So this is, the graph QL specification says that if you wanna define fragments, you have to tell GraphQL what type it's on. So we're saying there's this type in the GraphQL schema called post and the fields are gonna define are the fields that we would like data back on that type, if that makes sense. If you're not sure on like what these types even are, you can see them in the docs right here. So if I do a query for like posts to get the nodes and then for each of those, I get the title or something. Let's say that this is the query I've composed here and you're wondering to yourself, what GraphQL types are behind this thing here? If you, command click on post, that'll pop open the documentation right here or nodes, you can see that nodes is an array of this post, capital P post type in the GraphQL schema. And if you click on that, then that in turn would tell you, all right, the post type, here's all the data within it, author category, blah, blah. So that's where this comes from. We're saying on this capital P post type in the GraphQL schema, we're going to define a fragment with some fields for data that we care about. So that's where this comes from. So our fragment is named this, it's on the post type. So next open some curly braces or open the curlies inside of this. 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. So let's type that. It needs the excerpt, type that. It needs URI, all right. And it also needs featured image. And that's the one, remember we need a sub selection. So we'll do curlies. And then the node, curlies, and on that, the source URL and the alt text. All right, so now that we've defined this fragment, we see how nicely organized this is. It's like, here are this component's data needs. It cares about title, excerpt, URI, and featured image. And then here's the component, title, excerpt, URI, featured, featured image. It just goes out 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 anywhere. So we need to go ahead and do that. So postcard fields, title, excerpt, URI. So it 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, excerpt, URI, featured image, this component in this file doesn't actually care about any of this data. So we could 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'm just doing this for demonstration purposes. So just hold off on the typing if you're following along for a minute. So if I import that fragment from postcard, like this, hang on, I'll just take a minute. Where was that postcard? Okay, so now we've imported our fragment. So we need to insert this thing inside of this tag temple literal. And we can do that just by sticking it at the end. So if you hit Enter and then use this syntax, this and JavaScript, this tells JavaScript to interpolate some data here inside of this string. So I'll open that up to interpolate some data, and then we'll paste in the name of our fragment here. So we imported it and then interpolated it here. Now we go ahead and use this inside of 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, dot. And then we can grab the names we call it postcard fields. So I'll copy that. And here, postcard fields. So this is telling GraphQL to like, spread or inject the fields that we had defined in that fragment at this point in the query, right? So I'll save that. Hopefully I did everything right. Let's see. Blog, I think so. Let's try to do it without. So I'll remove this all together and then it should break. Yeah, there you go. So fragment postcard fields is never used. Plus it doesn't have any, the data that it needs isn't there. But if I go ahead and use our fragment and spread those fields or inject them at this point in the query and give that a save now, it works, right? So 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 to this postcard and you realize, oh, you know what? I need another, an additional piece of data on the post, then you can just hop above here and 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 lists here that I think we're gonna use. Let me look at my finished product. Yeah. So if you want to get technical, we could go even further with this. Cause right now we're saying for each of the post nodes, we need the database ID, but then 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. Cause it's just going to pass that along. You know? So even this database ID, this component doesn't care about. So if you 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 gonna delete some of this stuff. So no longer use this fragment in this field at all. I'm just gonna leave it in this state for now. So now you continue if you're typing along with me, you continue at this point.

23. Fragments and CMS Comparison

Short description:

We define fragments in GraphQL to co-locate component data needs with the component itself. This pattern allows for easy management and synchronization of data requirements as the code base grows. WordPress is a robust and popular CMS, while other headless CMS options like Contentful, Sanity, and Prismic offer modern content modeling and decoupled front-end capabilities. However, these CMS options are proprietary, which may raise concerns about price changes or licensing. Strapi is an open-source JavaScript-based CMS worth exploring. Next.js can be used as a static site generator for fully static pre-rendered sites if there are no dynamic elements like forms or comments. It is possible to build a static site using Next.js and a local headless WordPress installation, but it may not be suitable for production clients.

So, all right. So we define our fragment here and really post card, it gets rendered at this point inside of post list. So this is where 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 too. So type that, so if you're following along, you type this type this with me, so export Const. This will be post, post list fields, like that, equals GQL. All right, hit enter a couple of times, open that up, and this will be another fragment that we're defining. So fragment, there we go, fragment, posts, list fields. There you go with 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, a database ID. Everything else though, it's just passing through to post card. So this is where we can do this thing where we import post card fields from this adjacent component here from post card. So if you type that, import post card fields from post card, we'll take this fragment and interpolate it inside of this fragment here. So I'll 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 fragment inside of this other fragment inside of post card, I'll just grab its name, right? And then remember the syntax for this is just the three dots. So I'll say inside of this other fragment, right next to where database ID is, I'm gonna do dot, dot, dot postcard fields, right? All right, and now this postcard fields, 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, let me check the chat, okay, I think we're doing good. Let me know if you have any questions as you go through this fragment stuff. So 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 wanna import something else. We can hit comma, read the comma and then curlys. And the other thing we want from that file is this const that we've defined here, right? So that's the thing that we're also importing from post list. And this thing like we saw before, we're gonna hit enter and interpolate so that we have access to it inside of get posts. And now, as we saw before, we don't even need database ID at this point anymore. All we need are the post list fields fragment. So I'll copy the name of this fragment and then dot dot dot post list fields. All right, I'll save that. Save that. And post card is already saved so let me see if it works. Yeah, so everything still works. So hopefully you see the flow here. So starting at the highest level like blog, we're saying here are this component's data requirements. Really all it cares about is the collection of posts, right? So if 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 deferring that decision making to this post list fields component. So if we head over there and 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 specific field that I need to render my data. As far as any other fields on this, I'm deferring that decision making. Go over to postcard, you know, and look at the fields it needs. I'm deferring any other decision making over to the postcard. And then you 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, 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. And it makes things really easy to manage. I've found, like, as your code base moves and changes and grows, it's like, as long as you have a fragment here with the data needs and that kind of maps to what the computer 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 components up in the component tree that are defined somewhere else far away, or whatever. This makes it nice and close to the source of where they're actually used. All right, so that's it for the components or 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 not only for the blog page, but also like the single page here, it breaks up like some of the stuff that the single post page breaks that up into fragments and then composes those together as well, maybe the category page as well. So yeah, if you wanna see, I'll stop there with one example that we did with like the blog page, how to define fragments and compose them together. But if you wanna see some other examples, like you could just check out this commit here from our checkpoint to see the, and then that would be like the final application at that point. Yeah, so I think we're nearly at time. We got a couple minutes left. I'd love to hear some questions though. 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, my team produces all kinds of resources on this developer's site if you want to check out 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 says, which CMS do you prefer? Yeah, that's a great question. I personally have spent a very, very long time in the WordPress space, and I know it really well. I've never launched another production project using another CMS. I really like some of the modern headless CMSs that are popping up, I think are interesting. Like Contentful and Sanity and Prismic and some of those. I think they're like interesting and they have some cool modern, modern ways of doing like content modeling and then getting back the data for it's already in the format that you would need to render React components and things like that. It's kind of built with like a decoupled front end mentality from the ground up. I think that's kind of cool, kind of powerful. So I certainly like what a lot of the CMSs are doing. The one downside with those though is like they're all proprietary. One exception would be Strapi. Strapi is an open source one, like the JavaScript based one that you could check out. S-T-R-A-P-I. I haven't checked out Strapi yet but I like the fact that it's open source and free licenses or whatever is cool. So that'd be one maybe 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 some site for my client or whatever, some business, if I build a site using the CMS and then they decided to quadruple their prices or change their license so that parts of it aren't part 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, it's always free and open source and you don't have to worry about 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 Strapi, 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 and so many marketing teams and people like that really love it for its editing interface and the experience it gives content creators. So it allows you to, if you do headless WordPress, allows you to still give those people their preferred CMS that they love working with, but also have fun as a dev on the front end and build component based apps using like React and Svelte and other tech. So, yeah, I can't speak to super deeply on comparisons, but yeah, I admire some of the stuff other CMSs are doing, but most of my experiences in the WordPress world at this point. Nikhil or Nikhail says, ''Have you used Next.js as 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 headless WordPress and SSG Next.js, just wondering.'' Yeah, you certainly could do this. So yeah, so you're referring to using Next.js as option to generate a fully static site, right, where you have all of the pages of your site just end up being HTML files that you could distribute across a CMS, or a CDN rather, and it's, you know, fully static pre-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 were saying, you're even referring to like running WordPress site locally, you know, so next JS, when it runs a build, you can just access your local WordPress site, you know, to build out all the pages and then deploy those static pages 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 at 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, if it's like a personal project and you, you know, it's for your own site and you're like I have backups on 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.

Watch more workshops on topic

GraphQL Galaxy 2021GraphQL Galaxy 2021
140 min
Build with SvelteKit and GraphQL
Top Content
Featured WorkshopFree
Have you ever thought about building something that doesn't require a lot of boilerplate with a tiny bundle size? In this workshop, Scott Spence will go from hello world to covering routing and using endpoints in SvelteKit. You'll set up a backend GraphQL API then use GraphQL queries with SvelteKit to display the GraphQL API data. You'll build a fast secure project that uses SvelteKit's features, then deploy it as a fully static site. This course is for the Svelte curious who haven't had extensive experience with SvelteKit and want a deeper understanding of how to use it in practical applications.

Table of contents:
- Kick-off and Svelte introduction
- Initialise frontend project
- Tour of the SvelteKit skeleton project
- Configure backend project
- Query Data with GraphQL
- Fetching data to the frontend with GraphQL
- Styling
- Svelte directives
- Routing in SvelteKit
- Endpoints in SvelteKit
- Deploying to Netlify
- Navigation
- Mutations in GraphCMS
- Sending GraphQL Mutations via SvelteKit
- Q&A
React Advanced Conference 2022React Advanced Conference 2022
95 min
End-To-End Type Safety with React, GraphQL & Prisma
Featured WorkshopFree
In this workshop, you will get a first-hand look at what end-to-end type safety is and why it is important. To accomplish this, you’ll be building a GraphQL API using modern, relevant tools which will be consumed by a React client.
Prerequisites: - Node.js installed on your machine (12.2.X / 14.X)- It is recommended (but not required) to use VS Code for the practical tasks- An IDE installed (VSCode recommended)- (Good to have)*A basic understanding of Node.js, React, and TypeScript
GraphQL Galaxy 2022GraphQL Galaxy 2022
112 min
GraphQL for React Developers
Featured Workshop
There are many advantages to using GraphQL as a datasource for frontend development, compared to REST APIs. We developers in example need to write a lot of imperative code to retrieve data to display in our applications and handle state. With GraphQL you cannot only decrease the amount of code needed around data fetching and state-management you'll also get increased flexibility, better performance and most of all an improved developer experience. In this workshop you'll learn how GraphQL can improve your work as a frontend developer and how to handle GraphQL in your frontend React application.
React Day Berlin 2022React Day Berlin 2022
53 min
Next.js 13: Data Fetching Strategies
Top Content
WorkshopFree
- Introduction- Prerequisites for the workshop- Fetching strategies: fundamentals- Fetching strategies – hands-on: fetch API, cache (static VS dynamic), revalidate, suspense (parallel data fetching)- Test your build and serve it on Vercel- Future: Server components VS Client components- Workshop easter egg (unrelated to the topic, calling out accessibility)- Wrapping up
GraphQL Galaxy 2020GraphQL Galaxy 2020
106 min
Relational Database Modeling for GraphQL
Top Content
WorkshopFree
In this workshop we'll dig deeper into data modeling. We'll start with a discussion about various database types and how they map to GraphQL. Once that groundwork is laid out, the focus will shift to specific types of databases and how to build data models that work best for GraphQL within various scenarios.
Table of contentsPart 1 - Hour 1      a. Relational Database Data Modeling      b. Comparing Relational and NoSQL Databases      c. GraphQL with the Database in mindPart 2 - Hour 2      a. Designing Relational Data Models      b. Relationship, Building MultijoinsTables      c. GraphQL & Relational Data Modeling Query Complexities
Prerequisites      a. Data modeling tool. The trainer will be using dbdiagram      b. Postgres, albeit no need to install this locally, as I'll be using a Postgres Dicker image, from Docker Hub for all examples      c. Hasura
GraphQL Galaxy 2021GraphQL Galaxy 2021
48 min
Building GraphQL APIs on top of Ethereum with The Graph
WorkshopFree
The Graph is an indexing protocol for querying networks like Ethereum, IPFS, and other blockchains. Anyone can build and publish open APIs, called subgraphs, making data easily accessible.

In this workshop you’ll learn how to build a subgraph that indexes NFT blockchain data from the Foundation smart contract. We’ll deploy the API, and learn how to perform queries to retrieve data using various types of data access patterns, implementing filters and sorting.

By the end of the workshop, you should understand how to build and deploy performant APIs to The Graph to index data from any smart contract deployed to Ethereum.

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

React Summit 2022React Summit 2022
20 min
Routing in React 18 and Beyond
Top Content
Concurrent React and Server Components are changing the way we think about routing, rendering, and fetching in web applications. Next.js recently shared part of its vision to help developers adopt these new React features and take advantage of the benefits they unlock.In this talk, we’ll explore the past, present and future of routing in front-end applications and discuss how new features in React and Next.js can help us architect more performant and feature-rich applications.
GraphQL Galaxy 2021GraphQL Galaxy 2021
32 min
From GraphQL Zero to GraphQL Hero with RedwoodJS
Top Content
We all love GraphQL, but it can be daunting to get a server up and running and keep your code organized, maintainable, and testable over the long term. No more! Come watch as I go from an empty directory to a fully fledged GraphQL API in minutes flat. Plus, see how easy it is to use and create directives to clean up your code even more. You're gonna love GraphQL even more once you make things Redwood Easy!
Vue.js London Live 2021Vue.js London Live 2021
24 min
Local State and Server Cache: Finding a Balance
Top Content
How many times did you implement the same flow in your application: check, if data is already fetched from the server, if yes - render the data, if not - fetch this data and then render it? I think I've done it more than ten times myself and I've seen the question about this flow more than fifty times. Unfortunately, our go-to state management library, Vuex, doesn't provide any solution for this.For GraphQL-based application, there was an alternative to use Apollo client that provided tools for working with the cache. But what if you use REST? Luckily, now we have a Vue alternative to a react-query library that provides a nice solution for working with server cache. In this talk, I will explain the distinction between local application state and local server cache and do some live coding to show how to work with the latter.
React Summit 2023React Summit 2023
27 min
The New Next.js App Router
Next.js 13.4 recently released the stable version of the "App Router" – a transformative shift for the core of the framework. In this talk, I'll share why we made this change, the key concepts to know, and why I'm excited about the future of React.
React Advanced Conference 2023React Advanced Conference 2023
28 min
A Practical Guide for Migrating to Server Components
Server Components are the hot new thing, but so far much of the discourse around them has been abstract. Let's change that. This talk will focus on the practical side of things, providing a roadmap to navigate the migration journey. Starting from an app using the older Next.js pages router and React Query, we’ll break this journey down into a set of actionable, incremental steps, stopping only when we have something shippable that’s clearly superior to what we began with. We’ll also discuss next steps and strategies for gradually embracing more aspects of this transformative paradigm.