Build and Deploy THE BEST Modern Blog App with React | GraphQL, NextJS, Tailwind CSS

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi there and welcome to a project video where you'll build and deploy a custom blog app with a content management system we'll implement all of the features that you can imagine on an advanced blog platform i'm talking featured and recent posts tags and categories articles with images full markdown content author information previous and next post you name it you'll build it in this video you'll also learn how to implement moderated user comments most importantly you or your clients will be able to create old content that you can see right here from a dedicated content management system this cms blog is the best blog application that you can currently find on youtube and on the entire internet in this one video you'll learn advanced react and next.js best practices we'll use nextgs pre-rendering with static generation you'll also learn how to create a modern user interface using tailwind css completely from scratch then we're moving to the real deal you'll learn graphql and graph cms graphql is a querying language and will cover creating schemas models and finally retrieving data using graphql queries graphcms on the other hand is the best graphql content management system out there and in this video you'll learn how to use it to its fullest potential i initially planned on putting this as a paid course but i later decided to release it completely for free for you guys here on youtube so to support this video leave a like comment and subscribe it shouldn't take more than a few seconds and i really appreciate it keep watching and i'll teach you how you can build this amazing custom cms blog in just one video completely for free in the end we'll also deploy the app so that you can share it with your friends put it on your portfolio and get a job with that said let's dive straight into the code [Music] before we dive into the code please allow me to give you a quick demo of the entire application and the functionalities that you're going to build throughout this video this is the website we'll be building you can create your own completely custom blog from scratch in this case i named it graphcms after the platform we're gonna be using and let's check it out as you can see on the top we have our navigation bar where we can switch to different categories also just below the navigation bar we have a list of featured posts we can browse through them and find the ones that we like below that we have our articles list on the left side and then recent posts and categories on the right side we can scroll through the articles as you can see all of the articles have a title author the date of publishing some short description an image and then the continue reading button as you can see as i scroll we can see the recent posts and categories remain in the view so let's go ahead and read more about the best npm packages did you see how quickly that opened up a new page that's the beauty of next.js and graphcms we have our great post image and just below that we have our article this article has just the text but in here you can embed images videos and whatever you like on the right side we no longer have recent posts but rather related posts and then if we scroll down we can see the author information as well as the previous and next article in our list finally we can leave a comment as you can see right here you can write your own comment include your name and email and then that comment is going to appear here these comments are not that meaningful but of course your real users are going to write more meaningful comments with that said let's try to go to our next article right here and again it loaded up extremely quickly we can now go to a specific category like web development and we're gonna get only the articles for that specific category we can go to continue reading and let's try leaving a comment i'm going to say test in this case the name is going to be jsm and email is going to be jsm gmail.com just for testing purposes finally we're going to implement local storage to save the name and the email in the browser for the next time when we comment let's post a comment and as you can see comment submitted for review that means that the comment is not going to be published immediately it's left for review to the creator of this post and we can allow or disallow that comment from our graph cms we're gonna see that later on that was the short introduction of the project that we'll be building i hope you like it and i'm really excited to teach you how to use all of these technologies now before we go ahead and set up our graph cms schema let's quickly discuss the technologies we'll be using we'll be using graphql graphql is nothing more than a querying language for our apis it's an alternative to the classic rest apis and i know you might be thinking why do we need an alternative and hopefully throughout this video you're going to learn to appreciate all the new things that graphql offers as you can see we can ask for exactly what we need we don't need to get all the data from a specific api endpoint we get only the information that we need that's going to make it lightweight and so much faster than the usual rest api on top of that we'll be using graph cms graph cms is going to allow us to work with graphql so much more easily and it's going to allow us to create enrich unify and deliver all of our content across all the different platforms essentially graphcms supercharges the use of graphql in just a minute we'll already start with creating our first schema inside of graphcms and the final technology on our list is called tailwind css tailwind has been growing incredibly well in popularity in the recent few months it's a utility first css framework you don't use predefined components you just use custom utility classes that allow you to create a completely custom design extremely quickly and easily with that said before we begin i just simply want to point your attention to the project graphql blog github repository the link is going to be down in the description if you encounter an error or get stuck throughout this video definitely make sure to visit this repository compare the code and see if you might have some typos this usually resolves most of the issues again the link is going to be down in the description and while you're here definitely make sure to leave a star i absolutely appreciate that now that you completely understand what we'll be building and which technologies are we going to use to build it with let's go ahead and get started before we create our project folder and start creating the code for our application there's one thing we have to do before and that's create a graph cms schema if we do this at the start that's going to save us so much time later on and make everything so much easier so to visit this page click the link down in the description and click get started that should redirect you to the login form in this case i'm going to log in and that's going to be with google once you log in you should be able to see a site that looks like this in here you can create a new blank project or start from a schema of course when you decide to use graphcms for your next project you can go ahead and choose a blog commerce marketing website or anything else in this case i want to teach you how to do everything from scratch so we're going to choose a blank project we can give it a project name in this case i'm going to name it graph cms now we can choose a project name i'm just going to do jsm underscore blog and project description is going to be a javascript mastery block and finally we can create a project then we can choose the region in this case i'm going to go with europe but you can choose whichever one is closest to you and finally let's create a project you'll then be redirected to the pricing page feel free to look at the different pricing plans but of course in our case we're going to choose the free version so let's go ahead and click select plan and in here you can choose to invite your team members in this case i'm just going to click invite later and there we go we are inside of our dashboard in here you have your quick start guide the first thing we have to do is set up our schema at the bottom right you'll see a video that's going to teach you how to do everything but you're watching this video already so we don't need that right now and the first thing we have to do is create a model the first thing we have to do to create a model is to add a display name in this case that's going to be author because we need to have models for a few different things if you think in terms of our blog application we need to have a model for the author object also for the categories for the comments themselves and finally for the entire post that's going to be four different models in total so the first one is going to be author now that we have our model we have to add our fields to it and it's as simple as clicking different fields we want to add so let's click single line text in here we can choose a display name and the name is going to be just name because our author has to have a name we can use this as a title field and we can go under validations and make this field required let's click create and our model or our schema is instantly going to get this field let's go ahead and add a few more our author also has to have the image so let's find the image right here and that's going to be acid picker the display name is going to be photo and let's say that it's not required so we can simply click create the third thing we're going to have is going to be not a single line text but a multi-line text and this is going to be a description or we can call it a bio again not required so we can simply click create and that's going to be it for our author let's add a new model and the name of our second model is going to be a category our category is also going to have a name so let's add it right here and that's also going to be required and we can also use it as a title field and make it required and it also has to be unique so let's create it there we go just by checking a few check boxes we have our unique and required name then we're gonna have to have a slug a slug is basically a url that we have to go to to visit that specific category so the name is going to be slug and if we go to validation we're gonna make it required and also it's unique by default let's click create great and these are the only two fields that we need for our category now let's add some more for our comment so let's create a new model called comment fields for our comment are going to be pretty simple a single line text called name and we're going to make that required right here we're going to need one more single line text which is going to be the email we need to have an email connected to each comment so again make it required and the third thing that we need is going to be a multi-line text which is going to be called a comment itself so this is what the people are going to type to add it to a specific post and this is going to be required and now we need to create our main model if you think about it the main model is going to be the post itself it needs to have connections to different things like to a specific author it needs to have a date a title a featured image and also the content itself so let's add one and final model called post our post is also going to have a single line text which is going to be called a title our title is going to be used as a title field and it's going to be required our post also needs to have a slug a url friendly identifier and in here we can simply add a display name of slug and validation is going to be required let me make this just a bit bigger for you there we go the third thing on our list is going to be the excerpt so let's go ahead and add multi-line text and we can call it excerpt our excerpt is simply going to be a multi-line text and we just need to make it required finally we have to add the content itself and that's not going to be simply markdown or multi-line text it's going to be rich text text editor with formatting so we can call this our content our content is going to enable embeds and it's going to be set to required finally we need to have just a few more things we're going to have an image so that's going to be an asset picker and that's going to be featured image and again it's going to be required then we're going to add a boolean value so let's see if we can find a boolean there we go each post is going to have a boolean and the name of that boolean is going to be featured post is this post featured or is it not and that's going to be required finally each one of our posts has to be connected to all other models that we have we can make connections or relations in graph cms using the relation fields more specifically a reference let's add our first reference and we can do that by defining a relationship where we're going to set the author to be our first reference in this case we can choose a two-way reference and allow multiple posts per author let's click continue continue and create and there we go our reference has been created let's add one more four categories because each post has to be connected to one or more categories so let's click reference that's going to be allow only one model to be referenced and we want to reference the category that's going to be a two-way reference and we want to allow multiple categories per post and also multiple posts per category let's click continue continue and create there we go that should be it for all the fields on all of our models now let me show you what you can do in graphcms dashboard this was the schema editor but the real magic happens once you go to the content now in here you can create all different users posts or comments as you can see first we need a new author so in this case i'm going to say jsm and we're going to add a new photo i simply uploaded the javascript mastery logo and there we go now let's click save and publish again save and publish and we have a new author with the name jsm we have a photo and let's add a bio jsm helps aspiring developers reach new heights something like that should do and we are ready to save and publish this author now let's create a category as well but you might be wondering why are we doing this right now and the reason is once we start coding this out we'll need some data to fetch so we need to have at least one author one category and one post we can worry about the comments later on so let's quickly add a category and as you can see right now you have only the fields that we specified when we were creating a schema so our category is going to be something like web development and the slug is going to be something like web dev right now we don't have to add any posts so we're just going to save and publish and there we go our web development category has been created if something doesn't go right on the first try just try to create it one more time and again click save and publish now let's add our post that's the main piece of data that we have so let's create a new item and let's copy the post from our current blog so this is going to be react testing then we need to have a slug in this case a slug is react dash testing the excerpt is the thing that we see before we click on that post so just this thing which is currently just some placeholder lorem ipsum content and then finally if we go into it we can copy the rest there we go again in here we don't have any images but you can add anything you want you can make the text bold you can also make it italic add block codes links code images anything that you want then we can add a featured image so let's go ahead and create and add a new featured image that we're going to upload in this case i'm going to simply copy the image address and just go ahead here and paste it you can find any image that you already have on your pc or just find one on the web and there we go we can click upload and in a matter of seconds our asset is saved and published finally we need to choose whether this is a featured post or not and we need to add a new author as you can see we already have the javascript mastery here and finally we need to add a category that this post belongs to in this case that's going to be web development save and publish and that's it now we have one author one category and one post we are ready to code the entire application out then we'll be able to add many more posts authors or categories using this great content management platform finally let's close our browser and open up our desktop and then visual studio code as always we're going to start by creating a new empty folder on our desktop let's name it something like cms underscore blog finally you can open up an empty visual studio code editor or any editor of your choice and then simply drag and drop this folder into it great now we can go to view and then terminal we can start off by initializing a new nextgs application by running mpx create dash next dash app and then dash e and finally with dash tailwind css and then just dot slash to create it in the current repository as soon as you do that you'll say that we first need to install the following packages which is the create next app finally just press y and then enter this is going to initialize a new nexjs application in couple of minutes so i'm going to pause the recording right now and i'll be right back and there we go our new nexus application including tailwind has been initialized before we actually go ahead and run it we can first install the necessary dependencies we can do that by running npm install and we're going to need graph ql we're going to also need graph ql dash request we'll also need html dash react dash parser also the moment library for date and time and we're going to need react dash multi dash carousel and finally sas because for one file we're going to use sas to style different things and that's going to be it we can simply press enter and finally we can run our application by running npm run dev it's no longer just npm start as in react it's just a bit different with next gs but let's go ahead and check it out and if you open up your browser on localhost 3000 you should be able to see our website great in here we have some demo code like the title and a few links to visit the documentation and to learn more about nexjs but we're going to start completely from scratch so we can now close this terminal and we can first explore what we have here the folders that we'll be working with are the pages folder this is let's say the most important folder in nextgs in here we have our index.js which is the starting point of every next.js application then we have the underscore app dot js let's call this the second most important component here and finally we have the api with next.js you can create entire apis without ever needing the backend so that's a great thing about it then we have the public folder which we're going to use for deployment and publishing and we're going to create a few more folders like components contexts and sections but for now let's start by clearing up our index.js i'm going to zoom this out just a bit so we can see more of the content right here and i'm going to delete everything besides the outer div and we can also leave the head right inside of here this is going to be our home component our home route so inside of here we can have our outer div have something like a container then we're going to have the margin x auto and then px which is padding on a horizontal axis equal to 10 and then margin bottom equal to 8. now i know that this might seem like some sort of magic or crazy syntax happening right here what am i even writing are these different class names or what's really happening well as i've mentioned we are using tailwind so if you're ever wondering throughout this video what does a specific class mean i'm going to show you how you can research it for every single class but most of the classes are incredibly intuitive so for example you can notice this is going to be a container div more specifically margin x means x axis or horizontal axis that means that the margin is going to be set to auto the padding on the horizontal axis is going to be set to 10 specific points and we also want to add some margin bottom as we keep writing more utility classes the more they're going to make sense but again if you're not sure about any of them just feel free to type it out go to tailwind css docs and in this search just type it out mb8 margin bottom 8 and that simply means margin bottom to rem you can see it right here it's even drawn out let's see what does the container property mean there we go container the use of container class sets the max width of an element to match the min width of the current breakpoint so basically it gives it a specific width now let's continue with the creation of our interface we can leave this head in and i'm going to change this to something like cms block great below that we're going to have one more div and this div is going to have a class name equal to grid grid dash columns or calls dash 1 and then on large devices it's going to have grid dash calls dash 12 and gaap is going to be set to 12. now inside of here we'll be able to loop through all of our posts so for now before we actually fetch data using graphql let's create a demo list of our posts we can only give them a title so const posts that's going to be an array and let's say that each post is an object that has a title before we used react testing and let's also give it an excerpt that's going to be something like learn react testing and i'm going to add a comma and just duplicate this one more time this is going to be react with tailwind and this is going to be learn react with tailwind these are just some demo titles and descriptions so inside of here we can actually map over them by saying posts dot map we're going to get our post and the index here and we want to instantly return something later on we're going to return a real post component here but for now what we can simply do is render out a div and inside of there we can render post dot title and then just below that post dot excerpt great again later on this is going to be a real post component let's save it and take a look in the browser there we go as you can see we already have our div and this is not quite centered but let me show you what i mean this container already has some width margin and padding but we can do something like bg gray and there we go as you can see we have our two posts they are inside of the container but it's hard to see right now so let's add in some background we can do that by saying bg gray and then numbers from 100 to 900 let's do something like light gray with 300 and there we go now you can see what i meant when i said that a container class gives it a specific width okay i'm going to remove that and now we can continue adding something below our posts so that's going to be just below our grid we can add one new div and that div is going to have a class name equal to and we want to do something only on large devices so we can do that by saying lg column dash span dash 4 and column dash span dash 1 usually when we're not on large devices of course to be able to use columns we have to be inside of the grid so i'm going to put this div inside of the grid container and we have to wrap our posts with one more div let's not forget that so right here i'm going to write this div and put our posts inside of it there we go so now we have our div for our posts and also one for two new categories and one for two new components that's going to be the post widgets and categories right now i'm going to give this one a class name as well that's going to be lg call dash span dash 8 and then usually call dash span dash 1 great now inside of this div we're going to have one more div and this div is going to have a class name on large devices make it sticky usually make it relative and top dash 8. great let me show you what this div actually represents this is our finished site and the thing we're building right now is going to be this main view the home we are already looping through the articles although they don't look that good now but now we're building the right side the recent posts and categories so right here we can add two new components that we are yet to create so to create these components we can go ahead and open up our file tree and right next to pages in the root of our folder we can create a new folder called components and for starters we're going to need three different components the first component is going to be the actual postcard dot jsx the second component is going to be our categories component dot jsx and finally the third one is going to be our post widget dot jsx and each one of these components is going to be a basic react arrow function component i can get to that simply by typing rafce if you have never used that rafce just go to extensions and type snippets there you should be able to find es7 react redux graphql react native snippets so simply install that extension and then you'll be able to do this so inside of our post widget we can simply type post widget we can now copy that and paste it over to categories but just make sure to change post widget to categories everywhere and finally let's repeat the same thing for the postcard our postcard can even accept the post itself so right here as props we're going to accept a post and do the same thing with it before that's simply going to be post dot title and below post dot excerpt great now that we have all of these components we're going to create one new index.js file inside of the components this is going to allow us to more easily export and import those components by saying export default as and then we can add the name of the component in this case postcard from dot slash postcard we can duplicate this two more times the second time for the categories and the third time for our post widget great now we can go inside of our pages index.js and inside of here we can import those components we can import them by simply saying import in curly braces that's going to be postcard categories and also the post widget these are coming from dot slash components great finally we can use them right here instead of rendering out this div we're going to actually render out a post card component and we're going to pass the post as post to it we can even put this in one line there we go and we're also going to give a key to each item and that's going to be post that title the title should be unique then inside of this div we're going to render out the second two components that's going to be the post widget right here that's simply going to be a self closing component and then below that we're going to render one more and that's going to be the categories great and with that we are basically done for the jsx part of our home i know it might seem simple but the rest of the work is going to happen inside of the actual postcard and the other components let's save it and take a look there we go looks extremely stupid at the moment we only have two different articles on the left side and also the post widget and categories on the right side now let's add our global styles our global styles are going to be the only styles that won't be done using tailwind css so let's create a new folder and the name of the folder is going to be just that styles inside of there we can simply create a new file called globals.scss and what you can do right now is pause the video head to the description and then simply copy and paste it from the file mentioned in there there's going to be a github gist where you'll be able to simply copy and paste these styles you're going to notice that these are just some basic styles for the html and the body some text shadows and then something more for featured posts and the carousel they're gonna have later on but nothing special so just to save your time simply make sure to copy and paste this here you're gonna also notice that there's gonna be an image called bg.jpg or at least you have to save it as that so just download that image and then put it inside of the public folder call it bg.jpg and we should have it right here once you've done that we can go to our pages and then our underscore app.js inside of here we're going to simply import in a string dot slash styles forward slash globals.s this is going to import all of our styles and then we can continue creating more of our components and then finally fetching the data using graphql and graphcms now if we've done everything correctly we should be able to see our background and there we go as you can see the font changed and we can also now see our background of course there weren't many styles in that style sheet so this changed just the background and almost nothing more so now we're going to implement all of these components ourselves the navbar and then featured posts and finally everything else let's go ahead and start with the navigation bar we can start by creating a new component called header dot jsx of course just so we don't forget we can immediately export it from our index.js and that's going to be header now inside of here we can again use the rafce and we're going to import react as well as the use context from react inside of here we're gonna also import a link but no longer from react router dom it's going to be just from next forward slash link and we are ready to start creating our header more specifically we can start by giving this div a class name and that's going to be a container div it's going to have the margin x auto px which is padding on horizontal axis equal to 10 and then margin bottom equal to eight inside of that div we're going to have one more div this div is going to have a class name set to border dash b with dash full so just w-4 it's going to be an inline block and it's going to have the border blue of 400 and finally padding on y-axis which is vertical axis set to 8. now inside of there we can create one more div this div is going to have a class name set to md meaning only on medium devices we want to have a float left and usually we want to have it as a block element inside of that div we're going to have a link component right here that link is going to have an ahref equal just to forward slash and inside of there we can create a span element this pan is going to have a class name equal to cursor dash pointer also font dash bold text dash for excel to make it extremely big and then text dash white and finally inside of there you can enter the name of your blog in this case i'm simply going to say graph cms great and then finally below that on the right side so that's going to be below this div that's below the link we're going to have one more div and this div is going to show the categories so we can say class name is set to hidden and then only on medium devices we actually want to show it and make it float left and usually we want to have it as contents now this might be a bit weird one and not so intuitive so let's copy it and let's go to tail and css if we search for our contents and click it you'll see that we can use contents to create a so-called phantom container whose children act like direct children of their parent so yeah this is a specific one but that's going to help us to create a navigation bar such as this one as you can see if i go to inspect and see how this looks like on mobile devices we won't be able to see the categories on small devices but if we increase that a bit to tablet size we will be able to see them so right here we're going to say md contents now inside of there we want to map over the categories of course we haven't yet fetched the real categories so now let's just create a demo array that's going to be const categories and each category is going to be an object that's going to have a name and our first name can be something like react and then it also needs a slug slug is going to be just react now the second category so we can create a second object is going to be name something like web development and then we can add a slug which is going to be something like web dash dev and finally now we can loop through those categories by using a dynamic block of code categories dot map in here we get one specific category and we're simply going to map over them by displaying a link component for each category our link is going to have a key equal to category dot slug to make it unique and it's also going to have an href property pointing to forward slash category and then category dot slug this is going to be a template string so make sure to close it as so now inside of there we're going to open it up and create a span element our span is going to have a class name equal to md float dash right and also margin top mt2 we want to align it to the middle make it text white and also give it margin left 4 make the font let's do semi semi-bold and then let's make the cursor equal to pointer and inside of that span we can render that's going to be category dot name great we've just created our header but now we have to make use of it so to actually use this header we're going to wrap it in a specific layout and we're going to use a special layout component because we always want to show the header so whenever we want to show something we're always going to have that header inside of the layout and then the actual content let me show you what i mean it's going to make more sense once we actually write it out so that's going to be layout.jsx that layout component is going to be as simple as it can be react arrow function component and in here we're simply going to import and that's going to be header from dot slash now the only thing we want to do is render out a react fragment inside of here we're going to render out the actual header component and then below that we're going to render the children so with every react component you always get access to a special prop called children basically whenever we call a layout component like this and whatever we put into it that something is going to be displayed right here inside of the children and we're going to have the header just above that so now we can actually export that layout component here by simply duplicating this line and saying layout right here and finally we can use that layout inside of our underscore app.js first we have to import it so just at the top i'm going to import a few things that's going to be import react also use effect and use state we're going to use those later on that's coming from react and then finally we also want to import that layout component by saying import layout from that's going to be dot slash components great and now finally instead of just rendering this component like this we're going to render something else i'm going to expand this into multiple rows like this and that component is going to be wrapped with a layout so we're always going to show something that component but that component is going to have the header above it because if you remember what we said we're sending some children to our layout component and that's going to be rendered right here below the header so now if we save this and check it out we should be able to see our header let's go to our localhost 3000 and there we go graphcms react web development but these are showing on the left side alongside graph cms we want to show them on the right side so let's see what happened inside of our header component the only issue was this here i misspelled right as soon as we fixed that the issue should be fixed and there we go our header is now done we have this nice little border bottom not sure if you can see it we have our logo on the left side and we have all of our categories on the right side of course these are right now static but soon enough we're going to pull real data using graphql now is the time that we render out our posts before we actually code out the design and the jsx for our posts now might be the best time to fetch real data coming from graph cms to start fetching our data we're going to create a new folder called services again in the root of our folder inside of there we can create a new file called index.js inside of here we're going to import two things from graphql request that's going to be a request and gql and these things are coming from graphql and that's going to be request now if you haven't used graphql before this is most likely the first time you're seeing this library so let's go ahead and check it out on mpm i simply googled graphql request npm on google and this is what we got this is an extremely popular package with 1.6 million weekly downloads and basically it's a minimal graphql client supporting node and browsers that doesn't really say a lot but essentially it allows us to make graphql queries we import these two things we create a query and say what do we want to fetch and from where so let's create our first graphql request we're going to create a new function and immediately export it so that's going to be export const get posts that's going to be an arrow function more specifically an asynchro function and then inside of there we can say const query is equal to gql and then a template string and then in next row we can actually write our query right inside of here and the query usually starts like this query and then you can add a name something like my query and then in here we can start fetching our posts now thankfully we won't have to do all of this manually because these queries can get long so we are back on our graph cms dashboard and we're going to go to api playground there we go inside of here we can choose what do we want to fetch so let's go to explorer and then from here we'll be able to choose what do we want to query we're going to go to posts connection and inside of here we want to choose edges from inside of the edges we're going to choose node and you can see that our node contains all the information that we want to get we want to get the author and from author we want to get the bio as well as the name we can get the id and we can also get the photo url where is it there we go you can see this is creating our query as we speak now if you keep scrolling down we also want to get the created ad property right here so we're going to add that to the query we also want to get the slug and we want to get the title we also need the excerpt there we go our excerpt is right here and finally we want to get the featured image more specifically featured image dot url and finally we also need the categories so let's try to find the categories i can use our control f these are not the categories we're looking for we're looking for the categories inside of a specific post and here they are for each category we're going to need a name as well as the slug great as you can see this just created the entire query for us of course you could have written this by hand but this just makes it so much easier we can click this play button right here and our data has been automatically generated on the right side in real time as you can see we're getting the data with posts connection and then inside of those edges we have our first post containing all of the data that we specified right inside of the node right here that's going to be the author including all of the author properties created that slug title excerpt featured image categories including the name and the slug so now we can copy this and go back to our code finally we can paste it straight inside of here and this is how you fetch data using graphql and graph cms great so now that we have our query we actually have to make a request to get it and we can make a request right here below by saying const result is equal to a weight request and then in here we need to specify the graph ql api as well as the query now the question is where are we getting this graphql api from well we can create it right here at the top by saying const graphql api is equal to process dot env dot next underscore public underscore graph cms underscore endpoint now we can copy that and we can create a new dot env variable we want to keep this endpoint safe and secure so let's create a new file called dot env of course this shouldn't be using capital letters so just make it use lowercase letters and inside of here we can paste the name of our variable and now we need to find that endpoint inside of our graphcms and we can get to our endpoint by going to settings right here and then finally environments simply copy it right here go back to your code and paste it straight into here now to actually update this environment variable we have to go to view terminal press ctrl c to stop it from running and then run npm run dev one more time and once we actually fetch the results what we can do is simply return result dot posts connection dot edges these are going to be our posts of course this here is going to be result let's save this file and let's use it inside of our pages and then index inside of here we're going to import that's going to be get posts and this is coming from dot slash and that's going to be services finally we don't need to create our demo posts anymore we can delete that right now and we can use a special nexus way to fetch data inside of our components to do that we don't have to actually write it inside of our component which is something entirely new we create a new async function called get static props at the bottom of this component export async function get static props and we call that as a normal function and in here we can say const posts is equal to await get posts as we would usually do inside of the use effect of course we can make our posts equal to that or we can simply wrap that into parentheses and if we don't get that data we can simply say or empty array and finally you have to return it like this by saying return an object inside of the object we have props and then inside of those props we can return the posts this is how you fetch data using getstatic props in next.js now that we're fetching the posts the question is how can we use them inside of our home component and the answer is incredibly simply we can use them as props so our posts are coming as props to our component just to the fact that we're using this special getstatic props function so now we're no longer looping over our demo array with two different posts we are actually looping through all of our posts that we have in our graph cms right now we have one post there but of course we can create much more later on but of course we have to make sure that we're actually seeing one if we've done everything correctly so if we go back to localhost 3000 and reload the page right now we are getting an error saying not allowed and then in here 403 with path posts connection edges this error is not giving us a lot of information so let's open up the inspect tab and we can again see the error on cod we don't get a lot of information let's see if we mess something up and again i always like to include those errors in the video because these things can happen to everybody and nobody is perfect so you just have to get the error try to debug it and then continue with the work the error is most likely going to be inside of the services so let's see if we mess something up we are importing request and gql from graphql request we're creating our new graphql api by using the endpoint from environment variables we are saying export const get posts which is an async function including the query which is equal to gql and then there's a template string we pass in our query and we want to get the posts connection inside of there we want to get the edges but i'm going to indent this properly inside of that node we want to get the author so let's simply indent all of these properly inside of the author we're getting all of these so that's fine created that featured image categories this seems all right to me and looks like everything is properly closed we have the result here with the await request graphql api which is this correct api and a query right here return result posts connection dot edges this seems completely fine to me since this file is looking good let's try to go to graph cms and see if we have to grant some permissions we can go to settings again and let's go to api access if we scroll down maybe let's try clicking yes initialize defaults and hopefully now we should have access to read all the posts we've created i reloaded the page and there we go we can see nothing right now but no more errors which means that we should be good now let's go to our post component and let's actually render out all of the great details we have in our first demo post to do that we can go to our posts as you can see in here we're fetching them we're getting them straight right here to the props and then we are looping over them and passing one by one post into the postcard so this is where we actually have to create the jsx we can start by importing the moment library which we're gonna use to format the date and then finally we can also import a link from next forward slash link great we're getting the post and now instead of rendering these two things let's actually render out a new div and this div is going to have a class name equal to bg-white shadow dash lg rounded dash lg padding is going to be set to 0 and then on large devices we're going to increase the padding to 8 and we're going to set the padding bottom to be equal to 12 and margin bottom to be equal to 8. now inside of there we're going to have one more div this div is going to have a class name set to relative or flow is going to be set to hidden it's going to have a shadow dash md medium and finally padding bottom is going to be set to 80 and margin bottom is going to be set to 6. this is for our image so right inside of here we can render out the image by using the image self closing tag setting the source to be equal to post dot featured image dot url and now might be a good time to see what other data are we getting from the post so we can say console.log and we can console log the post before we go ahead and check it out let's just finish up our image we can add the alternative tag which is going to be post dot title and then finally below that we can add a class name to this image it can be object dash top absolute h dash 80 which is height then we're going to have the width dash full object dash cover shadow dash lg rounded dash t dash lg and then finally on large devices rounded lg now if you don't know some of these properties definitely make sure to check out tailwind docs now let's save it and take a look in the browser as you can see we immediately get cannot read properties of undefined reading url which means that we're still not getting the proper data from graph cms so we can comment out this image for now and simply save it then reload the page one more time as you can see we do get a post right here and as you can see in the console log we're getting an object that is containing a node node is basically our post it contains all the data but it's not just inside of this object it's inside of the node so to get the actual data we have to say post dot node let's see if we can simplify that somehow inside of the index we can write here simply send post dot node instead of simply sending the entire post because the node itself is actually the post now let's see if we can log this are we going to get the right data i'm going to reload the page and there we go now we have the author we have the photo created that categories everything we need with that we should be able to bring this back let's save it and there we go this is our post image now we're ready to start creating all the other things that this post has and it might be a good idea to put the browser side by side by the editor so that we can see all the changes live there we go if i space out the browser and the code editor like this we can see the changes live on the right side now below this image div we want to implement an h1 which is going to be the heading of our post we can give it a few class names so class name is equal to that's going to be transition duration 700 this is a new interesting way to learn that we can also do animations using tailwind we're going to give it a property of text center as well as the margin bottom set to 8 cursor is going to be set to pointer so cursor pointer and then this is going to be a really long line so we can split it into multiple lines hopefully and we can continue by saying hover let's do something like text dash pink dash 600 then we're going to make the text larger by saying text dash 3xl and font semi-bold finally inside of that h1 we need to render a link so we can write here save link this link is going to have an href which is going to be equal to a template string like this that's going to be for slash post forward slash and then post dot slug and our link can simply render out the post dot title now let's save this and as you can see we have react testing and if we hover over it it slowly animates to this pinkish color great of course we can put this in in one line like this and there we go this is our h1 so if you want to add a transition looks like i have a typo here this should have been transition but there we go duration is set to 700 but if i set it to 100 and do it like this see now it happens almost instantaneously so now below this h1 let's add a div our div is going to have a class name set to block on lg it's going to be flex it's going to be text center it's going to have the items dash center as well as the justify dash center it's going to have the margin bottom set to 8 so that's going to be mb8 and then width dash full or just w dash full inside of that div we're going to have one more div this div is going to have a class name and i just noticed that in here that should have been block right here we're gonna have the flex the items dash center justify dash center mb-4 which is margin bottom 4 on large devices margin bottom 0 and then we're going to have the w full to take the full width on large devices we're going to set the width to auto by using w auto margin right is going to be 8 and that's it now inside of there we want to render out the author image so we can create a new image tag like this inside of there let's add the alt tag which is going to be post dot author dot name we can set the height to be equal to something like 30 pixels we can also do the same thing for the width we can set the class name to be something like align dash middle and also rounded dash full finally the most important image property is the source that's going to be post dot author dot photo dot url let's save it and there we go javascript mastery logo appeared right here right next to it we just want to create a p tag and inside of that p tag we're going to simply say post dot author dot name we can save that there we go simply jsm in this case let's add a few more properties so class name and i'm going to press ctrl s with every property that i type that way you'll be able to exactly see what each tailwind class does so that's going to be in line that specifically didn't do anything right now we're going to say align middle also text dash gray dash 700 that's going to just make the text a bit more gray it's not noticeable right now though we're going to give it a margin left to text dash lg there we go that made it just a bit bigger finally below this div we want to have one more div this is going to be for our date so right here we can say class name is equal to font dash medium as well as the text dash gray-700 now inside of there we're going to render the svg component that svg is going to be down in the description between all of the gists as well on github of course so you can simply copy and paste this svg and svg is like an icon you can see it right here and below that svg i'm going to add a span and then inside of that span we're going to use the moment library to simply say post dot created add and we can say dot format and put a string mmm day day and that's going to be yyyy this is the date format that we can use if we use 2ms that's going to make it a number but if you use 3 that's going to put it in a shortened month object this is the date and finally this is the year and the library we just used is called moment finally below this div and below one more div right here we're going to render a p tag and this p tag is simply going to render the post dot excerpt there we go you can see it doesn't look that good right now but if we add a class name that's going to be text dash center there we go that centered it that's going to be text lg also text dash gray dash 700 font-normal px-4 which is the horizontal padding 4 on large devices padding 20 and then finally margin bottom 8 so that we can divide it from the rest of the content below that div we're going to have one final thing which is going to be a div this div is going to have a class name equal to text dash center inside of there we're going to have a link tag and that link is going to have an href equal to forward slash post forward slash post dot slug inside of there we want to have a span element so right here let's create a span that's simply going to say continue reading now inside of here we can add a class name and let's first see how does it look like like this there we go continue reading but now we can add utility classes first let's say transition duration is going to be something like 500. then we're going to set that to transform on hover we want to do minus translate minus dash y dash one let's save that and see if we can see the changes immediately nope nothing yet let's keep adding more styles that's going to be inline dash block and let's give it a background bg dash pink dash 600 there we go that's already starting to look more like a button and now you can see that little jump that the button does once you hover over it we can continue with more classes like text dash lg font dash medium rounded dash full it's starting to look a bit more like a button right now let's do text dash white and finally padding on horizontal axis equal to 8 padding on vertical axis equal to 3 and finally cursor dash pointer and with that we just created a tailwind button there were a lot of utility classes used we also added some little animation as you can see but there you go this is a really custom button that doesn't look like a material ui button or a bootstrap button this is the button that you've created right now and there we go this is our postcard right now we have only one post but right now using graph cms we can easily add so many more posts and they're all going to be listed right here as you can see this one so just for variety purposes let's add one more post inside of graph cms to do that we can go to content post and let's simply try to duplicate this one so we can go into it and then finally right here duplicate we can call this one something like next.js is the future of web this is going to be next js we can leave this the same as well as the content but we can change the image so i'm going to say replace featured image and we're going to upload a new one from the link i'm again going to use a url from here from the old blog and simply paste it as a link right here of course you can use any image that you want let's upload it there we go it's a draft currently and the post is going to be by jsm and let's click save and publish we also want to publish the image that's correct and if we save that our entry has been published and immediately let's reload the page there we go our second blog appeared right here and it's looking great the only thing that i can see is that the image is a bit skewed if you see on our original blog that doesn't seem to be the case so let's go ahead and fix that right away that's going to be inside of our postcard object top absolute h80 there we go object cover and also rounded there we go i made some typos so sorry about that but hopefully we're gonna be good right now i saved it and if we go back to our cms blog this is already looking so much better we have our categories and our navigation bar on the top and all of our articles being fetched directly from graph cms using graphql querying language great now our next steps are going to be to implement the post widget and categories and if we look at the live site that looks something like this all of the recent posts are going to be listed here and then we're going to show all the categories that we'll be able to browse through so let's go ahead and do that right now if you think about it we've already created components for our categories and our post widget so let's start right here inside of our post widget we're going to import a few things that's going to be import moment from moment and we're also going to import link from that's going to be next forward slash link great right here to be able to render something we first have to fetch the right data if we check the already done version we have to fetch all of the most recent posts so now we already have a pretty good idea of how we can do that we can go to our services and then in here we're going to create a one more function with one more graphql query that's going to get the recent posts for us so right here below this function inside the index of services we can create a new export const get recent posts and this is again going to be an async function like this and inside of that function we're again going to have a query so we can say query is equal to gql a template string again we need to close that template string and then inside of there we're going to say query get post details right here and now we can learn one more thing from graphql right here we can get the newest posts that were created by doing posts and right here we can say order by and that's going to be created at and then underscore ascending so these are going to be the newest posts we're going to space it out properly and right below that we're going to simply say last three like this of course we could have created this query inside of graph cms editor as well but this time i wanted to show you how we can do it manually so what do we want to get from these posts well the title also the featured more specifically the url from that image we also want to get the created add property and then finally the slug and now the situation is going to be basically the same we can even copy these two lines once we have the query we need to get the data by doing request graphql api query and then in this case that's simply going to be result dot posts great so now inside of the post widget we can now actually call the get recent posts function we can do that by importing the use state as well as the use effect from react and then we can create a new use state by starting to type use state and clicking here we can name it something like related posts you can click tab and then we can set it to an empty array at the start now we can get the use effect right here again auto fill it inside of here we want to know if we're seeing the post widget right here on the home page or in a specific article page because on our home page we can see the recent posts but if we go to the article page we can see the related posts so there's going to be a difference keeping that in mind to know the difference we can check the slug and the slug is going to be something that we're going to pass into the post widget component so the two things that we're going to pass later on are going to be the categories as well as the slug so we can simply say if there is a slug and slug being simply the path of the specific article for example if i click here this entire thing here is a slug so if there is a slug in that case we want to call some kind of a function called get similar posts and we can get a similar post by knowing the category that this post is in and then passing the slug and we can simply do a dot then and then we can get the actual result with that result we simply want to set related posts to be equal to result so we want to get similar or related posts if we have a slug meaning if we're viewing a specific article at the moment and if we're not looking at a specific article in that case we want to do a similar thing so i'm going to copy this but it's not going to be get similar posts is going to be get recent post and in that case we don't have to pass any parameters because we're not at a specific article right now great so the question is where are these functions coming from and we've already created one if you think about it we can go to import get recent posts we just created that at dot dot slash services it is right inside of here that was this query but while we're here we can also create the get similar posts which is going to be just a bit different so let's create a new query that's going to be const or rather export const get similar posts which is going to be an async function like this there we go inside of there we do the same thing const query is equal to gql a template string like this we need to close it and there we're going to have the query get post details like this that get post details in graphql language we can do something that looks like this we can pass in the dollar sign slug and we need to specify the type and that's going to be a string and then we can pass another parameter which is going to be dollar sign categories and that's going to be an array of strings like this and once we specified the params for passing in we can do the same querying we've done before it's going to look just a bit different so we're trying to get the posts where we can say where and in an object slug is not so slug not is slug why don't we want to get the current slug because that's the post we're looking at right now we want to show all of the related posts but not that one and then we can use the end that's going to be another object categories underscore sum is equal to an object where we say slug underscore in dollar sign categories so basically what we're saying is don't display the current article but display other articles that include some of the categories that we want to get and then we want to get just the last three articles so we can specify that last three this is how you write more complicated graphql queries of course it would be incredibly interesting to see how we can write these queries inside of graph cms and we're going to write so many more queries later on in the video using graph cms playground so what do we want to get from these articles well it's going to be the same thing as we get here so we're going to copy this object title featured image created ad and a slug we can paste it right here and then the situation is going to be the same that's going to be simply cost result await request and then return result.posts that situation is mostly going to be the same now let's save it and inside of our post widget we can right here import get similar posts now we have almost everything that we need this use effect is going to change only when the slug changes like this and let's say that for now we simply want to console.log the related posts there we go in here i have a typo this here should have been categories that we're passing into it so now if you think about it we should be accepting these two props to this post-widget component but we're not accepting them right now and if you can see that yep definitely nothing coming in but that's completely fine because we're gonna call this component from two different places the first one is going to be the home that's gonna happen right inside of here but the second time that we display it it's going to be inside of a specific article then we need to pass some props right now we don't we simply want to get the most recent articles and that's it so if you don't pass the props you're accepting they're simply going to be undefined and in this case that's completely all right so now finally let's create the jsx for our post widget that's going to be a div that's going to have a class name equal to bg dash white if i do that you can immediately see that it changed on the right side let's give it a shadow dash lg there we go let's also do rounded dash lg there we go changes look immediately let's do padding dash eight there we go and let's do margin bottom so mb dash eight just to push these categories a bit below hopefully tailwind is starting to make so much more sense you can see that there aren't many utility classes we're mainly repeating the ones we've used before now inside of there i'm going to show an h3 that h3 is going to check if there is a slug if there is a slug that means that we want to see related posts of a specific article else we simply want to see recent posts like this as you can see right now we just want to get the recent because there is no slug we're not looking at a specific article right now we are on the home page so let's add some class names that's going to be text dash xl also margin bottom 8 let's do font-semi-bold something like border dash b is going to do the trick that's going to give it a border bottom and padding bottom 4. there we go the border is barely visible but it's there now we want to map over all of our posts so we can do that right here below if we go over the related posts like this dot map so in here we get a specific post and we simply want to show something for each post and that something is going to be a div our div is going to have a key equal to post dot title and we want to have a class name our class name is going to be flex items dash center w dash full for full width and margin bottom mb4 great now let's render out the div that's going to contain our image that div is going to have a class name w 16 flex dash none inside of there we can show a basic image tag like this and it's going to have the alternative text equal to post.title let's also do something like height is going to be set to 60 pixels and also the width is going to be set to 60 pixels of course we need the class name that's going to be align dash middle and rounded dash full and finally the source is the most important thing post dot featured image dot url if we save that you can see the image of our two posts that we have right now below that div we want to display one more div this div is going to have a class name equal to flex dash grow ml-4 and inside of there we simply want to leave a p tag that's going to render out the moment library and that's going to be post dot created at and then we simply want to say dot format that's going to be mmm space dd comma and then yyyy there we go with that we're gonna get the date of course let's give it some class names something like class name is equal to text dash gray dash 500 font-xs there we go and finally we also want to add a link to that article so we can say link href is going to be equal to a template string to for slash post forward slash post dot slug we can also give it a class name equal to text dash md and looks like we have an error right now that's saying multiple children were passed to link with href of post-react testing but only one child is supported so let's try to add a specific key to this and a key is going to be simply the post dot title let's see if this fixes it okay even though we entered the key we still have the issue so let's think about it we're doing forward slash post forward slash post dot slug and we were doing the similar thing somewhere else but not in this file now inside of there we want to render something of course and that something is going to be post dot title if we save that there we go that worked that was just a small error we've had but right now we can click on these articles and they should point to a specific slug of course right now we're getting a 404 because we haven't yet created the article details page but as you can see we have our recent posts and again as you keep adding them they're going to appear here the second thing we have to do is to implement the categories that's the second card that looks extremely similar to our recent posts if we go inside of our index.js you'll be able to notice that we're calling the post widget here as well as the categories so let's go to the categories component and as you can see right now that's a blank react component so let's start by importing a few things we're going to import a use state as well as the use effect coming from react and then we're gonna also need a link so that's going to be import link from next link now as we had to fetch recent posts for the card above we have to fetch categories for the categories card so let's go to our services index.js and right inside of here we can create the get categories call again the procedure is going to be the same that's going to be the export cons get categories that's going to be an async function like this and inside of there we're again going to have a query which is equal to gql we have a template string and then inside of there we can specify the query something like get categories and just call that as an object and let's specify categories and what do we want to pull we simply want to get the name as well as the slug so right here that's going to be name and slug this is going to immediately give us all the categories that we need and finally we can copy this that's going to be cost result is equal to a weight request and then in this case that's going to be result dot categories great so now we can go back to categories and right inside of here we can import the function we just created by saying import get categories from services and then we can create a new state field by saying use state clicking here and that's going to be categories press tab one more time and set the initial value to be an empty array then we can create a use effect every use effect has a callback function and it also has a dependency array in this case we want to leave the dependency array to be empty meaning that we're only going to call this at the start to fill in our categories so let's call our get categories we can use the dot then here we are gonna get our new categories from the api call and then we can simply do set categories is equal to new categories and this is how we're fetching data from graphql or rather graph cms through graphql querying language right now we have an error so let's check our index services right here and i've just noticed the error in here we have a column but in graphql we don't need columns at all so this is going to fix our query just keep that in mind we're not working with json we're not working with javascript objects we're working with graphql queries great so now we're ready to get these categories and then we can simply render them our outer div is going to be the same as with our posts so let's go to our post widget and we can copy the first four lines which is going to be the div and the h3 let's go back to categories and just paste it here we're gonna have bg white shadow lg rounded lg b8 margin bottom eight and let's also give it padding bottom 12. of course we don't have access to this slug here and that's not what we want to say in this case we're going to have a constant h3 that's going to say categories and there we go we have our category section the last thing we have to do is actually map over the categories that's going to be categories that map we're going to get a specific category and then we want to show a link for each one so right here let's display a link that link is going to have a key equal to category dot slug to make it unique and it's going to have an ahref equal to a template string forward slash category forward slash category dot slug and inside of there we can create a span element this pan is going to have a class name equal to let's do cursor dash pointer let's do block and finally let's do padding bottom three and margin bottom three if we save that we can see that we need to render something in there and that something is going to be category dot name and there we go right now we just have one category of web development let's try to add a few more so that we can see them here for that can go to our graph cms to our content and finally category we can create one more item let's do something like react and the slide is going to be react and save and publish there we go as soon as we go back to our blog reload the page we can see react right here now that we can see our categories here we also need to fix them on the navigation bar you might think that this is fine right now because we have web development react and web development react right here but if we go to our header component right here you can notice that in this case we're simply hard coding them so we need to fetch our real categories in the header file as well and to do that we can copy and paste most of the logic i'm going to copy the use effect and the use state as well as the services and by the way i'm holding the alt key while selecting new lines that way everything is going to be imported or you can just copy and paste line by line now we can go into our header and i'm going to paste everything right here so from react we're simply going to use use state and use context then we don't need this line we don't need these categories and we're simply going to pull these lines inside of the actual component and fix the indentation there we go with that we now have our real categories right inside of this file and we can save them and there we go that means that our entire front page is now done we can list the articles we can see who made them and when we can also see the images recent posts right here as well as the categories on the right side and on the navigation bar now let's actually create a new page for our article details to create our article or post details we can create one more component but it's not going to be just the basic component it's going to be a next.js page and we can create it right here under pages and we're going to create a new folder called post inside of the post we're going to create a new file with a special name opening square bracket slug closing square bracket dot js next gs has something known as file based routing meaning you don't have to do all the routing as you usually do inside of the app.js using react router dom with next.js you just put your files as you want them to be structured later on in the actual url for example our index.js is going to show when you go to localhost 3000 and then if you create a folder called post that's going to be forward slash post and finally if you create a slug specifically with square brackets that means that this is going to be dynamic so if you go to forward slash 1 to 3 it's going to think about 1 to 3 as that slug and it's going to render this file so let me show you what i mean i'm going to create the rafce a react functional component and the name is going to be something like post details now inside of the pose details component we're going to import that's going to be get posts as well as the get post details from that slash dot slash services these are the end points we are yet to create and then we're also going to import a few components that we haven't yet created so let's just start by importing them first that's going to be import and a special component called post detail that's going to contain the content of our post then we're going to have the categories finally a post widget which we already have then we're going to have the author comments and finally comments form and this is coming from that's going to be dot slash one more time dot slash components great so now we have everything we want to use but of course we are yet to create most of these components so we can start right now in this pose details component i'm simply going to write post details here and right now if we go on a specific article like this post one two three you can see that we indeed do get post details same thing would happen if we clicked on a specific article there we go post react testing later on we'll be able to retrieve the react testing value to get the actual post details but for now let's create the structure of our pose details component we're going to have a div that's going to have a class name equal to container margin x auto padding x10 and margin bottom is going to be eight then we're going to have one more div inside of there so that's going to be class name is equal to grid grid dash calls dash 1 and then on large devices grid dash calls dash 12 and then the gap is going to be 12. inside of that we're going to have one final div and this div is going to have a class name equal to call dash span dash 1 and on large devices that's going to be call dash span 8 so that means that this div is going to take 8 out of 12 spaces we can also create one new one below by duplicating this one and on small devices it's also going to take one space but on large devices it's going to take four now inside of this first div we want to render our components first we're going to render our post detail component like a self closing tag then we're going to render our author component below that we want to render the comments form and finally below the form that's going to be the comments themselves great and for the second div we're going to have one more div inside of it like this it's going to have a class name equal to relative and on large devices it's going to be sticky and top dash 8. inside of there we're going to have our post widget which we already created and we're also gonna have the categories which we also created great so now is the time that we just create a boilerplate code for all of these components and properly export them so let's start with post details i'm going to create a post keep in mind it's going to be detail pose detail.jsx that's going to be on rafce and inside of there we can simply render post detail we can even make it an h1 just so it's more visible there we go post detail inside of the h1 now we can copy the contents of this file and we can create our second component which is going to be author.jsx inside of there i'm going to paste everything and simply change this to author finally we can create the next component which is going to be the comments form dot jsx again paste everything and just change it to comments form so we know what it is and the last component is going to be the comments themselves again we can paste everything and simply change it to comments of course we also have to export these components so that's going to be the first one is author then we're also going to have the comments form and the comments themselves and there's one more that we're missing and that's going to be the post detail great i might be missing something but we can easily fix it later on now if we go to our slug js this is going to be our basic structure let's see how does it look like there we go this makes sense on the right side we have our recent posts and categories which are already done but on the left side we are yet to implement the post detail and everything else one more thing i can notice is that these don't seem to be h1s but that doesn't really matter since we're going to implement the real components right now so the question is how are we going to get the post detailed data and the answer is we're going to use the get static props something that we've already used before inside of our pages we can basically copy this function inside of the index.js we can go to slug and right below export default we can put our export async function get static props in this case we're going to get params as a parameter and the params is going to be the slug remember this here is the slug or let's say a unique url to a specific resource so how can we now fetch the post details well we of course have to create the endpoint from our services so let's go to our services and inside of here we have to create a new endpoint that's going to get the entire data about everything that we need we are already getting almost everything in this case so we can simply copy and paste the entire get posts we can scroll down a bit and just below our get posts we can post our get post details get post details that's also going to be async but we are getting a slug right here when we call it then we have our query in here we can rename the query to something like get post details and in graphql we can call this as a function and in there say dollar sign slug is equal to and then that's going to be a string exclamation mark we're just saying that we're accepting a slug that's going to be a string and then just before we fetch the data we can do it like this by saying post parentheses where and then we can say an object slug is equal to dollar sign slug so we only want to get that specific article in that case we don't need post connections we also don't need edges and we don't need a node we simply want to get everything from that specific post so we can put an opening brace right here and i know that these queries are getting long and it's easy to make a mistake here so i'm going to give a link to this entire file with the queries just below this video so feel free to copy it and paste it right here in this case i'm going to write it out fix the indentation a bit and remove a few of these there we go so we are getting a post where slug is equal to slug and then we want to get a few things let me see what we already have we want to get a title and the excerpt we already have that we want to get the featured image in the url we also want to get the author including the bio name photo url and everything we need to create that property we also need the categories but in this case we also need just one more thing and that's going to be content and raw this is going to give us access to the post's content and just below in this case we want to pass a request and pass slug in an object as the third parameter these are as you can see here variables finally in this case we simply want to return result dot post great now if you go back to our slug we can actually make a request to this function we've just created so let's delete this and say cons data is equal to a weight get post details params dot slug let's fix this and that's going to be it we're calling to get post details and passing the slug of a specific post finally we can return not posts anymore that's going to be post is equal to data great now as you know in xgs we get what we pass here as props or component so right here we're getting the post i'm quickly going to fix the indentation right here there we go and we also need to fix it here that's good and we can pass the information to each one of our components to our post detail we're going to pass the post equal to our post our author is going to need the author so that's going to be post dot author then below that in our comments form we're going to need the slug so right here we can say slug is equal to post dot slug and for the comments we also need the slug is equal to pose that slug because we need to know to which post do these comments belong to finally to our post widget we only want to pass the slug to each category we can do that by saying post dot categories dot and that's going to be map in here we get a specific category and we simply want to return category dot slug for each one of these categories now we have all the data that we need and we can start working on these individual components let's see if we have an error here it's saying that cannot read property author of undefined so it looks like we don't have access to the post so let's try to console log the post right here there we go and i'm going to open up the inspect element and go to console reload the page and looks like get static paths is required for dynamic server side generation pages and is missing forward slash post forward slash slug so yeah that's true in next gs when you have a dynamic url like this you need to add get static paths that's another special nexus function that we can create just below this one so we can create it right here export async function that's going to be get static paths and then simply a function first we can get the posts by saying const posts is equal to await get posts keep in mind we're getting these posts from here that's another graphql query the first one we wrote and just below we can return something in this case we're going to return an object containing paths now what we can do is we can say posts.map in here we get a specific post but we can destructure that post to get the node out of it and then we can destructure one more time to get the slug now we simply want to return something and that something is params is set to slug so basically we need to specify what kind of articles are we going to have with this our nexus application is going to know all of the possible paths that we can go to forward slash post forward slash react testing and also forward slash post forward slash i think it was web development or next gs in that case so nextgs has to research all of the possible dynamic paths so that it can statically render them and finally we're going to add a comma here and say fallback to false that's going to be everything that we need to do in this case and the error should be gone but we do get one more error and the error says variable slug must be defined so let's see where this is coming from it could be from services and let's see if we're mentioning slug here it's getting as a prop here but that's when we're calling the post details right here so that's fine we're passing the params.slug let's try to really read what the error says variable slug must be defined the reason why we're getting this error is not because of the getpostdetails function let's see what's really happening if we go to our slug in here you can see that we are sending out the slug and the categories to our post widget and what's really happening here in here we're checking if there is a slug remember before we were just covering this portion of the code but now we are checking if there is a slug and we are sending over the categories and a slug to the get similar post graphql query in this query is indeed accepting the slug and the categories so we have to pass them as parameters and to be able to fill them in we have to pass them as variables as the third parameter inside of an object in this graphql request if we do that right now everything works as you can see and we can close this great so now we're properly passing all of the data to all of our components and we can start implementing one by one starting with post detail inside of our post detail we are of course accepting a post itself here and right here we can start by adding a class name that's going to be something like bg white and also shadow dash lg let's do rounded to make it rounded as well and on large devices that's going to be padding 8 usually padding bottom 12 and let's do margin bottom eight we can already save that and see how does it look like so much better already now it might be a good idea to put this here so we can see it like this and collapse this just a bit more there we go so inside of that div we're going to have one more div for our image that div is going to have a class name to relative also overflow dash hidden it's going to have a shadow dash md and it's going to have margin bottom 6 inside of there we want to have our image so let's create a new image tag and we can split it in a few rows we need to add a source src which is going to be post dot featured image dot url we also want to give it an alt tag which is going to be post dot title with one t and finally that's going to be a class name let's do something like object dash top let's say height full and width full let's see how does it look like already there we go and let's make it a bit rounded to the top by saying rounded t and that's going to be lg great this image looks fine and just below this div let's implement another div this div is going to have a class name of px4 and on large devices we're going to set that padding to be equal to zero there we go nothing changed but let's start by adding one more div inside of that div it's going to have a class name set to flex also it's going to be items dash center margin bottom 8 and finally width is going to be set to full just added a bit of height but now we're going to add one more image which is going to be for the author and if i'm not mistaken we already use that author somewhere so let's try to find it by looking for author and there we go inside of here we have our div that contains the author photo url and also author name and while grabbing that let's also grab the current date that the article was posted on again this is inside of the postcard and we're going to paste it here if we end up using it one more time we can definitely make it into a component now let's see we have to import moment in this file so let's import it right here import moment from moment there we go and if we save that we can now see jsm and then the date okay this doesn't look the best so let's try to remove the justify center from this div and save it and now technically this looks like a mobile device so having it on the left and the right side is fine for mobile on desktop this of course looks much better so let's stick with that now we have to go below this div still inside of the major one right here and inside of there we can implement our title that's going to be class name is equal to margin bottom eight then we can also say text three xl and font semi-bold that's simply going to say post dot title if we save that we can now see react testing here and finally we have to render out the content and the rendering the content is going to be let's call it interesting so post dot content dot raw dot children and then we want to map over the children to get each specific type object so the way we're going to get this data is going to be in a lot of different objects where we'll have to map through the children of that specific object as a matter of fact let me show you what i mean i'm going to simply console.log before doing anything let's do a console.log post.content.raw let's save the page and open up the inspect element go to console and there we go our object is right here with four different children you can see that each child is an object containing the type as in paragraph and then the children which is is something a text is it a bold text and so on and we have to render out each specific object they're doing it like this because this is not always going to be text it's going to be images headings tables everything else you can think of so we have to properly map over our children and find out what is that that we are rendering so we're getting a type object as well as the index finally we want to map over that let's open it up as a normal function like this and then inside of there we want to get the children by saying children is equal to type object.children and we need to map over them one more time to get one item and let's call the item index now what do we want to do for each specific item well we're going to call a special function we can first call it here get content fragment so we need to decide of which type is this item so we need to pass the item index as well as the item.text and finally we can pass the item itself of course this function doesn't exist yet but we're going to create it soon and just below this children finally we can return something and that return is going to be the call to the same function git content fragment but this time we're passing things from the upper object so we need to pass the index we also need to pass the children this time because now we have it the children of a specific item then we are going to get the type object itself and finally type object dot type i know this is getting complicated but this is maybe the hardest part where we need to properly loop over every single piece of content to figure out what type is it made of so now we know that we have to create this function just above and this is going to be a function that's not that hard to actually think about or create a logic for but we have to type out a lot of details so in this case i'm simply going to paste it here and you'll be able to find the entire code in the github gist down below but of course i'm going to go through it and explain every single line make sure to copy it and then you can continue with the video what we have to do here is of course declare the function accept parameters and then create a new variable where we just save the text here into it so that we can change it so we're looking into the object if the object exists if that's the case and if the object that bold exists then we simply want to return the modify text as bold right if it's italic we want to return it as italic or underlined then we go into the type so we have a switch where we're checking for the type of that object it can be a heading 3 for example so we're going to make it an h3 and return it it can be a paragraph a heading 4 or an image or it can be normal text in which case we're just going to return it if we did this correctly we should properly render out the entire piece of content right here now let's see what do we have type object is not defined so in here we called it type object let's see if we're somewhere calling it type object like this so in here we're calling it type obj in here i see type object fully spelled let's see if we're calling that somewhere there we go type object here this should have been just type obj and as soon as we save that we have our content in my case i have only text in there with a few bolded words and italicized words but if you want to put any images gifs or anything else that goes into blog articles you can now do that with this specific functionality great and with that we're done with our post detail the next thing we can focus on is going to be the author information so we can go into the author information component and we can start implementing it this one is of course going to be just a bit simpler so to implement the author properly we're going to get the author from props because we're already passing it and right here let's immediately render the author's image that's going to be a self-closing tag something like let's do alternative text is going to be set to author dot name we can also give it a height which can be something like 100 pixels and the width is also going to be 100 pixels then we're going to give it a class name which is going to be set to align dash middle and also rounded dash full and finally the most important thing is going to be the source that's going to be author dot photo dot url now if we save that and scroll down you can see the javascript mastery logo appear right here it's not yet in a full circle but even if it were it wouldn't look perfect because my logo has more width than it has height so it's not gonna fit properly in a perfect circle now let's add our div we're gonna have a class name set to text dash center as well as the margin top 20. also margin bottom eight and let's do padding 12. it's going to be relative it's going to be rounded dash lg and we're going to have a background bg black now if you save that you can see that looks quite aggressive but we're going to also set the bg dash opacity this is a new thing dash 20. so this is going to lower the opacity and now it looks so much better we're going to add one more div here that div is going to have a class name equal to absolute as well as the left dash 0 also right 0 and finally minus stop minus 14. that's going to be the div that the image is going to go inside of there we go add the rest of the jsx that's going to be the h3 it's going to have a class name set to text dash white margin top dash 4 margin bottom 4 like this in that case we could have used simply margin y set to 4 and then text excel and font-bold inside of there we can simply render the author's name by saying author dot name and there we go jsm finally we're going to render one last thing which is going to be a paragraph that paragraph is going to render the author dot bio let's look at it there we go and let's add some classes that's going to be class name is set to text white and text lg great okay this design definitely doesn't look that good so the first thing we can do is put this div above the h3 and the b only the image should be inside of that div if we save that that instantly looks just a bit better in here i should have had 0 that's going to center everything in the middle and for the first time we can also use the image tag from nextgs we can say import image from that's going to be next and then image let me just quickly show you what that is about it's basically an image component the same has the basic one but it supports static side generation with nexjs so in this case i'm going to switch it to that image and basically everything else has to be the same but we can in this case say unoptimized that's going to be it and we're going to save it now if we go back it is going to be centered in the middle but of course this still doesn't look that good let's see how does it look like on the deployed version this is looking so much better so i'm going to go ahead and change my logo to the white version in my graph cms dashboard there we go we are inside of our dashboard and i'm going to go to content once we're here we can go to authors and just simply change it i pulled everything so we have more space and i'm going to click replace photo and i'm simply going to upload it there we go i'm going to choose a different version of the logo and simply click upload let's see save and publish and the changes should be reflected immediately if i reload the page okay it says that the url of her photo is null that's because the photo itself still hasn't been published so i'm going to publish it right here there we go everything is published now and we can reload the page this looks so much better so sometimes the code is going to be correct but you have to use the right image great with that said our author portion is now done we have our entire post details page with the author the date of publishing the title and the content as well as the author information we also have our related post right here and the categories what we can do next is going to be the comments form and the comments themselves to create comments for the first time in this video we won't be just pulling the data from graph cms we'll be sending data we need to write a comment that's then going to appear inside of our graph cms dashboard and then we have to allow it so let's go ahead and implement it right now so let's go ahead and close all of the components besides the comments form that's going to be our next comment to implement inside of here we'll be dealing with some forms of course so let's import a few things from react and that's going to be use state as well as the use effect to our comments form we are already sending in the slug so we can get it right here and let's go ahead and create a few use state fields i usually create use states by starting to type use state and then clicking this little rectangle right here and don't click anything yet just type the name of your state something like error and then press tab it's immediately going to capitalize the e right here and you can start typing your default state which is going to be false in this case now we can repeat the process a few more times the second state is going to be called local storage this is going to allow us to simply fetch the data from local storage and at the start it's going to be set to null the third state we'll be dealing with is going to be the use state something like show success message and at the start that's also going to be set to false and finally for our form fields we're simply going to use the use ref hook so we can also import the use ref right here and that's going to be const comment element is equal to use ref we're also going to duplicate that three more times the second one is going to be name element the third one is going to be the email element we can add the el at the end right here and right here and the last one is going to be the store data element like this we don't need to keep these values in the state because we simply want to read the value from the input field and then send it to graph cms that's we're going to use refs because they're going to be more efficient than keeping track of the entire input state with all of these states and refs right here we can now start creating our output so let's first add a class name to our first div and that's going to be bg-white and let's scroll down so that we can see the changes there we go comments form let's do shadow dash lg rounded dash lg and finally padding dash 8 padding bottom 12 and margin bottom 8. with that we get this nice looking card then we're going to have an h3 instead of an h1 and we're going to give it a class name which is going to be set to text excel margin bottom is going to be set to eight font is going to be semi bold like this and also we're going to give it a border bottom as well as the padding bottom four great that's going to make it look like all of our other cards now we're going to create a div below this h3 and that div is going to be of a class name is grid it's going to have grid dash pulse dash 1 gap is going to be set to 4 and margin bottom is going to be set to 4. now let's duplicate that div two more times in the first one we're going to have our text area this is going to be the element in which we're going to input our actual comment we can specify a ref which is going to be the comment element like this and finally to make this look really good we're going to add quite a long class name so let's say class name is equal to padding dash 4 like this also we're going to do outline dash none let's do w dash full that's going to make it full width we can also make it rounded dash lg and now let's specify what's going to happen once we focus it so we can say focus ring dash 2 then we can also say focus ring dash gray dash 200 and then usually it's going to be bg dash gray dash 100 there we go now you can see this little text area right here and for the text we can say text gray 700 great this is our comment we're going to pull that into a new line and our text area is going to be a self-closing tag so we can do it like this and let's put our class name in a new row because we have to add a few more things before that we need to delete this right here and we should be good to go the other things we need to add are going to be the placeholder which we can set to comment and also name is going to be set to comment great now we can see that right here and we can create an input for our name and our email our input is going to be inside of this div right here we can create an input as a self-closing tag it's going to have a type equal to text ref equal to name element and now for the classes we can basically copy this entire object right here the only thing we'll do instead of padding 4 we're going to say py and that's going to be 2. and of course we can copy the placeholder and the name right here but that's going to be name and also name right here there we go now we have our comment and our name we can just say padding x is going to be 4 there we go to space it out properly now we can go ahead and duplicate this input and right here instead of name element we're going to say that's going to be email element here we can say email and right here the name is going to be email there we go we have our comment name and email and for our second div right here that contains these inputs we can simply say on large devices lg grid dash calls dash two this is going to make the name and email go one next to each other as you can see right here great now we won't need this div but instead of that div we're going to specify the error if somebody types something wrong so right here we can say error if the error exists in that case we want to render out a p tag that's going to say all fields are required not rounded that's going to be required great so and let's give it a class name our class name is going to be text xs and also text red dash 500 of course we won't see the error right now but later on once we test the error handling we will be able to see it now below that error we're going to add a div this div is going to have a class name set to margin top mt8 and right here we're just going to have a button this button is going to be of a type is equal to button and we're going to have an on click on click is going to be equal to handle comment submission just like that of course this function doesn't yet exist so let's go ahead and create it right here const handle comment submission and for now we can leave it empty great so what class names are we going to give to this button i'm going to put this into multiple rows again so that we can see it properly and let's start adding the class names we can start by saying classname is equal to and we're going to give it a transition then we're going to give it a duration of 500 milliseconds and the animation is going to be ease let's also immediately say something inside of the button something like post comment that way we'll be able to see the changes that we're making on this button there we go post comment right now we don't have anything but if we say hover then we want to say bg that's going to be indigo 900 and also it's going to be inline dash block let's see if that makes any changes not yet i have an extra end here there we go so now you can see that transition it eases in into the indigo color then we're going to say bg dash pink dash 600 and we can say text lg to make it a bit larger also let's do rounded dash full and let's do text dash white okay this is looking a bit better and finally we're going to give it a px or a horizontal padding set to 8 and also py is going to be set to 3 and finally cursor dash pointer take a look now it eases in from this pink color into this indigo color great i know a lot of classes to just create a button but we do have a completely custom button with the animation right now in one line and right now next to that button we can show our submission message so right here below the button we can say if show success message and then in that case we want to render a span and that span is going to say comment submitted for review great and let's give it some class names that's going to be let's do text xl extra large let's make it float right font dash semi-bold margin top is going to be three and let's do text green 500. of course we cannot see that yet but once we actually submit this then we'll be able to see that message of course now we have to work with actual data that we'll be sending over so we have to go to handle comment submission instead of here the first thing we're going to do is set the error to be false because at the start we don't have errors and then we have to check if the error exists so we can say if no comment element dot current dot value or no that's going to be name element dot current dot value or no that's going to be email element without the dot at the start no email element dot current dot value you can see we are repeating these things quite often so what we can say is let's do simply comment by destructuring the value so const comment is equal to that's going to be comment element dot current and finally we can duplicate this two more times the second time we're going to get the name from the name element.current and the third time we're going to get the email from the email element that's going to be email element like this of course we need to get the actual value from the current so this syntax wouldn't be correct we need to say destructure the value and then rename it to comment and we can repeat the same thing in this case and now we'll be able to simply write something like if no comment and then we can say here or no name or no email in that case what do we want to do well simply set the error to be equal to true and then return to outside of this function because we want to stop the comment submission great now we want to form the actual comment object we can do that by saying const comment obj is equal to and in here we can simply say name email and comment and finally we need to pass the slug as well now even though this is an object we don't need to say name is equal to name email is equal to email and so on and that's the exact reason why we destructure this because now we can use this shorthand property and just have everything in one line finally now we have to check if the user wants us to save the data into local storage to check that we're simply going to add a checkbox and before we do that we're just going to copy this div right here and paste it just above our error here there we go so that's going to be a grid grid columns 1 gap 4 and margin bottom 4. inside of there we can create one more div which is going to be just a container and in here we can have an input tag which is a self-closing tag it's going to have a ref equal to store data dot element the type is going to be equal to check box the id is going to be set to store data the name is going to be set to store data as well and finally the value is going to be set to true by default in this case this should have been just store data element so that's going to fix it there we go there is our checkbox and now let's add a label for that checkbox we can do that by saying label in there we can say something like save my email and name for the next time i comment there we go and now let's just style it with tailwind by saying class name that's going to be equal to text dash gray dash 500 and cursor dash pointer and finally we're just going to say html4 store data now if we save that you can see if we click this it actually triggers this checkbox we can just add it some margin left right here by saying margin left ml and let's do two if we scroll down you'll notice that now it has a margin left great so now we can use that value from store data element we can also destructure that right here inside of our handle comment submission by simply saying store data element and here we're going to say store data so do we want to store data or not but in this case this is not going to be value it's going to be the checked state because it's a check box so now just below this comment object we can say if that's going to be store data so if the user wants us to store the data in that case we can simply say local storage dot set item we want to set the name to be equal to and we can simply put name here because we destructured it from ref and finally we can duplicate this line and in here we can use email now if that is not the case if we don't want to store the data in that case we can simply remove it from the local storage by not using said item here rather it's going to be remove item great so now we handle the local storage as well and finally we have to submit our comment we can do that by adding a new query to our services right here so let's scroll to the bottom and right here we can create one more function that's going to be export const let's call it submit comment that's going to be an async function and we're going to accept the actual comment object now in this case we won't be making a basic graphql query we are rather going to make an http request to our own next.js backend so remember when i said that you can create your own api inside of an xjs application you don't need to have a separate node.js server well that's exactly what we'll be doing we're going to write a request that's going to go straight to our own backend so that's going to look something like this const result is equal to a weight fetch we want to make a fetch request to forward slash api for slash comments and then we want to pass some data so we can say the method is going to be set to post then we're going to add the headers and finally we're going to set the body to be equal to json.stringify and that's going to be object so we're going to send a stringified object to our own backend finally once we return the data we want to return result.json there we go of course now the most important part is to create our own backend endpoint which is going to accept that comment and actually do something with it and the reason why we need a backend is because graphcms allows our own backend to interact with our service to actually submit a comment to graphcms then we'll be able to see it and approve or disapprove it from the graphcms dashboard so we can go to our api and we already have a hello js file if you want to read more about the api routes that nxjs offers you can go to this link but in this case we're going to rename our hello.js to something like let's do comments.js now i'm going to put my own comment right into here and it's going to say something like this any file inside of the folder pages api is mapped to forward slash api for slash something and will be treated as an endpoint instead of a page this is really important to know as i've told you you can create your own backend within a next.js application so this file is going to be an endpoint to forward slash api for slash comments and if we go here you can see that that's exactly what we are doing so let's create that endpoint we can first import the things that we need that's going to be import let's do graph ql like this graphql and what we need from graphql is going to be graphql client and we also need gql to make that query now we're going to say const and that's going to be graphql api this is the variable that we already saved inside of the process.env dot next underscore public underscore i think it's graph cms underscore endpoint we can also go ahead and take a look right inside of here that's right next public graph cms and i'm going to expand our editor so it's easier to work here and let's go ahead and create our endpoint so we can say export default function let's call it comments we accept the request and the response the same as we do in node if you haven't worked with node before don't worry this is not a back-end tutorial i'm just going to show you how to create this one route so that we can submit user comments now to be able to post data to our graph cms we need to set up the graphql client so we can say const that's going to be graph ql and client like this usually we can write graph and then ql is going to be uppercase graphql client like so and that's going to be equal to new graphql client as the first parameter we need to pass our graphql api right here and then as the second parameter we're going to pass the options object where we're going to set the authentication headers so our headers are going to say authorization not authentication my bad and we need to set that to a template string that's going to say bearer and in here we have to use something from the process.env and this is going to be a specific token that we don't already have access to so let's find that special graph cms token from inside of their dashboard i'm going to expand our chrome right now and we are right here so let's go to settings i'm going to expand it even more so that we can see the sidebar and let's go to permanent auth tokens if we scroll a bit more down we can create our first permanent odd token let's add a token name as dev and we don't need to add a description create and configure permissions and there we go we have our token right here and i'm simply going to copy it now we can go back to our code more specifically to the env file inside of here we're going to set graph cms underscore token is going to be equal to like this and we're just going to put it in strings there we go this is our token of course you can copy yours once we have that we can go back here and just say process.env dot graph cms underscore token and this is how we're going to authenticate or authorize our graphql client now that we have our graphql client we can create our query and we wrote a lot of queries so far so you know how it goes const query is equal to gql template string and then from inside of here we write our query but for the first time ever this query is going to be a mutation query not just a regular get query so in here we can say mutation and we can call it create comment and when i say mutation in graphql that simply means that we're going to update some data or add some new data like a new comment so our create comment in graphql is going to accept a few parameters is going to be name we need to put a dollar sign syntax inside of gql queries and that's going to be column string exclamation mark and then we can do the same thing door sign email is again going to be a string like this then we're going to add our actual comment which is going to be again one more string like this and finally we need a slug and our slug is going to be a string as well finally open up a pair of curly braces inside of there we're going to call that create comment and we need to pass the data so we can say data colon and then we can say name is equal to dollar sign name email is equal to door sign email comment like this is equal to dollar sign comment and then finally post is equal to now keep in mind i'm going to put this a bit more to the right we have to say connect colon an object slug is equal to dollar sign slug so we're connecting our comment and name and email to a specific post that the user commented on and finally after all of these parentheses and curly braces we're going to add the id right here once we run this query it's going to create a new comment inside of the graph cms dashboard so let's run it we can run it by saying cost result is equal to a weight that's going to be graphql client and then dot request we need to pass in our query and then as the second parameter we need to pass our object which contains all of our data things like name our name is going to be equal to rec dot body dot name then we're also going to have our email our comment and our slug and we can destructure that at the top by saying name email slug and comment is equal to reg.body now instead of writing everything like this name is equal to reg.body.name email is equal to reg.deadbody.email and so on we can simply write it like this name and then email but if you think about it the only thing that our reg dead body contains are these exact properties name email slug and comment so if you think about it we're trying to form an object by taking the properties outside of another object and then putting them back in so that's not necessary we don't need to create a new object we can just pass the entire reg.body because it already contains all the values that we need and finally once we get the result we can return it back to our front end next.js by saying res.status is 200 dot send result and there we go if we've done everything correctly our endpoint should not work and we should be ready to import it inside of our comments form right inside of here we can simply import that's going to be submit comment from dot slash services and right here below our if store data we can call our submit comment of course we're going to call it and pass in the comment object comment obj and then let's use the dot then syntax so we're going to have a dot then here inside of the dot then we're going to get the response from our back end inside of that dot then we can simply say set show success message to be set to true and finally we're going to add a timeout so something like set timeout like this and in there we can simply say set show success message to be equal to false after let's do 3000 milliseconds which is three seconds so we'll be showing that message for three seconds and then remove it and that's going to be it for our submit comment now if you think about it there's just one more thing to do and that is if we're visiting the post for the second time our local storage data is already going to be there so we need to make use of it for that let's create a new use effect it's going to be a component did mount use effect so it's only going to happen at the start and inside of here we can simply say name element dot current dot value is equal to window dot local storage dot get item like this and that's going to be name finally we can duplicate this that's going to be email element and we can write here get the email let's save it and see if everything works back in our application localhost 3000 there is our beautiful comments form i think that we shouldn't actually say comments form there rather let's say something like to leave a reply so let's go here and say leave a reply and let's try to actually leave a reply this post is about react testing so i'm going to say just or mocha these are react testing libraries i've added my name and my email and i'm going to click save my email and name for the next time i comment finally let's go ahead and click post comment i would actually be surprised if everything worked the first try usually once you write code for quite a lot of time and don't do any testing something breaks but that's completely normal so let's go ahead and click post comment let's see there we go there's our error looks like we cannot read property of null reading set item in the if store data so in react you can immediately use the local storage but in next gs it might be possible that we need to add window dot local storage right here so let's try to save it and test it out i've added my name and email one more time and i'm gonna click post comment this time we got a different error unexpected reserved word await that is going to be inside of line 23 comments.js so let's go to our comments.js line 23 and we have an await here but i don't think we have an async so let's say async function comments now we should be able to use a weight and as you can see our local storage now worked and third time is the charm so let's say just or mocha let's do all uppercase right now and let's go ahead and post our comment okay nothing seems to be happening which could be a good thing or a bad thing so let's go to inspect and let's check out our console log we have four different errors here let's try to clear them and click post comment one more time there we go internal server error localhost 3000 api commons 500 unexpected token in json at position 0. so let's try to open up this request and go here we got a 500 which means that something went wrong on our api side and again i don't want to simply fix this and skip it in the video i want to lead you through the process of debugging this error yourself because errors are a normal thing and they happen to everyone so let's go to our back inside and see what can we do here first thing we can do to try to debug this is add a try and catch block if we're using an await we can put it in a try block also return the result in the try but if something goes wrong we want to console log this error so let's try to see what do we get now i'll try to initiate one more request right here we're not expecting anything on our front-end side because now we're working with the back end so you can go back to your code go to view and then terminal and right inside of here we should be able to see our error if you scroll down there we go type error graphql something graphql client is not a constructor that means that it's complaining that we're trying to do a new on graphql client and i've just noticed the issue we're not trying to import this from graphql rather it's going to be a graphql request library there we go now our graphql client should be good and we should be able to make a comment now let's clear our console and click post comment and nothing seems to happen if we go to our network tab we can see that all of our requests are pending that means that we are still getting into the error so let's see what the error is this time and it looks like api resolved without sending a response for api comments let's try to read it a bit more graphql error there we go so this is the real error and the error message is saying parse token failed compact jws format must have three parts so let's see if we mess something up with the actual authorization part what i would do right now is save this into a new variable graph cms token let's add a capital t and that's going to be equal to process.env.graphcms token of course we can now use that token right inside of here but i also want to add a console log at the top right here console.log that's going to be graphcms token let's see if we get anything back i'm also going to wrap it in an object so that we can more easily see where is it i'm going to save it and make one more request there we go still pending if we open up our terminal and scroll down we see compiled successfully but let me try to make one new request post comment and looks like nothing is happening yet so let's simply also return something because all the errors are currently pending so right here i'm going to say return res that status 500 and we can pass over the error there we go now i'm going to reload the page and these errors shouldn't be pending anymore because now we're returning something from the back end even though we have an error so right here i'm going to post my comment mocha or jest and finally post comment there we go now you can see that we immediately get a 500 and in here we have the request and the response parse token still failed but now if we go back and scroll a bit up we can indeed see that our graph cms token is undefined so that means one out of two things first we either named it incorrectly let's see graph cms nope the name is correct and the second thing is we forgot to reload our server before we tested out the token remember whenever you change the env you have to restart your server okay that was definitely a rook a mistake but again that's the whole point of why i left this entire part in to tell you that rookie mistakes are happening to everybody and you can spend hours and hours looking at a thing that should have been obvious but again you saw how i went through the entire debugging process and there we go now it should work and usually it's always a good idea to have a try and catch block in case something goes wrong so now finally i'm going to say mocha or jest and now we are really angry and hopefully it's going to work now let's click post comment and there we go it says comment submitted for review but we did get the 500 again and the error is json body could not be decoded so let's see what we're passing in as json let's see from our frontend part we're passing in the json right here as the comment object then we go into our submit comment right here and we're passing in a stringified object it's possible that we also have to add headers right here and specify the actual content type so right here i'm going to say content in a string content dash type and that's going to be set to a string that's going to say application forward slash json let's try to save that and see if it's gonna work right now i'm gonna press post comment one more time we still do get a 500 but now it's a different error saying field post is not defined by comment create input okay so we can go back to the code and now the error is definitely happening right here most likely has to do something about this post right here it's saying the field post doesn't exist on a comment let's go to our graph cms dashboard and see if we do have a post connected to our comment so that's going to be graph cms schema comment and looks like there isn't anything here we definitely have to create a reference between a comment and a post so let's go to our post and right inside of here i'm going to create a new reference that reference is going to be to the comment and it's going to be a two-way reference multiple posts per comment that's not going to be true it's going to be multiple comments per post and then it's going to be read and write and read and write here as well and there we go it has been created and if we go to our comment now you can see that there is a post so hopefully our mutation query should accept our post as a parameter to our create comment now that we've actually connected our comment to our post we can go to settings and then we're going to go to permanent auth tokens finally edit and then create permission we want to give read create update delete publish and unpublish and anything we can give all permissions to our api token because that's our token so let's click create of course if you use real tokens you can only give the permissions that you want in this case we're gonna need only the create update and potentially read but now let's go ahead and go back to our application and let's try to post our comment we can of course first clear the console and there we go 200 comment submitted for review and we got the id of the comment now the comment is not going to immediately appear right here but if we go to graph cms and if we go to our content comment you'll see that a new comment appeared right here created by dev token and it's set as a draft that's because we don't want to allow all comments on our blogs some comments may be inappropriate so we want to choose which ones do we allow and there we go we've actually submitted this data from our front end to our graph cms and now we can publish it our comment has been published and right now there isn't really a way for us to know if it's there what we need to do next is implement the comments function where we're just going to read the comments for each specific blog and then show them right here so let's do that right now to actually show our posts we can close all of the files besides the comments.jsx file inside of here we can start by first importing a few things that's going to be use state as well as the use effect from react then we're also going to import moment that's going to be moment from moment and finally we're going to import parse from html dash react dash parser inside of our comments we're getting a slug as our prop we're passing it in so we're accepting it and now we have to get all of the comments for this specific post to do that first we can create a new use state field and let's call our state comments set comments and at the start they're going to be set to an empty array then we can create a new use effect right here and our use effect is going to be a dead mount meaning it's only going to happen at the start and what do we want to do at the start well we want to call the get comments function and we need to pass in our slug of course this get comments function is not defined yet so let's go to our services and then our index.js and let's create that last graphql query to fetch the comments it's going to be a simple one we can even copy this get categories paste it right here and just rename it to get comments query is going to be similar const query is equal to gql a template string and then right here that's going to be get comments but we're going to call it as a function and say slug is equal to string with an exclamation mark so we're going to accept one parameter and that parameter is going to be slug coming from here and to be able to retrieve it inside our graphql query we need to pass it right here as the third parameter to our graphql request so once we have the query we want to simply fetch all the comments where post slug is dollar sign slug so one more time we're trying to get all the comments where in an object post again in an object has this slug once we do get all of them we can simply fetch them and then we want to fetch the name also the created add property and finally we want to return result dot comments great our last query is done and now we can go back here and import it that's going to be import get comments and that's coming from dot slash services right inside of here okay now that we do have this function we can call a dot then on it like this once we call like that then we're gonna get a result and we simply want to do set comments result because that result is actually the new updated comments therefore we're now setting our comments and we can go ahead and display them right here so to do that we can first create a new empty react fragment right here and inside of there we can check if our comments exist by saying comment.length is greater than 0 in that case we want to display the following we want to display a div that div is going to have a class name equal to bg dash white shadow dash lg rounded dash lg padding dash 8 padding bottom 12 and margin bottom dash 8. finally inside of there we're gonna have our comment so we can say h3 that h3 is going to have a class name set to text xl margin bottom eight font dash semi bold border dash b and finally padding bottom is four inside of here we're simply going to list the number of comments by saying comments dot length and then we can leave one empty space like this and we're simply going to say comments so this is going to be like two comments or three or four or any number of comments and finally below that h3 we want to actually map over the comments we can do that like this comments dot map we get an individual comment and we simply want to display something for it that's going to be a div with a key equal to let's do comment dot created at because every comment should be created at a different time that div is going to have a class name equal to border dash b border dash gray dash 100 margin bottom 4 and padding bottom 4. finally inside of that div we're gonna have a paragraph that paragraph is going to have a class name equal to margin bottom four and we're going to have a span element right here that span is simply going to show the comment dot name meaning the person who created that comment and it's going to have a class name equal to font dash semi-bold and below that we can leave one more space and say on i don't want to say on click i simply want to say on and then we're going to leave one more space and right here we are going to use the moment library to say comment dot created at and then dot format mmm to get the month and then dd and then comma four times y there we go this is going to give us our date and this is going to be it for our comments and finally the most important thing right below this paragraph we're gonna have one more paragraph with a class name equal to white space dash pre dash line again feel free to search for this in tailwind docs then text dash gray-600 and finally w dash full for full width inside of there we're going to call the parse function from our library and then send the comment dot comment and this is going to be it we're going to loop through the comments and display them with this functionality and this jsx let's save it and take a look and there we go one comment from adrian on october 21st 2021 mocha or just let's leave one more comment i'm going to say whoa the comments actually work and let's go ahead and post it comment submitted for review that's great we can go to our graph cms dashboard and right inside of here we can go to comments and there is our draft comment we can look into it publish it and just like that if we go back and reload the page we can see that now we have two different comments and finally there is just one more thing left to do and that's the thing that i left as a challenge for today's video you learn a lot by watching these videos because you're exposed to these new technologies and new ways of thinking but you really learn the most once you try something out yourself so the challenge for this video is to code out the featured posts section of course i'm not just going to leave you here i'm going to give you access to the code and walk you quickly through it so once you actually code it out or if you get stuck you can reference to this specific part of the video but definitely make sure to give it a try yourself with that said i'm going to show you how to get access to the code right now you can start by creating a new file but it's not going to be inside of the components it's going to be inside of a new folder called sections inside of there we're going to create a file called featured posts dot jsx the code is going to be in the gis down below alongside all of the other files we've used so far so you can simply paste it here or you can reference to this code if you tried coding it out yourself so essentially what we're doing is we're fetching data from graphql and just rendering it in a carousel can notice that there is one more component that we need which is a featured postcard so instead of the components let's create that featured post card dot jsx and this file is also not that complicated it's mainly doing everything we've done so far passing in the post through props and then right here displaying some jsx using tailwind and displaying the image for that specific post now the key part is that we also have to make one more and last graphql query right here get featured posts so to do that you can go to services index.js and just at the bottom you can either copy it or you can code it yourself you can try going through some other queries and thinking about how this query would look like of course we're getting posts but where are we getting the post somewhere else like here this is the post details in here we're getting all of the posts so could that be related this is how the get featured post query is going to look like it's a query where we get a post and the only thing we have to do is say get the posts where the boolean value featured post is set to true and then pull out all of these details that we need for that specific post and then finally return it now that we have that query we have our featured postcard and we're actually looping over all of our featured postcards let's go ahead and check it out let's go to localhost 3000 and reload the page right now we cannot see anything because we haven't yet rendered it out on our home page so inside of the index.js not the one in the components but the main one inside of the pages index.js instead of here we have to import that's going to be featured posts like this and that's coming from dot slash sections and we can render it just below the head element there we go of course that's going to be a self-closing component there we go let's save it and before we go ahead and check it out let's just export this component by adding a new file in the sections index.js and inside of here we're simply going to say export default as that's going to be featured posts from dot slash featured posts just like that now before we finally go ahead and take a look let's just go to our components in the js and let's not forget to export our featured postcard as well so right here that's going to be featured post card there we go now we're finally ready to take a look and there we go as soon as i reloaded the page we can see our featured posts right here that's looking great if we had more we would even have a carousel and we would be able to switch between them right now this is looking a bit empty but with the power of graph cms your clients or yourself can simply add new posts right away and in a matter of minutes you can fill your blog with a lot of posts with that said we've implemented the entire functionality of this application finally we are ready to deploy to the web and since this is a next.js application we're going to use versailles versailles works wonderfully with nexjs because they're both created by the same company before we go ahead and deploy this project there are two more things that we have to implement the first one is the category page so right now once we click on react we're gonna get a 404 and this is going to be the page similar to the one we've already created so let me show you how to do it we can go inside of the pages and then right inside of here we're going to create a new folder called category inside of our category we're going to create a new file and also call it a slug dot js like this there we go and again this is going to be really similar so feel free to find the slug category file in the description down below it's going to be in another gist so there we go i pasted it right here and you can notice that we also need one more component and that component is going to be a loader so let's go to components let's add that loader.jsx and that loader is going to be nothing more than a simple svg that's going to say loading then inside of the index.js we can of course export that loader straight inside of here considering that we've added some new changes to make sure that everything absolutely works and you don't encounter absolutely any errors go to services and then simply paste the services page from the gist below this video that way we'll be sure that we're all on the same page and will be sure that your project is going to be deployed correctly there we go now we can go back in here and the final change that we have to make is going to be inside of our pages post and then slug right here right now we just have get static props but we set fallback to be false that means that nextgs is going to statically generate our site and that's going to be great it's going to be incredibly fast but if we deploy this project right now and if we then add a new blog post using graphcms we won't be able to get to it because all of our current posts are going to be statically generated so what we have to do is simply set this full back to be equal to true and then we have to add a loader at the top so right here we can import something called use router from next router we can also import one more component which is going to be a loader component and now finally we can simply say const router is equal to use router and then just below we can say if router dot is fallback in that case we want to return just a self-closing loader component with that we should be able to see all of the new articles that we post even after the deployment great so with that said we should be ready to actually publish this project so let's go ahead and close all of the files and folders and the first thing we have to do is create a new github repository to create a new github repository you can go to your github and then at the top right you can click new repository let's name it something like graph cms underscore blog that's going to be enough of course you can call it anything you want and then you can click create repository and now we simply have to follow the steps to actually publish it so i'm going to put this side by side with our editor there we go we can go to view terminal and now we can stop that terminal from running by pressing ctrl c y and then clear great so let's start with git init in here it should say initialized or re-initialized that's going to be fine then we want to add the env to git ignore so right here just below i'm going to add the dot env file because we don't want to push it to github then we're going to say git add dot and now we can copy the rest of the steps git commit dash m first commit get branch dash m main get remote add origin like this and finally git push u origin master and as soon as you do that and reload the page you should be able to see your github repository appear right here once you do that you can open up for sell.com and then go to the top right and click login you can choose your preferred login method i'm going to go with github and once you're in you can simply click new project it's going to immediately recognize your github repository so you can click import we don't need a team so i'm going to click skip and just below we can configure our project by adding our environment variables so inside of our code we can go to the env copy the name of the first env paste it here and then also of course copy the value there we go and click add now we can repeat the process for the second environment variable right here i'm going to take the value as well and paste it straight here and finally click deploy this process should take about a minute and then we'll be right back to hopefully see our page live and deployed and there we go confetti flew down the page and our project has been deployed so let's go ahead and click right here and let's visit the page and as you can see our website is now live on the web now we can go back to grab cms and we can continue adding new articles to this deployed blog without knowing how to code at all you can give access to this blog to anybody and they can simply go here to content and start creating new posts this is phenomenal if you're creating any kind of websites for clients that need constant updates this way they can add the updates themselves so let's go to create item and let's add one final article let's do something like graph cms is awesome let's just say graph cms for the slug for excerpt let's do you must read this article and then in here we can really do anything you want i'm just going to say bold italic testing great again just so we can test out different features but really you can do anything you want in this case you can even add links change it to headings and so on great let's add a featured image in this case i'm going to use this graph cms one let's make it a featured post the author can be javascript mastery and categories can be both react and web development finally let's click save and publish there we go our article has been added we can go back to our blog reload the page and a new article appeared momentarily there we go so let's go ahead and check it out there we go our article is right here we can add the content we can see who created it and everything is right here let's check out some more articles right here and everything seems to be great we can even see the comments of course you can even add new authors new categories and new posts everything through graphcms and congratulations for coming to the end of this video hopefully everything looks great for you as well and you'll be able to use this project for all of your future clients need blog or any kind of website that needs content that requires updating this is a big project so it's possible that you'll encounter some edge cases or really obscure errors if that's the case i'll try to keep the getup repository up to date with all the latest fixes so if something doesn't work it's possible that the fix is going to be included in the github repository of this project so if something is just a bit different from what you've seen in the video don't worry on github we've implemented the latest fixes with that said thank you so much for watching and one more time huge thanks to graphcms for creating such an amazing cms platform i hope you enjoyed this video learned a lot and i'll see you in the next one have a wonderful day [Music]
Info
Channel: JavaScript Mastery
Views: 67,689
Rating: undefined out of 5
Keywords: javascript, javascript mastery, js mastery, master javascript, javascript tutorial, learn javascript, headless cms, nextjs tutorial, web development, create blog website using react, create blog website using next, create a blog tutorial 2021, create a blog using next, Create a Blog Website using React, cms blog, headless cms blog, graphql blog, graphcms, graphcms nextjs, graphcms tutorial, nextjs blog, react blog, nextjs blog tutorial, react tutorial, react website
Id: HYv55DhgTuA
Channel Id: undefined
Length: 189min 59sec (11399 seconds)
Published: Fri Nov 05 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.