Transcript for:
Complete Next.js 14 Tutorial Summary

Hello friends welcome to the complete nextjs 14 tutorial nextjs is the most popular react framework and it's used by thousands of websites and applications all these companies trust nextjs because it's so easy to create fast and secure web applications with it and this tutorial includes everything you need to know about the new version of nextjs including the app rer servers site and client site rendering data fetching API routes and server actions authenication and more and by the end of the video you'll have created this full stack application we will create all these Pages using the app row and you will learn the folder structure and the layouts after that we will patch all these posts from our database and you will understand this static and dynamic data fetching caching and revalidating then we will implement the authentication we will be able to log in and register with social media accounts or user credentials and log out using this button and you'll see how easy it is to protect routes on the server site using custom user roles and nextjs middle where right now I'm not authenticated and if I try to reach the posts I'll be redirected to the login page because only users can access the data and if I log in as an admin this button will show up and I'll be able to reach the admin dashboard and in this dashboard I can remove users and posts or add new ones and during this process we don't have to refresh the page or use any library to see the changes because we are going to be using the new server actions thanks to this awesome feature we can mutate our data on the server site I will also show you nextjs API routes and we'll compare the cons and pros of server actions and API routes this tutorial is going to teach you everything to create a full stack web application but if you want to go deeper and learn every little detail of react and nextjs I invite you to join the react nextjs Master course wait list if you are interested the link will be in the description below and after joining the wait list please let me know what your expectations are because I want to give you the maximum benefit instead of just recording regular tutorials okay after this information if you are ready let's get started okay I created a new folder and inside this folder let's install our next Jaz application let's open up the nextjs documentation next js. org and I will click on get started and I will say installation before starting make sure that not JS is installed on your computer but if you are watching this video you probably already have after that we will create our new app using this command I will copy and open up my terminal and I will paste my code I will install everything inside this folder so I will say dot if you don't write dot it's going to create a new folder I don't want to do that I will say enter and it's going to provide some options that we can choose you can use typescript or JavaScript we are going to be using eslint it basically allows us to see our potential errors before running our application and it's going to save a lot of time you can choose Tailwind or plain CSS but it's not our concern for this tutorial because we will not be primarily focusing on the design part I want to use the source directory it helps me to organize my files I will explain this in a moment we are going to be using a rder of course we don't have to customize our Imports and it's going to install our app and it's ready this is how we can create a next app but if you do that it's going to install some unnecessary files HTML elements that we are not going to use and some Styles so before starting we have to delete all these items and also when you use this command it's going to install the latest version but if you watch this video after the release date it might be a different version and if you want to prevent any potential errors I highly recommend you use my GitHub repository the link will be in the description below just find this branch and use thiso for this tutorial because I will show you some experimental nextjs features also so even if those features become stable you will be able to run your application without any problem so you can come here and download this repos story and open up your folder with vcot but you're a developer so you should get used to using git so instead of downloading come here and copy this URL and use this URL in your terminal first here I'm going to delete everything here and of course I should delete the git folder otherwise we will not be able to clone any other GitHub repository and you can say get clone and this URL but the better way is Fork this repository so you can create your own report and using this report you can keep track of your progress because it will be a long tutorial so you can commit your changes daily so after doing that come here and copy your own URL so again I will say get clone is going to be your URL and Dot and enter if you have any problem here instead of using the same folder just create a new one and clone your repos story okay as you can see we don't have our libraries let's install them using mpm install and our application is ready let's start I will say mpm run and Dev so it's going to run our application in the development mode as you can see our app is running on this port number let's open up and that's all we don't have any default HTML elements our page is here so we are going to create everything from scratch but before that let me explain the folder structure we have some configuration files here packet Json shows our dependencies inside next config JS we are going to write our nextjs configurations so we will be able to use next Jaz experimental features or we will be able to use different URLs to show our images you are going to see all of them later inside JavaScript configuration as you can see it provides a default path and it's going to be our source folder so instead of writing the exact path we can use this sign and import our files what I mean by that if you remember when we use react we were calling our components something like that import nowbar for example and from the previous folder and maybe other folders and finally components and our nabar component but instead of doing this we can directly say add sign and it basically means go to the source folder and inside this Source folder components and nbare so in this way it's much easier to import our files without digging nest. folders and this is going to be our estin rules when we make our first mistake you are going to understand how it works and inside source directory we have the app folder but before that we have our public folder here we are going to have our images videos or other media contents these are our libraries when we install a new library using our terminal it's going to install them here and this folder includes our cached application when we make any change it's going to cach our files and when we build our app our build folder will be here okay so let's talk about the app rouder it's the biggest feature of nextjs because we don't have to worry about routing let me show you how it works app rer allows us to navigate between our Pages easily in react we need a library and some configurations to do that but in next Jaz we are able to do this by using the app folder and we can create all our Pages using this app directory let's say we have four main Pages it's going to be the homepage about page contact page and and the blog page and I'm going to write their path names which are the part of the URL that come after the domain name like slash about contact and block so we can navigate between Pages using these path names the only thing I should do is create the page folder inside the app directory for example for the homepage we don't need to create any folder because we don't have any path name so I'm going to create here a file and the file name has to be page and the extension can be JS or jsx or if you are using typescript TS or TSX this name is important because this is how nextjs know that we are creating a page not a component and for the about page I should create a sub folder and the name of the folder will be this path name so I can do the same thing for the contact page and the blog page contact and block this is how we are creating our pages but why do if we have some nested routes let's say in the about page we have two more pages let's create here a child page it's going to be about company and maybe about career we can create these child Pages easily because app rer allows us to create nastad folders so I'm going to come here let's move them and I'm going to create my child folders about and Company about and career but what if our page names are Dynamic for example in the block page when we create any blog post the post names will be like blog and the ID of the post or the slack name like that let's create one more and it's going to be let's say another post so these names are Dynamic we cannot create here a folder because they come from the database and we don't know the names it's really easy to create Dynamic routes the only thing I should do is create here a new folder and I'm going to write my Dynamic route name inside a square brackets it can be ID or slug or whatever you want but we are using here slack so I will say slack Dynamic route so whenever we visit our domain name slash blog slash the post name the next JZ is going to run this page so even if we try to visit a post that doesn't exist this page is going to run and we will try to find the post using this slack if it doesn't exist we are going to return the not found page but I'm going to explain this later basically this is the main structure of the app R so let's see which Pages we are going to create this is our homepage we will have the about page contact page we are going to have our posts and we can see our single posts so this title will be dynamic so let's create our Pages I'm going to open up my application and I will say homepage because page. jsx is inside the app directory let's create other folders about and I'm going to create page do jsx let's create our function if you don't know how I'm using this shortcut you can watch my vscode video I explain there how to use your own cipit and the page name will be about page so I'm going to copy this folder and let's create two more times and it's going to be contact page I'm going to change the p jsx and it's going to be block page and remember inside block we are going to have a dynamic route to do that I'm going to be using Square parentheses and inside let's say slack because it's going to be the post title and inside again page do jsx let's say single post page let's see this is our homepage I will say about perfect contact Blog Page and we are going to have our posts let's say Title One okay let's try another one and it works so what else we have we are going to have an admin page and if we are not logged in we'll be able to visit the login page let's create them also I'll create two more folders here and it's going to be admin and login page but let's assume that we are going to have a register page or let's say forgot password page so these three pages are related to authentication in this kind of application it's not hard to find them because we don't have many pages but imagine you have 20 Pages 30 pages and you want to make some changes on your authentication Pages like login register or forgot password and in that situation it's hard to find them to prevent this there is an awesome feature we can actually group our pages to do that I'm going to come here and I'm going to be using parentheses and inside let's say off and I can move my folders inside this folder let's choose them and move it here and right now it's much easier to find our Pages moreover it's not going to count this as a route so we don't have to use this name because normally remember we are using nested routes like that but we don't have to write here the group name and let's say login page as you can see it's not found because it's a group name we can directly call our login page like that okay we don't have those pages but anyway it can stay like that and right now we can create our first component and it's going to be the NB bar let's open up our app as you can see we have nowb bar here but if I visit the contact page about page or the homepage this NB bar is still here and this footer so instead of creating our components and using them for every single Pages we can use our layout let's open up our app and I'm going to close those pages so we can see better and as you can see inside app directory we have layout. JS and this is our main layout which means whatever I write inside this layout let's say H1 tag this is the main layout so this H1 tag is going to show up for each Pages Let's test I'm going to save as you can see login page contact page homepage and it all always stays here only our content changes and this content is this children basically it represents all the pages but this H1 tag will be the common item as I said this is the main layout but also you can create different layouts for example let's come here or let's say block and I'm going to create new layout JS or jsx let's create our component I will say say block layout or whatever you call and we are going to take the children let's say h2 tag this is the blog layout and after the children let's open up our blog page as you can see it's here and also if I open up a single post page as you can can see it's still here but if I visit different pages like contact it's not going to be here this is how we can use common components using layouts but even if you don't have any common component the layout has to be here okay instead of this H1 tag let's create our nabar I'm going to delete this layout and this H1 tag and I'm going to create my first component and it's going to be Nar in the documentation of nextjs let's come here and choose learn nextjs and inside this official example it uses only app directory but I prefer using Source directory also because in my opinion app directory should include only routes only our pages and API routes nothing else because if you create here a component folder and write all the components inside it's going to be so confusing to find your components and pages and in this example it also uses the libraries authentication configuration basically everything inside this app folder but I highly highly recommend to use SSE folder and move your components and libraries or any other files inside this Source directory and leave only your pages and their Styles inside this app directory of course there is not a certain rule you can do whatever you want but I prefer using it like that if you watch my previous dashboard tutorial I used only app directory it was not a good experience for me I always struggle finding my files and folders I think this is the best option okay inside components let's create Nar and ne. jsx be careful here I'm not using page. jsx because it's a component not a page I will create my component it's going to be now and inside my layout I'm going to use this NE and as you can see this is how we are using this add sign it basically says go to the source folder find the components folder and inside Nar so I can do the same thing for the footer component and footer and I'm going to use it after this children so we are going to see number our content and footer let's see perfect let's open up the homepage and awesome and I also prefer using folders you can directly write your components inside this folder without creating any folder but I prefer this because we can need any sub component and also we are going to write our Styles inside this folder but even if you use Tailwind I highly recommend you create a folder because as I said we are going to need a sub component for example in this nowb bar okay so I'm going to close everything here and let's open up nowar let's see our app we are going to have a logo here and our links by the way I'm going to give here a background color I know some of you watch this video at night and your eyes hurt but don't worry just hold on I'm going to give a background when I show you styling l so inside nowb bar I'm going to create a d and it's going to be our logo and one more D and it's going to be our links let's create our first link here to do that we are going to be using nextjs link component normally we are using an anchor tag but when using a nextjs we don't need that we are going to be using the link component as you can see it comes from next link we will give again HRA and here let's say about page another one let's say contact we are going to have our homepage here let's see okay they are here using the link component is important because it fetches our Pages before we click those links so when I come here even if I don't click it's going to fetch the contact page so when I click on this link I will be able to see my contact page without waiting okay right now instead of writing our links one by one I can create here A Links array and inside I can pass my links actually let's create a sub component here I will say links links. jsx I'm going to create my my component and here I will create my array as you can see each link has a title and path so I can use them here I will say links. map and for each link I will call nextjs link and I'm going to write here my title is going to be link. tile and I'm going to give HRA and it's going to be link. path as you can see there is a warning here it comes from es lint and it says you are missing the uni key so if you are using a map here you have to create a unique key since our titles and paths are unique we can use any of them doesn't matter let's say link. tile okay let's use this component here I will say links and perfect our links are here oops in this example it's posts but I created Blog Page remember so I'm going to quickly change here or you can change this name and that's all I'm going to delete this link we don't need this anymore let's click again and it works so before giving any style let me show you what other layouts we can use we can use a loing layout for example inside F folder I will say loading. jsx let's create our component it's going to be loading basically when we switch between our pages instead of seeing a blank white page firstly we are going to see this loading component this layout and after loading our components we are going to see our page of course in this example we are not going to see that because it's too fast but if I open up my console and choose Network here and slow down my connection let's try to open homepage as you can see loading first and after our page and it provides a better user experience and increases our website performance and again as we created our custom layout you can create your custom loading layout for each page just create your loading jsx inside your page and what else we have an error layout error. jsx so if we ENC come an error we are going to see this layout but as you can see there's a problem here because error JS must be a client component I'm going to explain what the client and server components are but for now just don't worry about this and write this use client directive on the top of the file of course inside code and right now if we encounter any error we are going to see this error page for example inside the home page I will just say Throw new error and error in home for example in this case we will not be able to return anything and as you can see this is our nbar footer and between we have the error layout in this example of course we are not going to encounter an error because we are not fetching any data or we are not doing anything that can cause any error but when we create our database connection and fatch our blog posts you are going to see how useful to use this error layout and one more thing I want to mention if I write here any other page that doesn't exist let's say test as you can see it shows us this default 404 page but if you want to you can change here again inside app directory I will say not. jsx again I'm going to create my component and let's say not font and let's write here something h2 tag not found P tag let's write this text and after I will say a link nextjs link and I will say return home and the H will be our homepage as you can see it's here so if you try to reach any non-existing page it's going to show this not found layout so you can return to home or refresh the page okay guys layouts are like that I'm going to close everything and let me show you how you can style your component and Pages as you can see we have a global CSS here basically we are going to add here our common Styles let's give a background color I will say budy and background color let's say black and since we are using this CSS file inside our layout this is the default import I didn't add this here it's going to apply for every single page let's see as you can see home page contact page or any others so what common Styles we are going to need we can for example change the text color I'll say color white as you can see there is a default style for our anchor tags our links to prevent this and I'm going to choose all these links and I'm going to delete the text decoration it's going to be nonone and the color will be inherit basically this color will be inherited from the parent in this case it's going to be white like that so instead of writing our colors like that let's create our variables to do that I'm going to be using the root and inside I will Define my variables first one will be background it's going to be this color and the text color will be white so right now I can use my variables here and I'm going to choose the BG I will do the same thing here it's going to be text so I can create other variables I'm going to paste them here we don't have to waste time as you can see additionally we have the soft background the soft text color is going to be this grayish color and a button color so we can use all these variables in any component or page because it's the parent CSS as you can see there is a space on the left and top to prevent this I'm going to choose the universal selector I will say margin zero pading zero and Border sizing will be border box in this case we are not going to have any default margin or padding by the way if you don't know what the root is why we are using this selector why we are using our colors inside body I highly recommend you watch my previous CSS video there are some awesome CSS tips and tricks if you are interested it will be in the card on the top right okay right right now to give a responsiveness I'm going to wrap my layout with a class name and change the size of that container let's check here I'm going to open my console as you can see our page is responsive if I make it larger we can see our image here and this is how we are changing our container size you are going to understand better right now I'm going to open up layout and after buddy I'm going to create a de R my items and the class name will be container let's use it here firstly I'm going to give a background and see whether it works or not okay perfect right now I'm going to give a large size and I'm going to Center my container inside this body so let's say with 15 36 pixels and I will say margin Auto it's centered on the body and its size is smaller and also I want to give padding on the left and right padding left let's say 50 pixels and write okay okay right now I want to give a minimum height so it can contain all our screen here I will say minimum height will be 100 VH so it's going to fit inside our view part and I will separate my items the naar will be on the top the footer will be on the bottom and our content will be on the center to do that we can use flex box but if I do that our items will will be horizontal to prevent this Flex direction will be column right now they are vertical and I'm going to separate my items to do that I will use justify content and it's going to be space between okay this is what I want I'm going to give the responsiveness but before let me show you how you can give a style for your pages and components because we are not going to write everything inside This Global CSS let me delete this background color and I'm going to open up my naar here and I will say class name and let's say container and I'm going to create my own CSS file here nebar do CSS and let's say container and background color is going to be let's say blue let's import this CSS here import from now bar. CSS of course not from we are not importing any function or something let's check and as you can see there is something wrong by the way I'm going to change this color it's a torturing to see this color okay it can stay like that as you can see all our container is blue if I open up my Global CSS and change this background color there is a conflict here because we are using exactly the same class name it's a container and this is a container so if you are using CSS you will most probably see this kind of bugs but thanks to nextjs we are able to use module CSS what I mean by that instead of naar CSS I'm going to change the name and I will say nar module. CSS let's change our import and this module includes our Styles import styles from nowbar module right now instead of writing class name like that I will just say styles. container let's see right now and perfect this is our main container and this is the nbar container if you right click and say inspect as you can see this is our main container and our module style changes the name of the class name it's not container anymore it's this random generated class name this is how we can prevent any possible conflicts so you don't have to write different class name for your HTML items of course if you are using Tailwind you can directly give your style class names you don't have to worry about CSS files but there is something important here if you are using Tailwind you will create your Styles easily it's going to be so fast but if you want to make some changes it will be really hard to change your class names because sometimes we are going to have a really long class name even maybe two lines so even if you try to make a little change it's going to be so hard to find the related class name so in large projects I prefer using a pure CSS but if you are creating something quick of course you can use Tailwind CSS but as I said it's not our concern for this tutorial we are not going to focus on designing I just want to show you styling in nextjs okay let's delete this and here and should I copy paste all these Styles or I don't know because I know some people want to see every little steps okay let's do this quickly I'm not going to waste too much time but I'm going to show the steps if you want to you can skip this section you can find the time stamps on the video player if you don't want to see the design part just skip to next part and for others let's take care of this number firstly I'm going to give here a height and I will say display Flex so my items will be horizontal and let's Center this vertically align items Center and I'm going to separate my items remember how we did here just why content space between okay I'm going to increase this logo size I will say class name styles do logo logo so let's come here I'm going to increase the font size and font weight will be bolt okay let's separate those items again it's going to be display Flags but I'm going to give a gap between them to do that I'm going to open up my links and inside this folder I'm going to create links. module. CSS I will say display Flex align item Center and I'm going to give gap between my items it's going to be 10 pixels let's check our example here as you can see we don't have any class name styles. links let's import this quickly not F CSS we are using just CSS and perfect but there is something important here in our example as you can see when we are on the contact page we have a different style here when I click on about it changes this background so basically using this link we are going to change the style of our links to do that instead of writing all those links in one file I'm going to create another component here and it's going to be mear link jsx and CSS I'm going to create my component using the CSS file as you can see this is another snipet I'm using as I said you can find it in the previous res code video and basically this is going to be a single link so we are going to need our link item remember we have links here right now instead of calling this link I'm going to call my component now bar link and I'm going to pass here my item is going to be this link and again the unit key let's paste our link here I'm going to import right now I'm going to change this name it's going to item I'm going to delete here okay let's write here our class name styles. container but also if we are in the same page we are going to change the class name is going to be active to do that let's copy this and use back Tex and I will say use the container class name additionally if the path name is the title of our link right here active so we are going to need a condition here but how we are going to reach to this path name to do that we are going to need a use path name hook I will say path name use path name hook it comes from next navigation so using this name I can write here my condition if path name equals our item title it's going to be styles. active as you can see if you are using next navigation hook doesn't matter which one it can be use path name use rouer if you are using a hook it has to be a client component and again don't worry about this for now I'm going to explain after giving Styles and let's open up our CSS and I will say minimum width will be 100 pixels I'm going to give some padding Insight I'm going to change the Border radius is going to be 20 pixels and let's say front weight 500 and I'm going to Center my Tex inside this container and if it's active the background color will be text color the color will be background color the background will be white okay there's something wrong class name is Styles container and path name item title it's not going to be title it's going to be path because this path name includes this slash and the path name not title and as you can see our active class is here if I click here perfect it works this is how we can give active classes so I'm going to add two more items here in our example as you can see we have the admin and the log out button but if we are not the admin we shouldn't see this admin link and if we are not authenticated we shouldn't see this log out button instead we should show the login page of course we haven't implemented the authentication but we can write a temporary data here inside links I will say const user or user session let's say session and for now I will say true and again one more is going to be is admin and let's say true again let's say here temporary we are going to change here and I'm going to write a condition here firstly I'm going to check if we are logged in or not I will say if there is a session show something if not authenticated show something else so if we are not authenticated I'm going to call my now link component and I'm going to pass my item and it's going to be title login and the path will be login and if we are authenticated we need to check one more thing is admin because if it's admin we are going to see this link if not we are not going to see it so one more condition here if is admin again now link title will be admin path will will be admin and also I'm going to write here a button that we can log out and of course if you are using multiple items you should drop them with a parent let's use react fragments like that again if we are authenticated we are going to see this logout button and if we are an admin we are going to see this link and if there is no user we are going to see this login link let's check as you can see admin and log out if it's not admin we are not going to see that link and if we are not authenticated it's going to be the login link here okay let's take them back and give a style as you can see we have some padding here and I'm going to change the size let's say class name and it's going to be log out heading will be 10 pixels cursor pointer so we can click font we will be bolt okay it's not here by the way let's delete this class name oh I said log out directly I didn't use my Styles okay awesome so what about the responsive menu let's open up the console and when I shrink the page as you can see there is a responsive button here when I I click we can see our links and after this break point here we are going to remove that menu we are going to see our links here to do that we are going to be using media query but before let's create our responsive menu but first i'm going to create a use State hook and I'll will say const open set open and at the beginning it's going to be false let's import by the way let's move our links here before this component okay so at the beginning our menu will be closed but when I click here we are going to set our state and it's going to be true of course we are using a click event here so if you are using any user interaction your component should be a client component again I'm going to explain in detail but for now just notice if you need an user interaction the component should be a client component remember how we are doing this at the top of the file I will just say use client so let's show our responsive menu here but before I'm going to create a new D and the class name will be container and after those links I will create a button let's say menu of course later we are going to be using this image but I didn't explain how to use images it can stay like that for now and after that I'm going to check if the menu is open or not if if it is I'm going to create a d here and let's say mobile links and inside again I'm going to be using my links and for each link I'm going to call my Now link and the item will be link and again if you are using map don't forget your uni key link do Title One bracket is Miss in here okay as you can see we have manyu button here when I click on this button on click event I'm going to set my state set open and I'm going to take the previous value and write the opposite of this value if it's true it's going to be false if it's false it's going to be true when I click as you can see our items are here when I click again it's going to be closed okay so let's give a style for them the position of our links will be absolute so we can see it on the right let's check as you can see it starts from here after this NAB bar and the right position is zero it sticks to right side let's do that I'm going to open up my links mobile links there is some auto complete here let's complete and see Position will be absolute top will be 100 pixels remember our NE bar is 100 it says left but it's going to be right the width will be 50% it's not going to contain all the screen and the height will be 100 VH but remember it starts after 100 pixels so we have to calculate this this so I'm going to say 100 VH minus 100 pixels it's going to be display flags flag Direction column so it's going to be vertical and we are centering our items here and gap between each item is 10 pixels so we don't need this and this I'm going to open and as you can see it's here of course the background color is exactly the same let's change it for now okay perfect of course for this large screen we are not going to see this menu button or this menu we are going to see it only when it's on the small screen so let's use our media queries I will say media and the maximum width will be 768 pixels and in this case our links will be disappeared we are going to see our links here but in this backo we are going to remove them instead we are going to see this menu button and mobile links so at the beginning they are going to be display n but at this point they are going to be visible so I'm going to copy this and paste it here and if it's not the small screen display will be not I will do the same thing for the button did I give class name or not okay I didn't let's say class name styles do menu button and again display n actually I can write it directly here they are going to be we display on and at this point we will be able to see our button let's say display block cursor pointer okay they are not here we can see our links when I shrink the page our menu is here but as you can see it's overflowing because remember our container size is really big let's open up the global CSS as you can see 1536 so we have to give responsiveness for this container first this is the default value so let's add our first media query if the maximum width is 1536 pixels the container size will be let's make this bigger actually 366 pixels and for smaller screen if it's at this point it's going to be smaller and for this point 1024 and for 1024 768 those are common CSS break points you don't have to memorize anything just Google for CSS breakpoints and you are going to see those numbers and for this screen size 640 and finally for this size 475 okay if you remember we have some padding left and right right and maybe at this point I can decrease those numbers it's going to be 20 as you can see we don't have any problem anymore when I click on this button we are going to see our menu here and if I make this screen larger it disappears and we see our links here okay right now we can take care of our homepage but before let me show you how we can add images before using nextjs image I want to upload those images to my public folder I'm going to come here and open up the public folder and I'm just going to drag and drop my images here you can find them on the GitHub repository so let's try to use this image inside inside our about page I'm going to close everything and open up the about page if you are not using nextjs we show our images using the image tag let's self close this and I'm just going to write here Source I'm going to choose the public folder using slash and about.png I will save I'm going to open up about page and it's here if I right click and open the image in new tab as you can see Local Host about. PNG so it's not changing anything but if we check our code you're going to see here a warning and it says using image tag called result in slower LCP and higher bandwidth because we are not optimizing our images but as it says it might cause some performance issues to prevent this we are going to be using nextjs image as you can see it comes from next image and again we'll write here our source it's exactly the same about do PNG we can pass here and ALT tag if you leave it like that you are going to have a problem because we didn't provide any size if you are using nextjs image you have two options first one is giving here any image size let's say 500 pixels height 500 pixels as you can see there is no problem anymore and our image is here and if you check the image right click and open image in new tab you are going to see that this is not our URL our image is inside underscore next folder and if you remember this folder includes our cached files basically next Jaz is not showing our images directly instead it's caching it first and optimizing it for different secen sizes as you can see quality is 75% and this image is much smaller than the image that we uploaded and let me show you one more thing I'm going to close this menu and as I said you have two options you can give your sizes directly or you can create here a container image container I will say do image container and I'm going to wrap my image of course we are going to need a CSS file about do module. CSS that's call call it here about do module CSS and styles okay right now since we have an image container instead of writing here a specific size we can just say fill so it's going to fill inside this image container but there is something important here if you are using a parent div a container its position should be Rel relative so I will say image container position relative and you should give here a specific size so let's say with 100% height 500 for example I forgot adding my path let's add quickly our image is here when I open up my console and refresh the page and open open up my image here you can see that its width is much smaller but if my screen is bigger let's refresh again and open up and right now the size is much bigger basically next Jaz is optimizing our images according to device screen size so you don't have to worry about optimizing your images adding different images for each screen size it's one of my favorite features let's close them of course we are not going to use it like that our example will be like this first we are going to have a container here then our image and it's going to fit inside its container its parent but what about we want to add some external images let's open up heel.com and I'm going to choose this image for example and I'm going to paste it here let's come back and as you can see there is an error let's check and it says invalid Source prop because next ja doesn't allow us to use any external image URL so we cannot use any domain here we are allowed to use only Local Host 3000 which is our domain so I'm going to open my configuration and inside this object I will say images remote patterns and it's going to be an array and inside this array you can add your domains but also you can add additional configuration like protocol is going to be only h https connection and the host name will be the URL of image PEX house.com if you want to you can add multiple domains like that I'm going to save and let's refresh and as you can see there is no error but we can't see our image because I edit here directly URL the page URL it has to be the image URL like that in this case the URL will be images. pexels.com let's fix it and let's check again I'm going to refresh and it's here this is how we are using external images and if I check the image again it's going to be in this folder and our image is cached right now okay let's close here and here and let's take care of our design and after you will learn what the server component is what is the difference between client and server component but for now I want to design my website first let's come here and check the homepage as you can see we have two sections here those texts and this image by the way I'm going to make this a link I will open up the nowb bar and let's say link HRA and the homepage okay inside this container let's create two sections text and image let's close everything and open up our homepage I will close my menu and I will say class name styles. container let's import our style let's create our CSS file home do module. CSS I will say container and let's import this import styles from home module okay inside this container I'm going to create two more Dives let's say text container and image container inside this text we have title description two buttons and this image so let's say H1 tag I'm just going to copy this P tag I'm going to create a du that contains our buttons learn more and contact styles. button and one more and it's going to be contact and finally one more do and let's say Brands it's going to be our image container so I will say next image source will be brands. PNG I will write here a description it can be empty and I will say fil and let's give a class name styles. brand let's say brand image and finally this image inside this container I will say hero PNG again fill the class name will be hero image let's check our image here I'm not sure if it's hero or not okay it's test let's change this and that's all let's give a style I'm going to move my CSS file here and let's start with the container it's going to be horizontal display flex and gap between text container and image container will be by the way there is something wrong okay I forgot adding here a slash and here also by the way it's going to be a GI okay it's here let's separate our items text container and image container remember we are using an image so I will say position relative and their size will be equal and since we are using Flex box I can say Flex one flx one so half of the container will be text container and the other half will be image container let's change here image container like that what about here let's give a size and again Position will be relative okay but I want to change this color it's going to be this gray color to do that you don't have to change your image basically just give here a filter and the effect will be gray scale and it's going to be 100% which is one as you can see right now it's black and white perfect so let's come here and take care of those items I will say display flag flx direction will be column it's going to be vertical and gap between items will be 50 pixels like that let's increase this size I'm going to give CL class name title uh for the description let's write them here I will say phone size is 96 pixels and for the description it's going to be 20 okay what about those items again it's going to be display flags and I'm going to separate them let's say 20 pixels and for each button I'm going to give some padding minimum width 120 pixels we can click so I will say cursor pointer I'm going to delete the default border it's going to be nonone and the Border radius will be 5 pixels like that but as you realize this color is different we can use our button variable so I'm going to choose the first child I'll say button first child and the background color will be variable and button and the text color will will be variable and text so it's going to be white okay background color is not here I'm going to open up Global CSS oh because of the call plot and perfect so what about this footer we didn't add here anything as you can see only our logo and this text I'm going to copy this and close here and let's open up footer styles. container Styles another do is going to be logo and text I'm going to paste it here and it's going to be my logo let's import our style did we create this or not let's check okay we don't have let's create quickly and I will say container okay again display flxs and we will separate our items just why cont space between but as you can see this size is bigger but in our example we didn't give any size so it's going to be 100 pixels I will say align item Center by the way we can Center them vertically and finally the color will be gray and for the logo font weight will be bolt and for text font size will be smaller just like this awesome so let's check here as you can see it's exactly the same I'm going to open up the about page and we are going to do exactly the same thing here text container image container and we are going to have some texts like this title bigger title description and those items let's do that quickly I'm going to close them and open up my about page and I will take my CSS let's delete this and give here a class name styles. container and again text container image container and inside text let's say h2 tag I'll just copy and paste them at P tag and for those items I'm going to create another D let's say boxes and we are going to have three different box let's create one of them and after I'm just going to duplicate we are going to have here a number let's say H1 tag again and a P tag and I'm going to paste and in the right side I will say image I'm going to say fill and the source will be about do PNG let's delete here here let's give a style I'm going to delete this and I'll will say container again Flex One display flag and gap between items it's exactly the same and for image container Flex will be one awesome let's give class name for our items and after give our style styles do subtitle I'm just going to copy this it's going to be title and description okay the title will be 54 pixels I'm going to change the subtitle text color and it's going to be our blue color so I will say variable and button and for the description font size will be 20 pixels and font weight will be 300 it's going to be thiner like that and what about here let's create two more boxes firstly they are going to be horizontal and I'm going to separate them and after I'm going to change the color of this text I will say boxes display Flex align item Center and just F content space between just like that let's change this color and give space between this text and this one so I'm going to choose box it's going to be vertical and let's give a gap and I'm going to choose the title which is H1 tag and the text color will be our blue color I'm going to save and Awesome by the way this image doesn't fit inside our container to prevent this I'm just going to give here a class name let's say styles. image and the object fit will be contain okay it's much better and what about the contact page let's check this time our image will be here and for the right side we are going to create a form I'm going to close them and open up my contact page as you can see you don't have any CSS let's create I'm going to copy this right here container and import my file and I'm going to give class name here styles. container okay and in side I will say do image container and form container let's quickly create our image contact.png and fi and here let's create a form I'll say class name is going to be form and inside let's create an input and the placeholder will be let's check name and surname email address phone number and message and after we are going to create this button email address and phone number and let's say optional and I'm going to create here a text area and let's give a placeholder and it's going to be message and finally a button that says sent okay let's open up our CSS module and as always display flx and gap between items I'm going to give Flex for image container and the form container and Position will be relative for our form but before where is our image let's give class name and it's going to be styles. image and again object fit will be contained and for our form Flex direction will be vertical and gap between items let's give semicolon and try again okay and I'm going to choose my form input and also form text area I'm just going to give some padding let say 20 Border radius five let's delete this border I will say nonone I'm going to change the background color it's going to be BG soft and the color will be the Tex color okay I didn't close this image tag and now there is something else about our UR URL okay okay they look nice but we don't have our image oh because we are using our image container on the left side when you use it on the right side it automatically assigns a height for this because the left side has a height here and the right side automatically takes this size but in this case since it's the first item we have to provide here a height so let's say 500 for example okay awesome what about this button I will see form and button padding 20 background color will be the blue color and the color will be the text color font we will be Bolt I'm going to delete the border border radius will be five pixels and cursor pointer okay so what about this Blog Page let's see it includes our blog posts so for each card each post card I can create different react component so let's create that component I will close them open up my menu and in side components I will say post card let's create our jsx file and the CSS file I will say container and create my component here let's open up our blog page I'm going to close them and open up block and here I will say class name styles do container I'm going to create my CSS file block. module. CSS and I'm going to import it here just like that and inside I'm going to call my component postcard actually let's call four of them just like this and each card has two sections this top section and this bottom section in the top section we are going to have our image and this date and in the bottom section we have title description and this link let's create inside postcard let's close this menu I will say class name Styles dot container postard module. CSS let's say d top bottom and inside top I will say do an image container and we are going to have an image here just like that let's import this image from next image and after this container we are just going to create a span and it's going to be our date let's give any date here just like that and I'm going to give class name styles. date and for the bottom let's create our items H1 title ptag description and a link read more let's give class name title and description okay let's open up our CSS and let's give our style firstly it's going to be vertical top and bottom and gap between items will be 20 pixels and also I'm going to give margin between each item as you can see there's a space here so let's say margin bottom 20 pixels and for the top element display will be flag because they are going to be horizontal and let's give a size for this Con container image container let's say 90% And the 10% will be this date height will be 400 and again position relative and for this image let's give our object fit and it's going to be cover and for this date f size will be small and as you realize we have a transform here it's 270° it's not horizontal to do that I'm going to be using transform rotate and it's going to be 270° let's check okay we don't have any image so let me open open up pexel again and choose this image and I'm going to paste it here remember we can use images. pexels.com and as you realize our items are vertical but in this example our items are horizontal and if it overflows this container moves that item to other line like this one to do that we can use flex box and flax drop let's open up our block module and I will say display flx and flex Dr will be rra let's give space between items and for each item I can give specific width let's open up our page and for each card I'm going to give a container and let's say post let's remove them and duplicate like that and for each post let's say 30% so we will have only three items per line just like this if I say say 20% we are going to have four items if I say 50% we are going to see one item because remember we have a space here but if I say something like 40% as you can see two items it works like that so for different screen sizes we can give different size let's copy this and I'm going to use my media query for this this size for example it's going to be 100% but if the screen is bigger let's say 1280 pixels it's going to be 45% so we will see two items let's see I'm going to open my console and I will shrink as you can see two items if I shrink more it's going to be one perfect but as you can see this date is on the center I will say margin Auto perfect and what about this title phone size 24 pixels and margin button will be 20 pixels just like that for the description again margin bottom font weight will be thinner and the color will be gray okay awesome but if I add something longer let's use random generat text here as you can see it ends here maybe I can make this 90% also so it will stay here just like that it's much better right now maybe I can do the same thing for title if it's long it's not going to overflow okay and for this text maybe I can give underline so I'm going to choose this link styles do link I will say text decoration and it's going to be underline just like this and what about the the single post page let's check I'm going to click here again two sections inage and our content let's do that I will close them and open up what was the name okay single post page and single post module. CSS import Styles single pa module CSS of course from okay let's use it here styles. container and inside let me close this menu I will say image container and text container and inside this image let's say nextjs image again I will use my image let's open up postcard and copy this just like that a description and I will say fill and inside text container we will have a title of course all those items will be dynamic but for now for the design purpose we can add here whatever we want class name will be styles do title and after this title we are going to have a div here which contains this user image its name and the date let's do that I'll say do and I'm going to say detail again we will have an image let's copy this and the class name will be let's say Avatar or user image whatever you say and for this image Styles Dot image it's going to be the main image let's create one more du and it's going to be detail text for example we are going to have two spans the first one will be let's say detail title and detail let's say value and the first one will be title author value is this username and I'm going to create one more and it's going to be published and a DAT here let's give a test date and finally this description after this detail I'm going to create a Content de and let's say a random sentence okay let's give our style again I'm going to separate my items but as you can see image size is smaller than this content this text container so it's not going to be Flex One Flex one it's going to be much smaller so let's take this here let's give our Flex box as we always do image container Flex will be one but for the text container Flex will be two let's give position relative and I want to make this image full screen of course we have to calculate this nowar and this footer let's give semicolon here and say height I'm going to say calculate it's going to be 100 VH minus 200 pixels because 100 + 100 is 200 pixels and let's separate our texts gap between items will be 50 pixels uh for title phone size will be 64 pixels and for detail again display flag Flex direction will be column and gap between items will be 10 pixels let's check okay there's something wrong image container it looks okay but object with col but it didn't recognize our size Let's test oh it might be because of this AAR after detail I'm going to say AAR again object pit C and I will say border radius 50% because it's going to be a circle and I can give with and height here instead of this field it's going to be 50 pixels oh okay it works so let's take this back okay perfect let's separate our items where is our text container okay we already separated but I didn't say display flx okay and for these details I will give display flag but it's going to be horizontal so I mix these details and this text container it's going to be Flex Direction column and it's going to be only Flex box and let's see 20 pixels awesome and for those texts again I will say display flex but this time it's going to be vertical let's check detailed text and gap between each item will be 10 pixels and for this title color will be gray and font weight will be bolt and for this one font weight will be a little bit thicker but not bolt finally for this content and I'm going to increase the font size let's say 20 pixels I'm going to save okay perfect so let's take care of our responsive design and after that we can end the design part let's start with this page I'm going to open up my console and if the screen is small I'm going to remove this image media maximum width 768 pixels and in this case I'm going to delete this image container just like that but as you can see this footer is overflowing I'm going to copy here and open up footer if it's this size the container will be flx Direction column and I'm going to Center my I items and let's change this space it was space between but this time it's going to be space around okay it's much better but it's still overflowing let's check our NB bar I will close them and open up my layout and I'm going to remove this NAB bar and as you can see NAB bar is is not the problem so I will take this back and let's open up our Global CSS as you can see we didn't use this break point let's use and it's going to be let's say 380 pixels by the way I'm going to change this button let's open up nowb bar and Link and instead of this button I will say image source will be menu. PNG let's give some size it's going to be 30 pixels and again I'm going to use this on click event I'm going to delete this okay it's not here here let's check our image okay I forgot adding my menu here let's add menu.png here let's use it I'm going to refresh and it's here okay let's delete this Background by the way I'm going to remove this and for this image styles do menu button right now I can click perfect for this page everything is okay what about Blog Page we already tested this that there is nothing wrong contact as you can see it's always horizontal and our image is getting smaller to prevent this after a certain break point I can make this container vertical so let's take this open up our contact page I mean CSS and before this point the container will be vertical I will just copy this open up about and paste it here okay and for those boxes again direction will be column cap between items will be 50 pixels and text align will be Center just like that actually I can Center everything here just like that and for the homepage again it's going to be vertical let me copy this and open up homepage let's actually make this bigger it's going to be column let's remove that and if it's smaller I'm going to decrease the title size title font size 64 pixels and Brands will be 100% and again I can Center them and and those items let's check them first I will say red background as you can see they are not centered so I will say justify content Center awesome I can delete this okay I don't want to waste your time I was not going to do any design part but anyway when I skip any parts I don't feel satisfied because I know some people are still looking for the design part so it was a good idea to not skip so right now let's see how to render components in nextjs there are two types of rendering the first one is server site rendering and the second one is the client s side rendering before single page app libraries and Frameworks like react the traditional method was the server site rendering let's create our user the user browser and our server so when a user tries to visit a web page let's say L.D slab page after entering this URL the browser page is empty it will show a blank page and our server takes this request let's do the same thing for the client side rendering because this process is the same we are sending a user request let's move this here and for the server site rendering after getting to request our server renders this page creates an HTML file and sends that file to the user browser so this browser receives our rendered HTML file and in this case the user is able to see this page immediately so right now our page is viewable but this initial page is not interactive because it's just an HTML file if there is something interactive like event listeners animations or whatever the browser has to download the JavaScript files but it's only for the interactivity what about this client s side rendering after receiving the request our server sends an empty HTML file there is nothing inside this file and also the whole JavaScript bundle that will build our web application from scratch let's say amp the HTML and the JavaScript bundle in this case the user browser has to render this page not the server and now we still see this white page because we have to wait until the page is rendered of course I'm talking about just a few seconds and mostly even less but anyway the initial load is slower and after rendering the page the page is viewable and also interactive so here we are waiting for the interactivity but here as soon as the page is ready we can interact with it so we each one we should choose let's write cons and pros and after you are going to learn how rendering Works in next JS I'm going to write the pros first firstly the initial page load is faster because remember we can see our page immediately we don't have to wait for anything and since everything happens on the server site it's better for old devices and slow internet connection and the other one server site rendering is better for SEO because the server response is an HTML file and the content is ready to read but what about cons firstly if you are using server s side rendering you have less interaction and you will have more server loads because for every single request we have to render on the server and it causes the slower subsequent page loads and one more thing I want to add here and it's hard to manage our states State Management complexity what about client side rendering okay our initial load is slower but once we create our single web application it's much faster to navigate between Pages after initial load and since we are using the user browser we are going to have a l server load so it's going to be much cheaper and the client side rendering is best for the user interactivity and it can affect our SEO we are going to have slower initial loads and our application depends on the client resources so if you have a huge app all devices might have some problems in react the default approach is rendering application on the client but next she has using the server site rendering when you create a page or component they all are server rendered by default but what if we need to add some interactivity click events interactive charts react hooks so let's create here a website and by default it's a server component let's say server component and the blue is client component right now I'm going to create some components like a nowar by default it's a server component let's make this smaller we can have a sidebar chart the content and we can maybe have here a log out button and something interactive here so let's say nowbar sidebar chart component our post details a log out button and something should render it on the client side so these components will be client side components in next JS we can combine our server and client components like that and it's so easy to do that the the only thing I should do is write use client directive on the top of the client components and after this directive we can use react Hooks and we can interact with the user and this structure gives us an incredible flexibility but we have to be careful here because during this hydration we might have some problems so let's give some real examples and try to understand the rendering and the hydration okay let's prove that all our next ja components work on the server site I'm going to open up the contact page and here I will just console log and I will say it works here let's open up our terminal and as you can see it works on the server site if I open up my console on the browser as you can see there is nothing here if I refresh the page okay since everything works on the server we cannot interact with the user we cannot use the click event we cannot use on change event or we cannot use the browser local storage basically we cannot reach anything that browser allows us to do if you want to interact with a user your component should be a client side component to do that I'm going to come here at the top of the file and I will say use client directive and right now as you can see it's initially rendered on the server but if I open up my console on the browser as you can see it works here right now I can use my event listeners or local storage so if I come here and say for example on click event and console log clicked of course it's refreshing the page because it's inside a form and the default behavior is refreshing the page remember to prevent this we are using event do prevent default but anyway this is just an example if you want to use any event you have to change your component into a client side component and as I mentioned even if we right here use clients the initial render will be on the server site this is important because you will most probably encounter hydration problems because nextjs checks your component on the server site first and it expects that you have the same component on the client site what I mean by that if I write here const a equals let's say one and I will say console log one sorry a if I refresh the page we are going to see our number here and also here we don't have any problem because this component is exactly the same on the client and server site but if I come here and say use the math library and generate a random number I will refresh the page it's 0.70 but here as you can see it's 0.6 so they don't equal if I try to use this variable somewhere here let's say before this form I'm going to refresh the page and as you can see there is a hydration problem because in our component we are rendering 0.27 here and on the server it's 0.72 and nextjs warns us that the text content does not match server R HTML so how we are going to prevent this error because it's a really common error I saw many people ask this question on our social media accounts so to prevent this we have three Solutions the first one is using a US fact hook so during the hydration we can call the use fact hook and make sure that our component runs on the client side let me show you what I mean I will come here and say use effect and it's going to run on the initial render and here I will make sure that my component runs on the client site to do that I can use a use State hook here const is client set is client and at the beginning it's false because it's going to run on the server first and when I run this user effect I will set my state and it's going to be true and using this is client State I can conditionally write this a value I will say if it's client right here a let's move this here I'm going to save and I will refresh and as you can see there is no problem because on the server this is not going to be rendered it's going to be rendered only when it's client this is how you can prevent this or you can and prevent this error by disabling server site rendering on specific components for example if I create here a component hydration test. jsx let's create our component it's going to be a client component use client and I will do exactly the same thing here I will have this variable and I'm going to show it here in this case I don't have to make this component client let's remove them and let's remove here it's just an ordinary component but what I'm going to do is call my hydration test component and in instead of importing this component like this I'm going to use the dynamic import what I mean by that I'm going to comment this out and I will say const hydration test let's say no SSR and I'm going to be using nextjs Dynamic and I'm going to import my component dynamically I will say components hydration test and at the end of the function I'm going to write here SSR false in this case it's going to import this component without using server s side rendering let's call it here of course I should write here import I will save and let's see I'm going to refresh the page as you can see there is no problem we don't have our error here and here this is how you can prevent the hydration problem and one more thing you can do let's commment this out and get our random number from here and let's say use client again and I will write it here but I'm going to R this with an HTML element let's say a do and I will write here suppress hydration warning I will refresh the page and again we don't have any problem and it basically means okay there is a hydration problem but I'm not going to show you on the browser okay this is the most common problem when it comes to rendering nextjs components and let me answer the second most popular question if I wrap my server side component with a client side component is my server side component is going to be a client component or server component the answer is it's still going to be a server component because sometimes we have to rub our components with some client side providers let's create another example here we can have an authentication provider or context API provider and it has to be a client side component let's say test or client site provider test it's going to be a component and we are going to take a react children and we are going to WRA this children with our provider and I want to use this provider in my layout let's drop this container and I'm going to import and I'm going to make this component a client side component let's remove this by the way actually they can just stay here in case of you want to check it on the GitHub repos story I'm going to comment them out so if you need just check the GitHub repository and right now our provider is a client side component and we are wrapping the entire application with this component so let's open up our homepage or about page doesn't matter and I will say console lock let's check where it works I'm going to open my console oops by the way oh okay I did refresh page there is no problem I'm going to click and open my console as you can see there is nothing here I'm going to refresh and we cannot see our text here but if you check the server site you will see that it works on the server site so even if you gra your application or any page or any component with a client side component don't worry they will not be a client side component it's just the upper okay let's comment this out also and here and right now you know how server and client component Works what the hydration is client side and server side components don't affect each other you can combine them so let's learn the nextjs navigation let me create here another page and I will say oops navigation test and I will say page. jsx and create my component navigation test page actually let's make this lower case and let's open up okay the first thing is links I already explained this remember how we are adding link here we are using next link component and inside this link click here and you should provide here any internal or external URL let's say the homepage the default behavior of a link is prefetching the given URL so even if I don't click here it's going to prefetch our homepage and it's going to allow us to see our homepage much faster like that but if you have have many links on your component you might want to disable this prefetching because it might cause some performance issues to do that you can come here and say prefetch and false in this case it's not going to fatch anything sometimes instead of using a link we have to implement some functionalities and after redirect our users to somewhere else so let's create here a button write and redirect and when I click on this button I'm going to call handle click function let's create this function here const handle click and of course if you are using an event your component should be a client side component and here firstly I'm going to write console lock clicked and after redirect my user to the homepage to do that we are going to be using use rou hook so I will come here and say const rouer and use rouer hook and it comes from next navigation don't use the next rouer it's the older version we are going to be using navigation and using this router I can push my user to the homepage I'm going to save open my console and click here as you can see clicked and we are on the homepage let's get back so basically what push does is it performs a client side navigation to the provided route in this case it's homepage but also you can use router replace and in this case it will not add a new entry into the browser history stack what I mean by that let's refresh the page actually let's open up a new tab here if I turn back you are going to see that home page and if I click here it's going to refresh my page if I try to go back as you can see it's not going to go back to the navigation page instead it's going to show my homepage that because we are not adding a new entry to our browser history stack and what else we can use refresh basically it's going to refresh our current route and it's going to make a new request to the server so if you want to refresh your data refresh anything you can use refresh method let's see I'm going to test here I will refresh when I click here it didn't refresh because I added here a URL of course it's going to refresh the current page right now let's try I will click as you can see it reenders my components okay what else you can do you can create here back or forward buttons for example and using back method you can open up the previous page and let's get back using forward you can open up the next page if I click as you can see the homepage okay this is how we can use use router hook as it name implies it's a hook so even if we don't have here any click event your component has to be a client side component because we are using a hook so let's remember how we can use our path name we are using path name and use path name hook let's import again it comes from react navigation and let's see what's inside I'm going to open my console and as you can see it shows me the path name it starts with Slash and if I write here any query let's say test it's not showing my query it shows only my path name but how we are going to reach this query I'll say const query and use search params and I can get any query I want remember in our example it was C so if I say query or let's say search params search param s get C let's write it here I will refresh and as you can see Q is here so you can search for any query you want like sort query like price query anything you want this is how we are using this search params hook but as I said those are for client side components what about about server site components I'm going to write here client site navigation so let's open up our slack page and remember it's a server s side component when we learn how to fetch data we are going to fetch our data from a database so it's better to keep this component as server side component but how I'm going to reach this slack name it's really easy we can directly the structure our perms here and let's see what's inside I'm going to open up my terminal and let's check here A Blog Page this one and as you can see our parameter includes a slack and it writes whatever it comes out after block Local Host blog and post if I say post test and it's here so if I do the same thing for my blog page console log parms let's open up the blog page as you can see it's empty but what about search sech params again you can D structure search params let's write it here it's empty4 now but if I write any query you can see your query here this structure and use it for fetching data or whatever you want okay right now we know how to take our parameters or search queries so let's see how to fetch data in nextjs of course we are going to create our own blog posts and we are going to fatch them using our database but for now for the learning purpose let's use a fake API to do that we are going to be using Json placeholder it's a free fake API for testing Purp purpose if you come here let's check posts it gives the post title buddy and the user ID so using this endpoint let's try to fetch this data on our API I'm going to delete here and I will fetch this data my component should be an Asing component because fetching data is an Asing operation and here let's create a function I will say const get data async I will say const response AIT we are going to fatch from Json placeholder and posts let's correct here and it's going to return as a response and I will check my response here I will say if response is not okay okay if there is an error we can throw new error and say something went wrong and if everything is okay we can send our data of course the data should be a Json so I will say return response. Json so using this function I can retrieve my data so I will say const post await and get data and using those post I can call my postcard so let's delete them I'll say posts do map for each post call this due of course we are going to need a unique key and it's going to be post. ID because remember here ID is unique and I can pass my post here and in this component I can take this post and show the post title and post description let's see I'm going to refresh as you can see titles are here but where is our description no it's going to be body not description okay it works as we expected and by default next JZ caches the API responses and it increases the performance so if I visit another page and come back it's going to be much faster because this data is cached this is the default Behavior but how we are going to change it by the way let's close them okay I'm going to close my sidebar and if you don't want to cach this data you can write here an option and I will say cache as you can see by default it's Force cache you don't have to write it like that it's the default but if you don't want to store anything you can just say no store right now when you visit other pages and come back it's going to refat your data it's going to be slower but each time you will see the fresh data so if you have any data on your database that is changing constantly it's better to use no store but if you have a Blog website that you write once a week it's better to use the cache but also you can revalidate your data and you can give any duration to do that inside option I will say next you validate and you can write here any time period so let's say 3,600 seconds which is 1 hour so it's going to refresh your data in every 1 hour this is another option so let's see our single pages when I click here it's going to open up a single post to do that we can use this post ID but in our example remember instead of ID it should be a slack when we create our database we are going to use it like that but for now for the test we can use those IDs post IDs so I'm going to open up the postcard again and inside this link I'm going to wub my text here and right here post. ID let's check when I click here it's going to open up Blog Page and this ID okay right now using this slack let's try to patch a single post to do that again we are going to be using this API and as you can see we can use this endpoint posts and the post ID you can change here and hatch a single post let's use it I'm going to copy this actually let's copy here and open up our single page slack I will say get data our component will be a syn component and using this function we are going to fatch our post const post is going to be get data but remember we should use here a post slug so let's write it like this and I want to cach this data so I'm going to remove that and remember using params we can reach to our slack let's D structure this const slack is going to come from perms so I can pass this slack here and I can get that slack and use it here and right now I can use my post let's come here change this description post Dot body and where is our title here let's change it and let's see this is our title and description and as you realize we have a user here and in our example our post includes a user ID using this ID we can fetch our user let's check if I say a users and the user ID as you can see it gives the username email and other details if you want to you can fetch this user here and you can pass this post and this user but if you want to you can create another component just for this user and fetch the data inside that component I prefer using this method because if you fetch data in one function it's going to fetch your post and even if you have the post you will have to wait for the user so if you want to increase the page speed I recommend you to patch your post first and after using this user ID patch this user in other server component let's do that I'm going to come here create a new folder and I will say post user let's say post user jsx post user module. CSS and let's create our component here and I'm going to open my single page let's cut here and paste here let's say container username sorry title and username let's import our CSS post user module CSS let's open up our CSS here I'm going to copy this paste here and the first one will be container title and username okay right now I can use this component here as you can see nothing has changed and when we fetch our post we will get a username and we can pass this username to our component so I will say user ID equals post. user ID let's check I'm going to open up posts okay user ID okay so using this user ID I can fetch my data so let's say async we will do exactly the same thing this time we are going to have the user ID we are going to patch users and the user ID so let's say const user await get data and user ID and it's going to return us the username user do username and as you can see it's here in this case you don't have to wait for the user it fetches this post first and after fetches the user but if you do that you should show here an indicator like loading text or a skeleton component to do that we can use react suspense so let's come here open up our single page and I'm going to call the suspense component comes from react and we are going to need a fallback basically it's going to be our indicator and it will say loading okay but of course it's going to cach our data to prevent this remember you can say cash no store and let's refresh as you can see this is how we can use suspense blocks if you want to you can create here a component called skeleton and show that component instead of this loading text but I'm not going to waste time it can stay like this so right now let me show you one more thing since we are using NEX js14 we don't need to use an API of course we can create and I'm going to show you how but if we don't have API endpoint we don't need to use the fatch method so how we can fatch data without using any API let me comment them out I will say fatch data with an API I will do the same thing for the blog page let's comment this out so instead of patching data directly inside our component I'm going to come here and inside Library I will create a new file and it's going to be data.js of course you don't have to use exactly the same file and folder you can name them whatever you want and here I will say export const I will say export because we are going to use it in our component and let's say posts actually let's say get posts we don't have any data yet but I can create here a temporary data let's say con users it's going to be ID one name John ID to Jane and I'm going to create some posts ID title body second one user two and user to so when we call this function we can return these posts of course when we create our database it's going to be an async function and we will fatch our data from the database but for now it can stay like that and I will say get post I'm going to return a single post we are going to check our array and we are going to find the post that has this ID and I will do the same thing for a user just like this and in my blog posts we don't need this function anymore I can directly call my posts here const posts wait get posts let's check as you can see they are here let's call this here also with an API without an API and for the single page I'm going to do exactly the same thing I will say C post with API and without and for post user again and I will say get user I will click okay as you can see there's an error let's come back and put here question mark and if there's a post we will call this component and let's see what's inside let's check our data here const post okay it's undefined if I say ID it's one if I say type of ID you are going to see that it's a string this must be the problem if I say parse integer and ID okay our post is here that was the reason and I'm going to return this post but it's not a problem because we are going to send our slack not this ID but for now it can stay like that and of course when we create our database we are going to use here try catch blocks and we will be able to catch our errors and show a user a meaningful error here okay this is how we are going to patch our data we will use this data file instead of creating an API so let's create a mongod DB and fetch our items using that database I'm going to close everything here and open up mongodb Atlas and in this page you can create your free cluster I'm not going to show you how to do that it's really easy but after creating your free cluster make sure that you created a user and a password in my case it's going to be lad and the password will be exactly the same and we are going to click on the network access and here we have to add an IP address otherwise we will not be able to make any changes in our database if you want to you can add your current IP address if you deploy your application you should write here your server IP address but for this tutorial to make everything easy let's say allow access from everywhere because we are not going to use it in public so there is no problem it's going to take a while and after that let's click on database and we are going to connect to our database we will be using not JS so I will click here and this is our database URL as you can see the username password I'm going to write here lad Dev also and using this URL we will be able to connect to our mongodb so this is important and we shouldn't reveal this in public to do that we can use EMV file and hide our secret key let's come here inside the root file I will say dot EMV and let's say equals this URL I'm going to write here my password and after this URL you can write any database name let's say next4 tutorial or you can write blog or whatever you want after that let's open up the git ignore file because we don't want to reveal our EMV and make sure that EMV is included in your file so when you push your project to GitHub it will not be visible so using this variable I will connect to mongod DB if you want to you can install mongod DB but I prefer using mongus it's much easier to work and it's kind of type saved because you can create your own models as you can see there is a cat table and this table includes only name and it should be a string so if you try to create a new cat with name and let's say h it's going to throw an error because it should be only name and it's type should be a string to create these kind of models we are going to need mongus so let's open up our terminal I'll create one more terminal here and I will say mpm install mongus and I'm going to write here the exact version is going to be 80 and Z because again if you watch this tutorial in the future I don't want you to encounter any error this is why I want you to use exactly the same version and after that let's read the docs I will say connections and we will use mongus and connect method and we are going to pass here our secret key remember it's inside em file but I want to use try catch block because it might throw an error as you can see try catch so I'm going to open up my library and let's create connect to db. JS or if you want to you can create another file and say util Jaz and write your function here let's do that const connect to DB it's going to be an Asing function and I'm going to paste my connection method let's import and it's going to be process EMV file and and if there is an error let's console log this and throw this error we can write this string or directly pass your error and I will say export const because we are going to use it but there's a problem here since we are using the development mode whenever we refresh our application it's going to create a new connection to prevent this I'm going to check if we have the connection or not if we have we are going to return the existing connection if we don't have we are going to create a new one so I will say const connection is going to be an empty object and I will say if connection is connected we are going to direct the return we are not going to create anything but if it doesn't exist I will say const DB equals this connection and I'm going to update my connection here I will say connection is connected will be database connection and we are going to take the first con contion and ready State don't worry about here you don't have to memorize anything basically we are saying okay we don't have any connection I'm creating a new one and after creating we are going to update our connection and next time when we call this connect to DB it's going to check the connection and since it's not empty it's going to use the existing one so let's create our models I'll say models do JS remember how we were doing this mongus do model the model name and whatever we want to create but also we can use schema let me show you how to do that but first let's decide what we are going to create we are going to create a post and a user it's going to be really easy I will say const user schema we are going to create new mongus schema let's import oh why it imported like that we are going to be using es6 import and using this schema I'm going to write my types firstly we are going to have a username and let right here our options its type will be string I'll say required true because we can't create any user without username and uni will be true we cannot create a user with the same username it should be unique and what else we can give we can give minimum character it's going to be three and let's say maximum 20 and what else we can have we can have an email again type string required unique and let's say maximum 50 and we are going to create a password and the minimum character will be six and we can have an image type will be string but it will not be required so I will not write anything else and finally I will say is admin the type will be Boolean and by default it's going to be false so if a user logs in his admin property will be false and additionally we can add here time stamps it's going to be true basically when we create any User it's going to create the creation date automatically so let me close here by the way and I will do the same thing for the Post let's copy this and it's going to be post schema so we are going to have a title it's going to be a string required it doesn't have to be unique I will delete this I will say description again string required and I can delete this if you want to you can give maximum we are going to have an image I will delete this but it's not required we are going to need the user ID the type will be string and it's going to be required we can't create any post without user and I'm going to create one more thing and it's going to be our slack so when we create here a new post for example new post and the slack will be new Das post and it has to be unique required and unique okay and again time stamp right now using those scha as we can create our models I will say export const user and we are going to create this user but there's a problem here if we already have a user in our database we don't have to create a new one instead we are going to use the existing one so I will say mongus do models we are going to check our models if there's a user inside use it if not create new one and I will do the same thing for post just like this and that's all using those models we are ready to create new user new post we can update them we can fatch them let me show you how to do that let's close everything and open up data and right now I don't need them anymore let me comment this out and I will write here try catch block if there's an error firstly we are going to console lock and after that we are going to throw this error and let's write here fail to fatch posts and let's try to fetch our data I'll say const posts by the way let me know in the comments if you want to see this cop plot or not it might be annoying for you if it's annoying just let me know and I will close and I will say await post model and I will say find so it's going to return all the the posts we have so let's return this but of course to use this method we should be connected to DB so I will say connect to DB so let's do the same thing for others I will paste here and here and we are going to have the post slack and it's going to be user ID it can stay like that and I will say pause find and I'm going to pass here my slack it basically means slack equals slack but if you are using the same name you can directly write it like this and I'm going to pass this post here and what about user we are going to get the ID I will say user we are going to be using the user model and and we are going to find by ID and I'm going to pass here this ID and again if you want to get all users that we are going to use in our admin panel I will just say users find so it's going to find all and we are going to return it's that easy guys so let's open up our post page this Blog Page and let's see what we have as you can see we don't have any post let's come here and add some posts as you can see this is the previous project I'm going to choose my database here and inside users let's create a new user I'm doing this because we don't have any admin panel yet so I will say username is going to be John let's add new one email John add gmail.com we should get a password one to six of course we are going to Hash this password later but for now it can stay and what else we have let's open up our models okay by default it's going to be false is admin and false of course it's going to be aoon string string string okay let's create and I'm going to duplicate this I will say clone but this going to be chain chain okay and one more and let's say admin admin and it's going to be true okay so right now using this user ID I can create a new post I will say user ID this ID title hello world description test and what else we don't need this we are going to need Slug and let's say hello Dash World okay let's create one more second post second T description of course we can give some images so we can see it better let's open up pixels again I'm going to choose this one so I will say edit add here new field and it's going to be image and I'm going to paste it here okay and the other one doesn't have image because I want to show you something so let's see I'm going to refresh the page and as you can see Hello World and second post let's update our image inside postcard I'm going to write here a condition I'll will say if post has an image use it here like that and let's click as you can see there's an error okay we cannot Fouch our user there's something wrong there let's open up the single page and comment this out for now okay we don't have post because this is our post ID but remember it has to be slack so inside postcard I'm going to say block and it's not going to be ID it's going to be slack let's get back and when I click it's going to open up the hello world but again it cannot fetch our data let's open up console and I'm going to close here okay it's correct but why it's not showing by the way let's say if there's an image and I'm going to update my content it's going to be post. description oh this is an array get post because when you say find it's going to return an array to prevent this I will say find one I can say that because I know that it's Unique so I have to say the same thing here but we don't need we are already saying find my ID it's going to return only one user and right now it's here but what about this image I use different one because I didn't change here let me close this menu and it's going to be pause. image okay perfect we are going to change this created ad date but we didn't add them let's actually find a user here and copy this created adate and I'm going to edit I will say created at and paste here of course the type should be the date I will do the same thing here okay right now I can show it let's close here and I will say po do created at but if I do that it's going to give me an error as you can see because the type of our date is a date object we can not show it directly to do that I will say to string and as you can see it shows this long date but I want to see only the day month and the day and maybe this year also it's not today's date because we are using different database here so I will come here and use a slice method and I will say take from the first character to 16th character actually I can delete Here Also let's say forth and perfect and what about our user let's get this back as you can see John is here but I forgot to change this image it should be inside this component so I'm going to cut this open up post user and let's update here it's going to be container after we are going to have the image and I'm going to wrap my texts let's say a do text and drop my text let's open up our CSS in this case it's going to be texts uh for the container I will say display flex and gap between image and text will be 20 okay let's remove here and it's going to be user do AAR it was aatar or image okay image and of course remember it's not required so I should write here a condition if it exists actually I can do here something else I will say if it exist show the user image if it's not show no Al do PNG let's check okay it's here I'm going to save and here and perfect of course I should change its style inside single post remember we had alar but we don't need this anymore here instead we are going to be using post user and before texts I will say alar okay so this is how we are fetching data but remember when we use API we were able to stop caching it was here I think okay we said Cache no store but how we are going to do when we don't use fetch let's close everything open up data so if you don't want to Cache your data you can add here nextjs no store function but this feature is not stable for now probably it will be stable soon but we can use it by the way let's move them on the top of the file and I will say import unstable no store as no store from next cache and when it's stable you don't have to use this name it's going to be directly no store and we will be able to use it so I'm going to come here and call this function and that's all it's not going to cach anymore as you can see loading and after jump and this is how you can control caching so let me show you how to improve search engine optimization if you open up your layout file let's close here you are going to see that there's a metadata and this is the main title of our application let's say next app title and description and let's open up the homepage and inspect and inside hat tag you are going to see that our title and description is here but if I open the blog page again we are using exactly the same title and description but it's not a good idea for the search engine optimization we should give different title and description for each page especially for our posts products whatever important for your SEO because people are going to search for the title of posts or anything in the description in this example you can see that statically changing title and description is really easy just copy this metadata and let's open up the contact page and before this function I will just say metadata next app contact page and contact description and I can do the same thing for for example about page let's open up as you can see it's here this is how we can change statically but before explaining how to create create Dynamic titles and descriptions let me show you one more thing here if you realize we are using this text all the time next app contact page next app about page and for the homepage we are directly using next app title so instead of writing this text again and again we can create our own template let's see how to do that I'm going to open up my layout and instead of this text I'm going to create here an object and I will say by default it's going to be next js14 homepage and also I'm going to create here a template and I will use percentage s and let's say nextjs 14 and let's leave it like this basically instead of this s we can use different titles but we don't have to add this part again and again let's try I will come here and let's delete here contact page and about page this is the next js14 homepage about page and our default template and contact page this is how we can use it so what about Dynamic title and description let's open up our single post and I want to add this title to metad dat and this description so let's open up the single page so I'm going to come here and say export const I can't use metadata because I have to fetch this post first and get the title and description so I'm going to use use generate metadata it's going to be async and again we can get our params and we can D structure as we did here and we can fatch our data and using this data we can return our title and description it's going to be post title and post description let's see as you can see Hello World hello world and our description if I open up the second page second single post as you can see it's here perfect you might think that why we are fetching data twice but don't worry in nextjs if you try to fatch exactly the same data twice or multiple times times nextjs fetches only once so even if you use an API call it's not going to fetch again it's going to make only one request so let me explain you server actions and after that we will be able to add our own posts and users so let's create our first server action I'm going to come here and I will say actions. JS and let's create a function say hello and to make this function a server action I'm going to write here use server directive and after this point whatever I do inside this function is going to run on the server so let's say console lock hello and there is something important here if you are using server actions your function has to be async whether you are returning an async event or not doesn't matter it has to be async so I will say export and let's use it in our let's say actually I'm going to create new page server action test page do jsx component test page so right now inside this D let's create a form and it's going to include only a button test me and when I click on this button it's going to call our action what was the name say hello I'm going to import I'm going to open my terminal and let's see Server action test and when I click here as you can see it calls our function and it says hello and since we are using a form we can create any inputs here like post title description or whatever and using this action file we can create a new post by the way you don't have to create this file you can also create your own action here const action in component as I said it has to be async console log it works let me write it like that and of course I will say use server let's try I'm going to click and it works so let's see how it works I'm going to open my console and network Tab and when I click here you are going to see that it's actually calling an API request as you can see the request youl is our URL and payload includes an action ID if we have any input here is going to include that also and it returns us 200 status code so basically whenever you call an action it's going to make a post request so instead of this small test let's try to add a new user of course we are not an admin and we are not authenticated we are going to handle this later but for now to understand server actions better let's do that I'm going to delete this actually let's say add post async and when we have our inputs here remember we need a title description Slug and what else let's check title description image it's not required okay user ID and they all are going to be string so they can stay like this and when I click on this button let's say create we are going to take all these form data as a prop so I will say form data and let's say and let's see what we have inside I'm going to call this action of course let's delete this and here let's see I will say let me zoom in title description slack and user ID and let's try to destructure our items const title equals form data get title description and slack let's see them I'm going to click as you can see they are null because we didn't provide any name it's really important name description SL PL and user ID let's see right now I'm going to click and as you can see they are here and also you can destructure this instead of writing them one by one so let's comment this out and I will say const title description and slack from form data and also user ID let's check again I will click of course it's undefined because we didn't get any of those items to do that we are going to be using object from entries and form data let's try and they are here and right now using those fields we can add a new post to do that firstly I'm going to be connected to mongod DB so I will say connect to DB if you want to Let's right here try catch block if there is an error we are going to console loog and we are going to return let's say error something went wrong and after connecting I will say const new post and I'm going to create a new post remember this is our model I'm going to import and I'm going to pass inside my title description and slack and user ID let me close here and after that I can save this to our database so I will say await new post Dove and let's write here a console lock save to DB let's open up again and when I click save to DB let's check I'm going to refresh and as you can see it's here and if I visit my blog page we can see that our item is here let's add new one title two description two slack two and user ID and again it's here but if you remember in our data file when we patch our posts we are not using no store function as we did here but it still shows our posts that's because we are in the development mode if you build your application you will not be able to see your changes immediately but how we can let nextjs know that we added a new post and it should update our page it's really easy I will just come here in my action and after after the successful operation I will say revalidate path and I'm going to write here my URL which is block so whenever I add a new post even if we cash our block posts it's going to revalidate our path and it's going to show us the fresh data so this is how we are using server actions we can do the same thing for deleting data how we can do this I'll will say delete post and we are going to need only post ID actually let's directly say ID and again we are going to be connected to mongod DB and after I will say await post model and find by ID and delete and I'm going to pass here my ID delete it from DB and if everything is okay again we are going to revalidate our path and it's going to refresh our data it's that easy guys by the way if you are using multiple server actions in one file you don't have to provide use server directive again and again just use it at the top of the file so it's going to apply for any function so let's come here and I'm going to create another form I will call delete data what was the name delete post of course I should export first and we are going to need a post ID I will create a button and I will say delete let's try let's get this post ID if you want to you can pass the slack also but anyway ID is a better option we are going to take this ID and delete okay let's try I will get back and refresh it's here I'm going to paste delete if I go to the blog page okay it's still here because again I forgot adding here the name it's really important guys you shouldn't forget and it's going to be ID remember here let's try again I will paste and delete I will check and it's not here anymore as you can see you don't need any API route you don't need to use any click event and track this progress everything is much easier so the question is are we replacing apis with server actions if you ask my opinion the answer is no if you have a complex application if you are using multiple platforms you are still going to need an API because you can dispatch your actions only on your website and also if you have a huge schema like posts users categories products of course using an API might be a better solution so it depends on your project but again in my opinion if you have a small application and just have couple tables I think server actions are great but if you have something complex use API routes let me show you how to do this also and you can compare so let me explain how to create an API route if you remember we can create our pages in the app directory using the path name of the pages and we will do something similar here we will create our API inside the app R so let's say API and the path name of this API will be/ API and inside our API we are going to have some end points like API and users and insight users another endpoint and it's going to be API users and the user ID so using this ID we can get delete or update our user and let's create one more and it's going to be posts so we can do exactly the same thing here in the app directory I'm going to create a folder called API but there is something important here we have to let nextjs know that this is an API route not a page so the file name has to be route route JS or TS and right now NEX ja knows that this is an API route and it's ready to get our user requests and send a response so in this example we are going to have users route and using this route we will be able to get all users or create a new one so let's move this here and I'm going to create my users folder just like that and for this end point again I'm going to create a folder but remember this number will be dynamic so inside users I'm going to create a dynamic route and I will say the user ID and using this ID we can make the cruit operations so this is how we can create next Jaz apis so let me show you how to receive a request and send a response in nextjs API routes so I'm going to come here and create a new folder and it's going to be API and for the blog page for example we are going to fatch our data and inside I will say route. JS since we are fetching data our request will be a get request so I will say export con get request is going to be async and we are going to get the user request let's say request and again try catch block lock if there is an error we are going to console lock and also we can throw this error new error failed to fetch posts it's exactly the same let's connect to the mongod DP and again post wait post and find I'm going to import this and if everything is okay we are going to return this post to do that we are going to be using nextjs response next response it comes from next server Json and posts that's all for this example we don't need any request because we are fetching all these posts anyway let's use these end points and fetch our data in the blog page if you remember we are fetching data with an API just like this and right now in instead of this fake API we can use our endpoint so I will say Local Host 3,000 API and block let's get this back and right now I'm going to comment this out and take it back there's an SSL problem of course it's going to be HTTP let's see I'm going to refresh as you can see they are still here nothing has changed so what about single post let's create our slack and Route JS and we are going to do exactly the same thing but this time we are going to need our params remember how we are doing this we are able to take our PRS like that so we can do exactly the same thing in our API routes but be careful it has to be after request like that so let's D structure our slack const slack from parms so using this slack I can find my post remember how we are doing this for find one and I'm going to pass here my slack like this let's say post post and post so let's use this API route right now I'm going to come here comment this out open my API fetching and here of course not this title and I'm going to change my URL Local Host 3,000 API and slack of course you can write this URL in your EMV file so each time you don't have to change everything by the way as you can see there's an error because I didn't write here block but again there is something wrong let's check but Local Host 3000 API block and slack Okay the reason is I forgot making this Dynamic right now I will refresh and it's here perfect so you can do the same thing for post or delete requests so you can come here and say delete again we can delete one and pass here our slack failed to delete post of course we are not going to return anything we can just say post deleted so when you want to delete your post you have to make a delete request and it's going to be just like fetch block or slack but the method will be the delete method but of course we are not going to delete anything and it can stay like that let's leave it like this and I'm going to close everything right now we know how to fetch data how to add new data or how to delete but to do that we have to be authenticated first and we have to be an admin and we can restrict our blog posts it can be premium feature for authenticated users so if we are not logged in we will not be able to see our posts so let's learn next js14 authentication so let's open up the documentation of OJs and I'm going to click on API reference and find the latest version as you can see it's still beta but it's compatible with NEX js14 in the previous version we had to use API routes we had to WRA our entire application with an off provider but after this version everything stays on the server site so let's open up the documentation and see how to use it firstly we are going to install next off and beta and when you watch this tutorial probably it will be version five but for now we have to use it like that and again I highly recommend want you to use exactly the same version with me so I will say mpm install 5.0.0 beta and three during this installation let's see how to use it as you can see we are going to need two environment variables next of URL and secret and after that we are going to need a configuration file and inside this configuration file we are going to create this function and pass our providers it can be Google provider GitHub or any other social media and also we can use user credentials let's first create our secret and URL I'm going to close here open up my EMV file and I will say all secret and URL it's going to be Local Host 3000 our URL and we should add here your API and off and for the secret you can write anything you want or you can generate a secret key using open SSL like that let's copy this and paste here it really doesn't matter what you write here we are using this because when we are authenticated next up is going to create a session using this C secret ID so I'm going to save here and let's create a new file OJs let's paste this here and to use GitHub provider firstly we should create a new GitHub app to do that let's open up GitHub and I'm going to scroll down and find the developer settings and I should create a new authentication app let's say next 14 tutorial homepage URL will be our URL and the Callback URL will be our URL API off callback and GitHub so when you use other providers again you are going to use same endpoint you are just going to change here it's going to be Google Facebook or whatever let's create as you can see it gives us a client ID and secret we are going to use them inside our EMV file let's copy this and here I will say GitHub ID and I'm going to paste this and GitHub secret let's reveal our secret I will copy and paste okay right now we can use them in our configuration client ID will be process EMV GitHub ID and client secret will be GitHub secret so using this function we will be able to reach our user sessions and also we can use signin methods or sign out method so we will use this in our login page and we are going to use this in our nbar component let's come here and open up the login page and let's open up login and let's call this function to do that we can use a form here and call this inside a server action so I will say button login with GitHub of course it's going to be a form here I will say handle GitHub login let's create this function here GitHub login and it's going to be use server don't forget adding here async when I click on this button I'm going to call the sign name function that's import and inside I'm going to write my provider as you can see there are many providers but we are going to be using GitHub and of course it's an asnc function so I will say8 and let's see I'm going to click here and as you can see this is our app name I'm going to authorize but before let's try to console log our session remember we have off here and let's see what we have inside I will come here and say async const session equals await off I'm going to import and let's see what's inside by the way there is a problem here because we didn't create our authentic ation endp point if you remember we are using API and off but we didn't create anything let's come inside API and new folder and it's going to be off and our library is going to handle every single endpoint like login logout error or whatever it might be so I'm going to create a new folder and spread next off so we don't have to write one by one log out error or anything it might be let me show you actually I'm going to come back and let's say getting started and as you can see in the documentation it says we should create API route off endpoint and another endpoint which is next off of course it's using Pages directory we are using the new app rouder so instead of writing next off. TS I should create here a route file remember this is how we are creating our endpoints and as you can see all JS handles every single end point for us we don't have to create any of those this is why we are spreading this end point like that it might be confusing but this is how it works okay so this library is going to handle all the G and post methods if you remember we have handlers here and it includes get and pulse methods and we can take those and Export inside our route I will say export get and post from library and off let's click and authorize okay there is still something wrong oh when did I create this there is a layout but we don't need this layout I'm going to delete okay there is no problem and if you check your terminal you are going to see your user session as you can see inside this session we have a user object and inside we have the username email and image so we don't have to worry about sessions tokens cookies next o does everything for us if you use a custom AU authentication like signning with user credentials you don't have to create this API route but if you are using social media accounts like GitHub Google Facebook you should create this route otherwise it's not going to handle the session process and let's try to log out if you want to you can move this function into action JS I'm going to scroll down and I will see export cons handle GitHub login and I'm going to import this sign in I'm going to save and let's import here in this case we don't need this actually we don't need this either we are not going to check anything then we create our middleware after the login process it's going to redirect us to the homepage so let's give log out functionality for this button I'm going to open up nowb bar and inside remember we have links component and here where is log out here so I will come here and create a form and let's write our action handle log out let's create this I will duplicate and change the name and here I'm going to call the sign out function we don't have to pass anything and I'm going to import it here by the way let's call our user session if you remember we were using these temporary variables session and is admin right now instead of this session I can directly call my off function wait and off let's import and of course our component will be an async component but there is a problem here we said use async in this case our component will be a server site component but here we are using use stook which can be used in only client comp components to prevent this problem I'm going to leave it as client side component and I'm going to take my session as a prop asnc component we are going to call off function and we are going to pass this session here session equals session let's take it as a prop and as you can see right now we don't have any problem it's going to check our session and if session. user is admin we are going to see this link and this button if not we are going to see this link by the way let's see user let's refresh the page and I'm going to click here but before I should console lock otherwise we can't see console look session okay it's here when I click as you can see logout button disappeared because we are not authenticated anymore if you check your terminal you are going to see this null value let's try again okay authenticated and then I click log that so this is how you can create social media authentications but how we are going to add this user to our database firstly when we log in we are going to check if the user exists in our DB or not if it doesn't we are going to create a new user if you already have that user we are going to return that user directly and in this case we will be able to use the is admin property because when we log in as you can see we have only name email and image but but also when we create a new user his admin will be false how we are going to do this I'm going to close everything and open up of JS and after providers I'm going to write callbacks and the call back will be sign in Asing sign in and as you can see it Returns the user account and profile let's check what Insight it'll just say user account and profile and for now I'm going to return true it's going to be a comma and let's see I'm going to log in and as you can see this is our account it shows our Pro provider and the user access token and profile includes our AAR URL email or anything related to our GitHub account so using those informations we can create a new user you can use any information you want so what I'm going to do here let me shrink this first here I will say if account. provider equals GitHub because remember inside account object we have provider and it's GitHub basically I'll say if user is authenticated with a GitHub account connect to DB and try to find that user I'll say try catch if there is an error I will console lock and I'm going to return false so if you return false inside this signin function even if user signs in with the GitHub account if we fail to search for that user in our database the user is not going to be authenticated we have to check it in rdb first so I will say const user await user let's import our model I will say find one and I'm going to check the profile email if it doesn't EX exist I'm going to create a new one I will say if there is no user in our database const new user and we can use profile name email and image and if you want to you can write here is admin false but remember by default it's already false we don't have to write it and after that I'm going to save it to my database okay there's a mistake here let's check it ends here we don't need this and this okay and if we don't have user we are going to create new one if we already have we are going to return true actually let's return after this function okay okay we couldn't import this model so let's add here question mark okay I'm going to log in and there's an error let's check it says there is no provider because I didn't D structure them let's try again I'm going to log out and log in and as you can see access denied we missed something if there is an error it's going to show this page and if you realize it's showing different URL when I click it shows the default login page but in our application we are using the login path we are going to change this but before let's check our error as you can see user validation failed because we didn't add any username we said name but it has to be username and also the password is required but in a social media authentication we don't need any password so I'm going to open up my model and change my field I'm going to delete this and here and as you can can see the field name is username we are going to change it like that let's try again I will log in okay it's not passing our username there is something wrong let's console log again this profile and see what's going on I will come back and login I'm going to open up links maybe this console is coming from our Nar okay the profile is here here oh it's not name it's login so you have to be careful here because when you use GitHub the username is login when you use Google the username is display name or when you use any other provider it can be username or just name so make sure first which data includes your username otherwise you are going to encounter this error so I will say profile do login and again for URL we are going to use this and email is correct let's try one more time I will click and let's check our data I'm going to refresh and and it's here so when I log out and try to log in again it's going to find this user so it's not going to create the new one so right now let's see how we can create user using the credentials so firstly we can create the register page and after we can log in so let's come here and say register okay we didn't create this page yet inside register I will say page. jsx I will create my component let's say register page and I'm going to create here a form so let's say form we are going to add our action here but before let's create our inputs placeholder let a username and remember you should add here a name because we are going to be using server actions username we are going to need email password and one more let's say password again so let's say password repeat and finally a button and I say register so let's create our action and I will say export const register Asing form data and let's get username email and password from our form data and also password repeat and firstly I'm going to check if the passwords are equal or not I will say if password doesn't equal password repeat I will return password does not match and if they are equal finally we can create our user of course firstly we should check if it exists in our database or not if not we are going to create a new one so let's say const user user model I will say find one and and I'm going to search for the username if there's a user in our database I will return user already exists so we can't create a new one if not we are going to create a new user username email password and if there's an image we can add this also but remember it's not required in any case I'm adding here and after we are going to save the user and if there's an error we are going to return this error let's call this in our register page and let's see we are going to give a style actually let's give quickly I will say register. CSS and I'm going to paste my style there is nothing important here and let's give a class name Styles dot form let's import our Styles okay by the way I forgot module if you want to Let's create here a rupper and change the background color of that dropper it's going to be our container and inside I'm going to create a new do it's going to WRA our form and its class name will be rer so let's enter everything inside this container and give a size for our rupper and change the background color okay it's much better and I forgot adding here a weit and let's see we have a wait here let's try I hope everything works properly I will say from client from client at gmail.com password and password I will click let's check our database I'm going to refresh and as you can see our user is here but there is something important here as you can see our password is a plain text but before storing passwords you should hash them first to do that we are going to be using a library and it's going to be bcrypt mpm install and bept let's see how it works I'm going to open up the repository and find the usage which as you can see this is going to be the plain text that comes from the user firstly we are going to generate Assa and after using this hash method we are going to encrypt our password let's do that I will say bcrypt from bcrypt and before creating a new user I'm going to change this password so let's say generate salt and and after const hash password await bcrypt hash method and we are going to pass here the user password and the generated salt and right now we can use our password here so let's try again from client with password let's change here and I will say from 1 to six I will register and let's see and right now our password is hashed so when we login again we are going to take the password from the user and we are going to Hash it again and we will compare that password with this password if they are equal the user will be authenticated let's do that and after I'm going to show you how to handle errors here because if I try to create a new user it's going to return this error but to see this error here we are going to be using a hook but before let's see how to L in I'm going to come here and let's create a form I will close everything and open up my login page and after this get up for I'm going to create a new one and it's going to be login action of course we are going to create later but for now let's create our inputs placeholder will be username and the name will be again username one more and it's going to be password and finally a button let's say login with Creed ials let's create this I'm going to open up actions and let's duplicate this actually and I'm going to say login so what we are going to do we are going to take the username and password I will delete the rest we don't need here and let's delete here if there's an error we will say say something went wrong and we are going to sign in using next of credentials so I will say8 remember we have assign in method comes from next off and the provider name will be credentials and we are going to pass here our username and password let's see I'm going to save and call this login function here right now we are passing our username and and password but OJs doesn't know how we are crypting our password so inside our provider we should let it know that we are using mongodb we are passing the username and password and encrypting our credentials let's do that inside providers and after GitHub I will create credentials provider let's import this at we did for GitHub credentials provider next of providers and credentials and after that inside I'm going to write my rules to do that we are going to be using authorized function and we are going to pass here our credentials there is a typo here okay and inside firstly we are going to find our user using mongodb if the user exists and password is correct we are going to return that user if not we are going to return null so authentication will be failed let's actually create here a function otherwise it's going to be really complicated here I will say const login Asing function we going to take the credentials and I will say try catch block if there is an error console lock and after throw that error let's say fail to login and here I'll say connect to DB I will find my user you already know how to do that user model find one and we are going to pass here our username and it's going to come from our credentials and after if there is no user we are going to throw another error and I will say user not found but if you want to you can say wrong credentials and after I'm going to check my password I will say const is password correct we are going to be using bcrypt and compare method I will import okay let's do this manually okay and we are going to pass here the password comes from user which is credentials and password and the password which is inside our user into DP and again another condition if password is not correct we are going to throw this error wrong credentials and finally if everything is okay we are going to return our user let's call this function here let's say try catch again if there is an error we are going to return null we will not have any user so let's call our function here await login and credentials and if everything is okay we are going to return our user okay let me check those weights again because sometimes cop Lo doesn't add them as you can see wait and okay there is something wrong there is something wrong about bcrypt okay guys let's remove this bcrypt and try to add bcrypt JS mpm uninstall bcrypt and mpm install bpjs let's change the library name equp JS and in action I'm going to run again mpm run Dow okay there is no problem okay let's try I'm going to zoom in we are going to give style but for now it can stay what was the name from client with password and one to six and I will login okay it seems nothing has changed but if I refresh the page you are going to see that we are logged in so it works but if I give different credentials for example that doesn't exist I will login and refresh the page and as you can see we are not logged in so after the login process we have to redirect our user to homepage to do that we are going to be using middleware but before let me show you how you can handle errors when we add different credentials we can see our errors here or when we register again we cannot see our errors let me zoom out and open up our register action here and how we are going to show those messages of course instead of sending here a text you can throw new error and say password do not match and it's going to open the error page let's do that actually I'm going to save and let's write something and I'm going to register as you can see we are in the error page and using that page we can show our error message but it's not a good idea because if there's an error user has to go to the register page and write all these information again and again to prevent this we are going to be using use form State hook let's search for it I opened react documentation and as you can see this hook allows us to update the state based on the result of a form action let's check the example and you are going to understand better as you can see we have a form here and we are going to create our action here basically this form State Stores a state and we are going to pass here its initial value in this example it's zero when we click on this form button it's going to trigger form action which is here and this form action is going to dispatch our increment function and it's going to pass this current value and it's going to take that value previous state and also form data of course there is no input here but you can use form data and what it basically does is increasing the number so our current state will be one right now if I click one more time again it's going to fire this function but our state will be one and it's going to take that state and increase again so how we can implement this in our register function basically we can pass here an empty string and when we trigger our server action if there's an error we can update that state it will not be empty string anymore it's going to be do not match or username already exists or something went wrong by the way for the consistency we can add here object and error because here we are using error and again I will do the same thing and error if you want to you can directly pass your text doesn't matter but this is going to be our state and we can check this state and if there is an error we can show it in our register page this is the login page I'm going to open up register okay so let's use this hook but remember if you are using a hook your component should be a client side component so let's create another component here inside components let's close here I will say register form jsx I will create my function and let's create style and I'm going to import this let's say container import styles from register form module CSS okay so let's come here and copy this form actually let's cut and paste here we don't need this do okay and I will say it's going to be a client side component and right now I can use this use form State hook just like this let's import okay I can't import let's do this by copying here it comes from react Dom and at the beginning our state will be let's say undefined we are not going to have anything and our action will be register and I'm going to pass this action here let's import right now I'm going to call my component here register form we don't need this action anymore and let's come here and copy this form and paste inside our new component CSS file you can leave it form or change it to container doesn't matter and after this button I can show my error I will say if state has an error show it here but what if it's successful as you can see we are just writing a console message but we are not returning anything so I'm going to return success true and again this information will be inside this state so using that success bullion I can redir direct my user to the login page so I will say use a fact hook if state do success we are going to be using use rou hook to redirect our user so I will say const rouer use rouer hook let's import this from next navigation and using this hook I'm going to push my user to the login page there's a typo here okay of course we are going to need our dependencies and it's going to be state do success and our rou okay and if you want to let's add here a link I will ask user have an account if you have login and hre will be the login page let's refresh and don't forget question mark and there is one more thing when we call our server action we should pass here the previous state let's open up action and we have form data but we are going to also have the previous state let's try I'm going to refresh as you can see our link is here and if I use exactly the same username let's copy this again gmail.com password and register as you can see username already exists if I give different and here but if I change my first password password do not match so this is how we can handle server action errors and this is awesome because even if you don't run JavaScript on your computer it still going to work so let's give the correct credentials let's say two two let's paste the same password I will register and we are in the login page perfect so let's do the same thing for the login page but before I want to give my style it's going to be exactly the same inside components I will say login form jsx module. CSS let's copy here and paste actually again client import will be login action login form CSS again form State use effect use rouer I'm going to change the name of the component is going to be login form and we are going to make some changes here we are going to need username and password and I'm going to say login if there is a state and error we are going to show and I'm going to change here and let's say don't by the way if you are using code here it's going to give this warning it's not an error but it's better to use it like this okay let's call this component inside login page here I'm going to delete this form and write my login component in this case we don't need this login and again let's give class name Styles container one more is going to be rer I'm going to R my items import styles from login module CSS but we don't have let's create and again I'm going to Center my wrapper and let's give style for our form and let's copy this from register component I'm going to copy and paste okay if you want to you can change this GitHub button let's do that quickly login CSS and I will say getop it's going to be 100% I'm going to give some ping cursor will be pointer of course I'm going to give class name styles. GitHub okay it can stay like that I don't want to waste time let's open up our action and see what are our messages by the way we don't need this we are not fetching anything and let's close everything and open up action and inside login as you can see we return here something went wrong and we are going to need our previous state and let's try I will give some username that doesn't exist any password here and I'm going to log in as you can see something went wrong and let's open up our server and see our error message as you can see the error message is credential signning so when we give different credential next off throws this error so using this message we can return a meaningful message so let's write here an if block and I will say if error Dot message includes this message let's copy I'm going to return error and it says wrong username or password and if it's not the case if there's something other we are going to throw this error let's do the same thing again I'm going to log in as you can see invalid username or password perfect but there is something important here if I write the correct credential from 1 to six and as you can see it returns an error but our credential is correct and if you check your terminal you are going to see the next redirect error but why this is happening because after the successful authentication next off redirects our user to homepage using nexs redirect method and this method intentionally throws an error and since we are using try catch block here even if we are successfully authenticated it's going to catch that error let's open up the documentation as you can see calling redirect function throws a next redirect error it does this because when you use the redirect function nextjs wants to terminate whatever you do and redirect to desired page to prevent this error you can remove the try catch block but in this case we are not going to catch our credential error it's not a good idea so what we can do here instead of returning this message I will throw this error and if I log in as you can see we are logged in and we are in the login page and right right now there is one more thing to do if we are logged in we shouldn't see this page and also if we are not authenticated we shouldn't see blog pages and if we are not an admin we shouldn't see this admin page you might think that we can use this off function remember it returns our user session you can open up the login page and call our session and we can say if there is a user R push and the homepage you can also check if the user is admin or not and you can use this functionality for the admin page but there is a better solution and it's nextjs middleware because using middleware you can interrupt your requests and you can check the user permission without rendering this page it's not even going to visit this page nextjs is going to detect this URL it's going to check the user if it's not admin it's not going to call the admin page so let's do that I'm going to remove this actually let's close everything and this terminal and inside source directory I'm going to create a file and it's going to be middleware and if you are not using Source directory you should create this file inside your root folder not inside app directory we are going to have here our default config object it's not going to interrupt our API calls or static files and here I can use my off function but how we are going to write our rules to do that inside callbacks I'm going to create a new function and it's going to be Al authorized and this function includes our user session and the user request of course I'm going to D structure this and using this function we can write our authorization rules for example we can say if off doesn't exist redirect user to login page or if the user admin they are allowed to see the admin page and so on but there is something important here if we use our off function inside middleware it's not going to work because we are using a not JS Library here bcrypt also we are using mongus but the middleware is independent from any not JS dependent library to prevent this instead of writing our function here let's copy this and create a new file and it's going to be off config.js I will say export const of config and I will say callbacks and write my function here let's try I will just say return false but I have to pass here my login page because if we are not authenticated if we are returning false it's going to redirect us to the login page so I will say Pages sign in and it's going to be the login page and again we should write here providers and leave it empty because we already Define them here GitHub and credentials we shouldn't have to write this but if you don't write it's not going to work so I'm going to save and let's use this config file here I'm going to call next off first and off config and I will say export default next off and I'm going to pass here my configuration and the O function so let's call our configuration inside the main function I'm going to come here and say all config let's import like that so it's going to spread everything inside our configuration like providers but since we are using using different providers is going to overr right so we will be able to use them but inside callbacks again it's going to overwrite so we will not be able to use this function to prevent this I'm going to come here and I will say off config do callbacks okay let's see right now of course it should be library and as you can see it redirects me to the login page if I try to reach the homepage about page contact block doesn't matter I will not be able to do that let's say block as you can see it doesn't let me to visit any page because in any case case using this configuration we are returning false and since we return false it redirects us to the login page so right now I can write here my conditions by the way let's log out and let's see what's inside this off function let's say true otherwise we will not be able to see that I'm going to login I'm going to open up my terminal and as you can see it includes our session which has our username email and image this is the default behavior and if you log in with the user credentials what was the name let's copy one to six login and right now it includes only our email we don't have username we don't have his admin to prevent this we should add the user information inside this session to do that we are going to need two more functions here I know it's a little bit complicated but this is how it works the first one will be async JWT and the second one will be async session basically when we are logged in next off is creating a token JWT token and we have the user here the user information and using this information we can update our token let me show you how to do that I will say if there is a user token. ID will be the user ID and token dot is admin will be user is admin of course if and finally we are going to return our updated token so right now using this token we can update our session it's going to be exactly the same thing we are going to have the session and token and this time we are going to update our session session user ID will be token ID and his admin will be token is admin we can reach this data because we updated our token here in any case we can control our token okay right now let's see what's inside off I'm going to log out let's write our credentials and login open up the terminal right now we have the email ID and is admin so you can add here whatever you want you can add the username or if you have any other fields you can add it here but the important thing is is admin here because using this field we can redirect our user firstly let's check our user const user off. user and we are going to check if the user is on the admin panel const is on admin panel and we are going to check it using this request request next URL starts with admin so if it's admin it's going to be true so I can do the same thing for my blog posts if on Blog Page and it's going to be block and one more and it's going to be is on login page so right now we are going to have a couple of conditions first one will be only admin can reach the admin dashboard and the second one will be only authenticated users can reach the blog page and finally only unauthenticated users can reach the login page so let's write here our functionality I will say if let's write it like this is on admin panel and user is not admin we are going to return false and it's going to redirect us to the login page and the second one if is on blog page and if there is no user again we are going to return false because it's not authenticated and finally if is on the login page and user exists this time we will not be able to see the login page so I will say return nextjs response redirect and we are going to create here a new URL and we are going to pass homepage request. next URL this is how we are using redirect and finally if none of them we are going to return true let's see right now okay request next URL it will be path name here do path name okay let's try to open up the login page as you can see I can't because I'm authenticated let's try to see the block Pages as you can see I can because I'm authenticated and if I try to visit the admin page I cannot because I'm not an admin let's log out and try to open up the login page as you can see I'm not authenticated let's try to reach the admin page again I cannot and if I login oops let's actually make this admin true admin is here and I can see my admin page and that's all and as I said I know it's a little bit confusing but when you create a couple of project you are going to get used to and you are going to understand better it's an awesome library but as far as I know a really small group of people try to write this documentation this is why it still uses nextjs pages and it's not updated so often when you try reading their documentation don't be overwhelmed it's not well written or it's not totally up to date but just follow my tutorial try to add here different credentials like Facebook and Google and play around this authorization function this token function and after creating your own project I believe that you are going to understand more okay right now let's quickly create our admin page and add new posts and users we already did this in our action file you know how to delete post how to add post we are going to use those functions and we will be able to manage our posts and users in the admin panel we don't have users here I think so let's do the same thing for the user I'm going to copy this and paste let's say delete user I'm going to call the user model and we are going to revalidate the admin page because we are going to list our users there and let's say add user let's remove here and I will say take username email password and image and we are going to create a new user let's say new user and again admin by the way when we delete a user we are also going to delete their hosts so here I will say delete the user but before await post delete many and the user ID will be this users ID okay and again since we are using a form we can use the previous state to send our errors I will do the same thing here and when we add a post again we are going to revalidate admin also and then we delete okay so let's use them in our admin page so what I'm going to do is create four components the first one will be admin posts and I'm going to create here a form that we we can add new posts and user list and user form let's do that inside components let's say admin posts jsx and CSS I'm going to copy this and create two more admin users and it's going to be admin post form and user form by the way let's change this copy okay so let's create our functions quickly styles do container I'm going to copy this and finally admin users module. CSS okay let's use them inside admin page I will say class name container and inside we are going to have two rows let's import style it's going to be CSS rows and columns let's change here of course it's going to be styles do container styles. row and let's say call actually inside first call we are going to have the admin posts but remember how we are using suspense and I'm going to call admin posts I'm going to do the same thing here it's going to be post form and I will create another row and this time it's going to be admin users and user for let's import okay so basically inside admin posts and users we are going to fetch our data and those are will be form in this case we don't need suspense we are not fetching data they are just forms so let's open up posts I will say quickly async remember how we are fetching data con posts 8 and what was the name let's open up our data as you can see cat posts I'm going to import and using this data I can show my posts here so let's say H1 posts I'm going to use my data do map and for each post let's create a container and it's going to be a single post of course we are using map so we need a unique key and it's going to be post ID and inside we will have the post detail which includes a post image and a post title let's say span post. title and it's going to be source pause. image and if there is no image we can show no avatar.png let's give size it comes from next image and finally after this detail we can add a delete button to do that again we are going to be using form actions so I'm going to create a form here button and delete of course to delete this post let's open up action and see how we delete this as you can see inside form data we are going to need the post ID to do that you can create here an input and make this hidden name will be ID and the value will be post. ID but instead of doing this we can actually bind our ID before calling our action to do that let's write here delete post with ID and I'm going to create this function here we can take the post ID and I will return delete post this action and I'm going to bind my ID the post ID in this case we should pass here our post ID like that but if you don't want to do this just call your delete post action and pass this input let me write it and comment out so you can explore okay let's give class name here post button and I can give here here styles do Post title and that's all I think okay call plot has written s CSS let's fix that let's check the others okay okay it's correct and let's log in there is something wrong because we didn't use use server directive let's close everything and open up admin page again and find our component here and I'm going to write use server and of course we are direct to passing our ID we don't have to D structure and using our action we should take this ID before our form data so I will comment this out and oh we we can't call our functions like that I think okay so what you can do is create another component just for this form and take that ID as a prop because if we cannot use a function here like that you have to take this from the component prop and pass it here so I don't want to create a new file in that I'm going to use the previous version like that I will take as a hidden ID but anyway you know how to use the bind method right now this tutorial was way too long so I don't want to create different component let's see right now and we have an error here okay of course they are user avatars but if you want to you can add here no post.png and let's click here as you can see it's gone if I open up my blog page it's not here anymore okay it works so I can do the same thing for the admin users again it's going to be async function const users we are going to use get users data and using this data we will do exactly the same thing so I will just copy and paste let's import image and delete user just like that let's try to delete Jane and perfect John it's gone it's that easy you don't need any third party Library this is how you can easily mutate data and let's create our post form so let's make this a form element and the action will be let's say form action because we are going to be using use form State hook remember how we are doing this const state form action use form State hook we are going to call our action which is at post and the state will be undefined let's import this from react Dom and inside this form let's say H1 tag add new post we are going to have the post title description slack and image was image or IMG let's check okay it's image user is also image I mean IMG and they all are going to be string actually description can be a text area let's move it here and it's going to have 10 RS and finally a button let's say add and if there's an error we are going to show it like this let's check add post of course state do error okay and of course since we are using a hook it should be use client let's try test from panel I'm going to add and something went wrong let's see oh we don't have any user ID it's really important so again I will say hidden and it's going to be user ID we don't need this but we are going to need a value but how we are going to reach to our user ID if you remember after the authenication we passed our user ID to user session we can use it to do that let's open up the admin page and I will say async and and I'm going to call my off function I will say const session aate off and inside this session we have the user so let's come here and say user ID equals session user. ID actually we don't need this question mark because in any case we are going to have the session thanks to Middle whereare so we can delete this let's take this as a prop where is our form here and I'm going to pass it here if you think this hidden input looks a little bit weird you can use the bind method here because we have the user ID so let's try again let's copy this and paste and it's here perfect let's check blog page and it's here awesome so let's do the same thing for new user and after give a style and end the tutorial it's going to be exactly the same thing I will copy this user form and I'm going to paste let's say user actually we don't need this user ID why did I create that so I'm going to delete this and we are going to need username email one more is going to be password let's change the input type it's going to be password and I'm going to delete this text area and one more thing we are going to need by the way and it's going to be a select element and the name will be is admin if it's User it's going to be false if it's an admin it's going to be true and let's write here one more and I'm going to say is admin just like that and by default it's going to be false we can choose user or admin let's try I will say user from panel at gmail.com password is admin is let's actually say no and yes because we are asking question okay let's say no I will add and as you can see it's here perfect so let's give our style I will just copy and paste as you can see exactly the same thing as we did before and the post form exactly the same like that and for these lists as you can see there are just going to be display Flags justy content space between and the same thing for users like that so let's make them row because they are vertical right now I'm going to open up my admin CSS and let's delete them and paste our CSS as you can see it's much better but we can give space here so I will say display flx flag Direction column and gap between each row will be 100 pixels just like that let's delete add new one last post okay and let's say last user it's going to be admin and it's here okay guys that's all I think if I missed something just let me know in the comments so right now you know how to create your pages of course our password is too weak how to fatch data you know how to login with social media accounts and credentials and you know how to protect routes and you know how to add data using server actions so nothing else you need to know to create your own project and as I said if you want to go deeper and master your react skills you can add your email to wish list it's going to be in the description I hope you liked it if you learned something new today please like the video you can support lad by using the link in the description below or by joining the channel don't forget to follow lamad social media accounts I hope I'll see you in the next tutorial goodbye