welcome to the ultimate nextjs crash course in this specific crash course you will learn everything that you need to know to master nextjs from basic to Advanced Concept in a full stack modern production ready application you will learn things like client and server components server actions complex database manipulations using super base styling with theen CSS typescript form validations using Zod different data fetching mechanisms and knowing when to pick the right one for your project and for your pach building a SEO friendly site that the search engines are going to love and a lot more that we will be covering in this specific course but here's the thing don't worry if any of these terms are alien to you because my teaching style is to teach you all about the decisions that we are making such as the wi the house and the whats in the specific course towards the end of this course you will be able to confidently build applications that scale really well and are really performant if you have been looking to master nextjs but are tired of staring at the dogs and are tired of building a bunch of to-do applications then this course will teach you nextjs in a comprehensive easy to follow and a well organized Manner and guess what you don't necessarily need any prior knowledge of nexts before taking this course because whatever I teach I'm going to walk you through each concept step by step so you will know how I got that information and how you can apply the same in your projects as well now here's the thing unlike other courses we won't be building a dummy application we will be building a full stack e-commerce application that allows you to sell different products so trust me if you follow along you will Master next J and you will be able to build full stack production ready applications so what are you waiting for let's get started now whenever you are ready to level up your next year skills I have some good news I'm running a exclusive Hands-On workshop for you to take your next year's knowledge to the next level it will teach you everything that you need to know to design build and deploy a full stack app with nextjs it is a live Workshop so you will get direct access to me and I will answer any questions that you may have as well Plus at the same time you will get lots of exercises to learn different topics in nextjs you will be divided into breakout rooms so you can learn from your Workshop peers as well and learn complex topics together and if you get stuck don't worry because I'm there to help guide you as well Additionally you can show off your certificate of completion at your workplace or on LinkedIn to Showcase that are a certified next year developer at the same time I will be sharing a lot that I couldn't necessarily share in this specific crash course in that Workshop so if you're interested please sign up to the weight list as the weight list folks get exclusive launch discounts and special bonuses as well so sign up to the weight list and I will see you in the workshop what is next as next as is a react framework for production it allows you to rapidly build modern full stack applications it is one of the most popular react Frameworks out there and you want to know what what makes next CH powerful well it does provide a lot out of the box so as a developer you can focus on writing code and building seamless experiences for your users for example if we take a look at the docs provides us a lot out of the box it uses a file based routing system so all you need to do is create a new file and your route will be automatically created for you you can opt in different data fetching mechanisms based on your page and the requirement of your page so for example if you want your page to be service side rendered then you can do that or if you want your page to be completely static then you can do that as well thanks to nextjs it also has additional capabilities of server actions and mutations which I'm really excited to teach you in this specific course as well at the same time we have different rendering techniques so it allows you to create hybrid web applications where your code can be rendered either on the server or on the client thanks to server and react components which currently are only available inside of nextjs so we will be learning all of that too it also has a really powerful router that performs a lot of the caching for you so your router is going to take care of a lot for you because a lot of your data will be cached and you can opt out of caching as needed then we can choose how you want to style our application using CSS module tail and CSS and a few other different options then we can also optimize the application thanks to nextjs because it does provide us a lot of built-in optimizations provided you use the components that nextjs provides you so that you can improve your Cod web vitals that a lot of search engines focus on to rank your application higher for example if you use the image component inside of nexs then it automatically optimizes all the images for you so based on a viewport it is going to download a different image size so that your application is really fast then it also provides you a powerful metadata API so that you can power your application for search engine optimization as well you can also test your application and configure your application so that as your application skills nextjs can help you with that as well so nextjs does give you a lot out of the box and that is why it is one of the most popular Frameworks for react out there so I'm really excited to teach you all about nextjs in this specific course now if you are interested in accessing all the visuals and links that I have shared in the specific crash course then check the link in the description below because I have compiled all of them and shared it with you so you will be able to easily follow along so check the link in the description below and download it let's go ahead and install our first nextjs application now if we head over to the docs then we can head over to the installation section and get our next day's app up and running now here we have a few things we want to make sure you want to make sure that you meet these resistant requirements so you want to make sure that you have this nodejs version or later and you can quickly go to the command line and just type node hyphen V and that will automatically tell you the node version now in my case I'm already on this specific version so I'm pretty much good to go now you also want to make sure that you're using any of these operating systems as well so make sure you have that since I'm on Mac I'm pretty much good to go there as well now here you recommend using a tool called as create next app which is an easy way to Bo bootstrap your nextjs application it is a CLI tool now what it will do is it will create a new nextjs app for you with a lot of the setup for you and using the command like npx will also give you a few prompts that you can follow and set up your application let's just go ahead and copy this head over to the terminal and paste what we just copied here let's just call this app easy sell we will be using typescript we will be using eslin and we will be using a CSS framework called as tailin so alongside building nextjs and learning nextjs you will also be learning tailin CSS which is a added bonus so now we're going to say yes there we don't want to configure a source directory and we will be using App router now if you head over to the documentation you will notice that we have the app router and the pages router now in xjs the recommended way is actually using in app router rou we will be sticking to that so we will be sticking to that so now heading back here we are going to say yes we are going to use the app router and we don't want to customize the default import Alias as well so let's just say no to that now it's going to install the dependencies and the dev dependencies is necessary to run nextjs application and get started so now that it's almost ready to go we can just go ahead and change directory to easy cell let's just go ahead and open up our repo our next year's project inside Visual Studio code now I am using VSS code which is Visual Studio code as an editor of my choice but feel free to use whatever you're comfortable with now we already have the app ready to go but if you head over to packet Json you can see this specific command which is next Dev which will start our development server so let's just go ahead to our terminal and run npm runev and see what this app is all about now I'm on Local Host 3001 and that's because I already have app that we want to build easy sell on Local Host 3000 running but you will most likely have Local Host 3000 here but don't worry about that it's just a port so let's just go ahead and click on this and our app is ready to go we have created our first next year application so congratulations for that so now that we have our app set up let's just go ahead and start building easy cell let's give you a quick walk through of the app that we are building so for example if we head over to vs code then here you can see all the files and folders created for us so now if you head over to the app directory this is our app router this is the root directory of our application and where we will be creating any of the files so now whatever you see on the page here for example this nextjs page this is all available inside of page. DSX because page. TSX is the default route inside of our app directory now the entire application is also surrounded by another file called as layout. TSX you can see the HTML and body elements here inside of our application and that's pretty neat as well because this means any of the code inside of page or any of the new pages that we create will be inside layout so this children here is what will contain all those routes and this specific layout will surround the entire application so then we have the global. CSS file this file is our Global configuration file and we already have tail CSS already set up which is pretty awesome and we have some default styling as well at the same time speaking of of tailin we have another tailin config file where we will be adding or extending the existing tailin config that is provided out of the box for us can extend the design system that t provides us over here now also have a public folder that we can where we can store all our assets and it will be publicly accessible such as it gives us the next. SVG and ver. SVG then lastly we also have the packet Json which have a bunch of scripts ready for us such as we already saw the next Dev script allowed us to start a development server this will allow us to build the application for production and we can use the next start script to start the application that was built inside of next bill then this is just allows us to lint our application so check for any potential errors that have come up and help us avoid any sort of mistakes so let's talk about routing now now routing is one of the most fundamental concept inside of nextjs but it's also relatively straightforward for example if you want to define a route inside of nextjs then all you need to do is create a file called as page. DSX now any file which is page. DSX will be the index file in that specific folder now in this case the app folder page. TSX is the default route because it's called page. TSX the word page is sort of reserved for that reason now whenever you want to create a new route you can just create a new page. TSX file let's say we want to create a route called as products and in that case we could just say products and then create a new file inside of that called as page. DSX and we can create a new page here and just call this High page now what would happen is when you go to that application if you go to/ products then High page should be displayed here because we have just defined that here we have defined page. DSX here and this becomes the default route as we will at application further we will get into more routes and the reason why we can just create a new file inside of nextjs inside a folder and it we can automatically route to it and that's because nextjs uses a file based routing system so whenever you create a new file it should mean something and if as long as you stick to the definition of that file and you would be able to get a lot of the properties for that specific file now there are quite a few special files inside of nextjs there are special file conventions needed to define the spe special files and they will create a specific UI for you for example the file that we already have is the layout. TSX file now as we discussed earlier a bit this file contains the HTML and body tags and all the pages inside of our application will have whatever we Define here because layout is the root file so layout is essentially a shared UI between multiple routes layouts preserve State remain interactive and they do not render it's really important now the children prop means that any page that we load will automatically be loaded with inside the children prop and this specific layout is called a root layout because it's a root file inside the app directory which is our main directory so anytime you want to define something globally then we would use that now I have created a few diagrams for us for all these special files inste of nextjs now let's say we have a header and we have a footer now this header and footer would be there in all the pages for example if you head over to easy s site we have header and footer whenever we go to a individual page whenever you go to the upload page and so on so we need to add header and footer in side of layout we want those head that header and footer to exist everywhere so that is the advantage of adding a root layout layout file is not just limited to that you could create a new layout file here inside of products and create something similar to this it needs to take in a children prop so we can just copy this and paste it here again we don't need to add HTML and body tags because that's only for the root layout this is not a root layout but we could just get in whatever children we have as well now this specific layout file will only be applicable to products it will not be applicable anywhere else so let's just try this let's say high product here and whatever children gets defined inside of products will be the children here so now for example if we go to our site since we are on the product routes we are seeing High page we should not see high page the minute we route to the homepage there you go it's gone so that is the advantage of layout we could we can Define layouts however we like now as we build that application further we will be learning all these special vies along the way but routing is extremely crucial for us to go learn the second file now as we build our application further we will be going through the other special files as well you have defined layout and Page files here I wanted to cover I wanted to start the routing fundamentals here so you can start learning nextjs before we proceed further let's just delete what we created because this was just to learn nextjs now as we saw earlier the app router comes with taen CSS as a CSS framework by default as we chose in while setting up our project so let me quickly give you a walkthrough of dvin CSS so you know exactly how to style our application and we'll be able to follow along as I teach you next year as well so for example here tvin CSS is essentially a utility first CSS framework now if you want to learn tailin in depth then I also have a free crash course for you on tailin CSS that you should also check out on my channel right here if you want to Lear in that then definitely check out the tillin crash course on my channel now TN is a utility for CSS framework so for example instead of typing display Flex in a CSS file all you're going to do is write Flex instead of writing padding top is 4 pixel or 16 pixel or one Ram or 2 Ram or so on you are going to write PT hyphen 4 so that is the beauty of tailin it these are all different utilities now you can think of these utilities as essentially JavaScript functions that return the specific CSS for us for example essentially that's what they are now the reason why delin has gained so much popular because you don't need to create a separate file Al together you can just inline the CSS here for example if you hover over this and you have display Flex here now if you want to install the specific plug-in that I do have then you can go to extensions in Visual Studio code and then look for tailin CSS intelligence and you will be able to get the intelligence needed to style your application so if you head to getting started you can see the utility first fundamentals here and why they're important but if we take a look at responsive design and then DN does provide us a breakpoint prefix as well so that we can style our application for different viewports so for example by default tailin focuses on mobile and then we go to desktop for example over here p24 applies to all view ports but if I specifically say I want p24 to apply to mobile but let's say I want p64 to apply to let's say desktop then I can just add large as a prefix Elin also provides us with a design system system out of the box so it gives us a bunch of colors already all these different swatches that we can just use so for example if I want to change the background color of the page to BG I don't know gray 800 then I could easily do that thanks to tailin but at the same time I can changes to Pink as well if I want but it provides us on a scale from of 50 to 900 or 950 these are all the different colors that tailin provides us and it goes all the way to 950 now it also provides us a space spacing scale if you want to learn anything about getting good at building really good design then you need to make sure that you have a really good spacing scale now we don't need to worry about it because tailin automatically provides us for us which is this default spacing scale for example if you use PX4 then it means it's 16 pixel or one ram and so on so as you saw over here p24 is adding a padding of six Ram here but if I add say PX then it will only add padding left and padding right and if I want only on the y axis then I can just say py so all these utilities are really cool and really great and you will learn more tillin as we build our application further but keep this in mind that I will be focusing mainly on next year and providing you all the tailin sales so you know exactly how they work but I won't be necessarily going in depth in tail in order for us to match the look and feel of the application that is easy cell that we want to build it has a overall theme now although this is not a design course but in order for you to build a really good look looking application a beautiful application and in that case you need to come up with good fonts good colors good spacing skill which a lot of it Tailwind provides us but what we going to do now is set up our project in a way that we are set up for Success so we will configure our Tailwind config file which is our Global configuration file for our application and we will also add a couple of components that will set up our application as well which is the header component here which has the easys cell logo along with the upload Link at the same time we will also have a footer which also just has your company trademark for example this can be anything you want so let's go ahead and do that so now first let's just get rid of the stuff that we don't want let's just remove all of this because we don't really want it we are going to start from scratch here all we need is min eight screen let's get rid of all of this let's just make sure everything is centered and we're going to set the max with to be 100 R next thing we're going to do is go to tailin config file so now what we we're going to do is we're going to get rid of this extend background image because we don't need it we're going to replace theme with these colors remember I said that tilin does have a few colors for example that it comes out of the box with so if you want to extend the existing color so for example gray goes all the way to 950 then we can start adding custom colors at 951 952 and so on next let's go ahead and create a new folder called as components now this components folder will store all our react components here so let's create a header component and let's also create a footer component now again for the header component let's go ahead and create a new functional component and call this header now in the header component we are going to have a couple of things we're going to have a easy cell logo and you feel free to call this whatever you want and we also going to have a upload link as we can see right here we have the easys cell logo as well as the upload link so now what we want is whenever anyone clicks on the logo we want this to be a link so it l link between application and for that we could use an a tag which is very typical we can just say route to the main page for example similarly this will also be in another a tag and then route to let's say product/ upload this page doesn't exist yet but it will eventually so let's just route to it but we don't need to do that in nextjs in nextjs there is a component if you go to the documentation and call which is called the link component it extends the HTML and Anor element to provide prefetching and client side navigation so for example if you want to add linking between Pages for example and these pages in exist inside of your next year's application then you can easily just use the link component if let's say you want to link to an external page altogether then you're not going to get any advantages of the link component because every time this specific link component is on the page it's going to prefetch that data automatically so that we can have that data and user can get a seamless user experience so what we could do is we could just copy the import here and we don't need react inside of nextjs because react is globally available so we don't need to import it but here instead of a tag we're just going to call this link close this with link similarly since product upload is the same as well then we're going to call this link too we'll dive into the link component a bit later as the best place for us to declare the header component is inside layout so what we could do is right above we're going to say this layout is a file that wraps the entire application now we have imported the header and here you can see easy sell and upload if you click on upload not this page doesn't exist but it does route us to it but and if you click on easy cell again it goes back to homepage which is exactly what we want so this is how the header component would be so now I already have the header component styling for us so what we could do is just replace that specific style code for this is already available in the GitHub Reaper so definitely check that out and copy paste the code as necessary now we will talk about this a bit later where we are taking in a font as a prop so we can pass in custom font as well in the future but this is this is very simple code that takes in the font and applies it to the H1 tag now you can see already easy cell and upload links are already here which is awesome now let's go ahead and add a footer as well again we're going to copy paste it have provided it for you but all it does is it wraps with the footer HTML tag and it has some styling it's aligned to the left and this is the the name of my company but you can call this whatever you want now again footer is also going to be over here so now let's just import footer and save it now again as you saw that font is missing inside of footer and header for now so let's just make font optional so that we can add it later on as we configure fonts now if we refresh the page can see we have the header and we also have a footer is exactly what we want similarly we also have have the colors as well now there's one more thing that we need to do we also need to configure our Global CSS file now a global CSS file is essentially a file where you would add in whatever you want to add that needs to be applied globally and we're going to replace this entire file and pass in the styles that I have already provided for us so for example I have already styled H1 button input text area header and so on so we can just use this now one thing you need to keep in mind is whenever you want to ex end and replace and apply styles to directly to these elements there H1 button then you need to use the layer attribute inside of tailin and extend the base but let's say you want to create a tailin component then you can just do layer components here and then create a new component Al together if you want again we won't be diving into that but base is what we would need in this specific case if you go back to our application look at that we actually have our application looking very similar to what we want to build here here which is pretty amazing so what exactly is a link component well link is a react component that extends the HTML anchor element now we use the a tack usually to link between Pages or external pages but the link component I should say is specifically for internal route for example inside of your application if you are the one who has created that route you own the page it's an internal route then you can use the link component but let's say you want to route to twitter.com for example then you don't need to use Link component because it just doesn't make any sense because link component is a special nextjs component that provides us with a few properties that we will take a look at for example it it provides us with prefetching now what exactly is prefetching well it prefetching is a way to preload a route in the background before the user visits it so routes are fetched automatically in the background as the as they become visible to the user so for example over here right now we are only seeing these specific routes but as we scroll down nextjs is going to prefetch these other card elements as well and the data for that and the data for that so that it's available as the user sees it but on a smaller viewport let's say we go to a mobile device for example over here then in that case we not going to see all the 10 cards that we have on the desktop we're only going to see one at a time in that case link component is very powerful because one on a mobile device we don't have a lot of bandwidth we don't have a lot of data mobile data for us so this makes it really handy and useful because link component is only going to prefetch things that are available inside the viewport as the user is about to scroll and now in our case we are building the header and the upload link so for now we don't need to worry about it but for eventually as we build the card component we will be using link component to link between pages and that will make it really interesting for us and we can take advantage of the performance benefits that link provides us now one more quick change we want to also make is the background color here in the easy cell we have a specific back background color but here it's basically white so in order for us to make sure that whenever we get the same background color even when we route in that application you want to change it in a spot that is global and what we can do then is if we go to layout. DSX file here we could wrap children with a div tag and this will have the background color because layout surrounds each and every page this is a perfect spot for it so here let's just add class name and we can say BG gray 951 and we can just also add some padding as well so now you can see we also got the same color as we have over here so let's talk about what exactly server and client components are well your client components are basically react components that we are familiar with they are your typical react components without having any specific server functionality you can write code and it gets essentially rendered on the client that is your browser and but with server components the difference being that they allow you to render and cach the components on the server versus on the browser so the server is doing the heavy lifting let's take a look at a diagram here now typically client components are essentially typical react components so what essentially happens is let's say this is your app with a header and footer and some content on the page and the client which is a browser is is basically asking for data from the server the server is going to get take the data and give it back to you and it could be Json data or any other data and the server is going to go back give back to you this is how it works right now but things are a little different in server components in server components what essentially happens is the browser which is our client is basically requesting for that specific page or data right it's trying to fetch data from the server server components are going to render the components that say header and footer components on the server itself and and only return a specific stream which is not Json but a very special stream to the client and the browser is going to just show it onto the page that's exactly how server components work the main heavy lifting happens on the server versus on the client as we saw in the client components now because the browser in the client components is doing all the heavy lifting and a slow Data Network the data is going to be slow and users will not be able to essentially interact with it but versus on the server components because our servers are typically really fast rendering the data and components on the server is quite fast and it returns a specific stream that the browser is entally displays onto the page and that's essentially the difference between server and client components but you might be wondering well what's the advantage of server components if there are a few advantages for example in the server component now because the client components that is a header and putter now have access to the server we can make any database calls in the server itself let's say in the header component we want to fet some data from the database we don't need to make an additional API request we can just call that data in the server component on itself versus in the client components if you want to do that let's say in typical react application without nextjs or without the server components capabilities we would need to make an API request we are going to basically make an API request right here the browser is going to make that API request and then it's going to lead to an unnecessary Network rter versus on the server side the server already has access to the components to the data so all we need to do is just return the stream to the browser and all of that can be here you don't need to make an additional API call so you don't need to do that additional work and it's going to save your time eventually now the prosos of server components are that you don't need to add an additional API call so you can add all your code in the component itself you can call backhead in the same component like I mentioned and your client bundle is going to be really small because server is going to do all the heavy lifting so because of that your client bundle bundle is going to be a lot smaller and as a result you're going to get a performance boost as as well so that is the advantage of server and client component now I have written a blog post on this topic as well that you may want to check out and really understand the differences between them but there are a few things you need to definitely keep in mind and a few gas that we will take a look at later but these this is the difference between a server and a client component now in order for us to truly understand server and client components let's take a look at one specific example now here in the example I already had a header and fitter now in nextjs any component or Page by default is essentially going to be a server component so this means it's going to be rendered and fetched on the server and the browser is just going to show the stream onto the page now in this example header and footer in our easy cell app header and footer are already created and they both are not client components they both are server components so this means if we head over to the app and refresh the page now if we go to inspect element go to sources in weback internal I want to show something really cool now if you go to the folder app you will not see even in shared you will not see header and footer at all because they are not client components so browser has no business to show them in here in the client bundle but because they are rendered on the server but if we make them client component all we need to do is add a directive here called use client save this same thing here let's add this additional directive use client but this will use client makes this specific footer component a client component same thing for Herer as well we explicitly telling nextjs that hey the browser is going to be responsible for it just like a usual react applications do so let's head over to our page refresh it and now if you head over to webpack internal let's see what what webpack has built for us and if we go to components now you you can see now footer and header are in fact included in the client side bundle this is the bundle of the browser that's our client so these two components are now included because now it's browser's job to fetch and render them and not the server and just like that you know the difference between server and client components and how making a lot of our component server components makes so much more sense if you review our application again just like that we know now that layout page footer header are all server component now let's just get rid of use client for now and this also makes it a server component now when should components be client components well let's take a look at some examples now whenever your components need any interactivity that is they need the browser browser a server won't have access to the window object they won't have access to use effect use client or any of the react life cycle methods then in that case those components need to be a client component so for example if you have event listeners if you want to provide immediate feedback to the user and update the UI show some sort of a loading State and so on then in that case you would need to use a client component if you want to use browser location if you want to use local storage all of these things are available strictly in the browser and not on the server then in that case you want to make those components a client component if you take a look at our components that is header and footer do we think they need to be client components because there's nothing here that makes it a client component it can be rendered and fetched on the server similarly for header yes we are linking from one page to the other but that does not mean that this cannot be fetched or rendered on the server they do not use any life cycle hooks they don't have any browser specific stuff such as local storage or window or anything like that and in that case header can also be a server component now if you take a look at page page as well is a server component but every time you create a new component or a new page inside of nextjs when you're using the app router you need to keep in mind that you need to ask yourself should this need a browser or not can this be done on the server because by default it will be a server component so we can safely keep header and footer as server components same as page for now because there's nothing in page right now but eventually as we add more code and build our application further then in that case we can decide if certain things should be a client component or a server component so for example in this counter example this definitely needs to be a client component because it's using UST state but let's say we don't need to use UST State we don't need to use use effect or so on then in that case it can be a server component so in terms of composition patterns this is a really good table for that what do you need to do want to fetch data make it a server component access backend resources make it a server component not client component keep sensitive information on the server such as access tokens apis Keys server component keeping large dependencies on the server so let's say you're using a really heavy library then in that case those can be dented on the server then we can do that on the server adding interactivity and event listeners such as onclick handlers on change handlers then they definitely need to be a client component same thing for any of the use State and life cycle effects client component browser only apis client component custom hooks that depend on State effects browser only API client components or even react class components than client components as well diagram is a really good handy reference to keep in mind whenever you adding a new component or page in your application now in Easy cell so far we have a header and we have a footer but we don't have any of this now majority of this page has card components so if we take a look at our diagram that I've created for us to talk a little bit more about the architecture we have the header we then have the footer as well so we can add a footer here at the bottom for example and let's just call this footer and now we have all these different cards on the page and these can safely be called as card components they have a name description image and also a price and similarly if you create this one card component then you can use it pretty much in both sections for example you can use it in top products as well as you can use that in all products how about we go ahead and create this card component the real question is should this component be a server component or a client component component well let's think about it do we need any sort of use effect or use state or any life react life cycle hooks well not really because all we need to do is when the user clicks on this specific component this card then we want to navigate to to product/ this unique ID similarly we will be fetching this eventually from the server so this can safely be a server component so for now let's keep this a server component and then revisit this later so what we can do is let's create a new file called as card. TSX now here again we don't need to add the use client directive because this is a server component and we can safely make it a card component now if we just say card but on the page here we can just say let's render the card component all right so now if we go here you can see card did get displayed here which is awesome now we do need some sort of data to render on the cards so what we could do is create an array of different items and then render it onto the page and render these cards so for that let's create a let's create a array of products here so let's just call these products and they are going to be an array of objects so we can call this ID zero name is going to be mushroom orange lamp description is going to be let's just call this mushroom orange lamp itself and let's just add description here and then we can call we can say price is going to be $40 and we need some sort of an image URL as well already have an image URL for us so let's just save that we can just pretty much Loop through that so we can say products. map and let's just call this product and we can just Loop through this list of products now we don't need to do this we can just call this card and close it immediately and now every card component needs a key property so we just pass in key it's going to be product dotname with an ID as well which is again come which can which can come from product. ID see how the structure of the card component would be we have all these different properties so now in the card component we need a few things I'm going to provide the structure for us so let's just get rid of this and save it here now the card component has a few different property right we have ID name description price and image URL which is exactly what we have here ID name description price and image URL we're not passing any of the data to card we are passing key for sure but other than that we're not passing anything so let's just spread all the properties here in card component now as we do that you we should be able to see a card component which is exactly what we want we don't have an image yet but we'll fix that in a second but we do have the styling necessary for us we have the name of the product and we also have a description with a price as well let's quickly walk you through the code as well now this card component takes in these specific props and we are passing all those props here we are setting the max width to be 32 Ram so it doesn't exceed a specific width that's going to be the max with of the card component but at the same time we are say saying that hey it's going to be flex and it's going to be Flex column so that this is where the image would go so we can add this here image URL now we will learn image using the next JS image component just in a second but let me quickly walk you through the rest of the code as well now we have name and we have description here and similarly at the bottom we have price here now tailin has these text utilities apply a combination of CSS Styles such as font size and L height if you use text 2 XL now here's the thing tailin also provides a few utilities which makes tailin really awesome which is line uppercase line clamp to and there's one more trunk it now these ones are really handy so you don't have to add these styling on your own and you can use you can just use these utilities yourself so if you take a look at line clam 2 after a specific number of lines it's basically going to truncate a block of text that's what line clam 2 does and we also have uppercase utility which again if we go to text transform uppercase will turn the text into uppercase all uppercase but similarly you have other case as well such as normal case lowercase capitalize and so on which is again very handy and lastly we have truncate if you use truncate here then if the text overflows instead of wrapping it to the next line and making the card component really huge we are essentially using an ellipses here the trunk it does exactly that for example if we go here and just copy the same description here and make it really long but we are good here because it's not going to overflow and it's going to show this ellipses here which is pretty awesome so that's exactly how our card component is essentially set up now to show the power of the image component let's go ahead and head over to the network tab now if we head to the network tab you should be able to see any of the requests that have been made so now if I refresh the page now you can see all the images that got downloaded for example so these are all the images now we have this image of 81.9 kiloby which is a g image similarly let's also take a look at one more image which which is this lamp so it was 61 and Jeep was 81 61 and 81 now I'm going to open up the responsive site for example which emulates the mobile device so now if we take a look at the Jeep it's 75 kiloby and the mushroom image is in fact 25 KOB and if you remember it was like 6181 or something like that that's the power of image component on different viewpoints next Cas image component is going to detect what View you are on whether you're on desktop or mobile or what type of device and accordingly it's going to download a smaller image or a bigger image so that the quality doesn't get compromised it doesn't cost you performance to download a huge image and that is one of the beauties of next year's image component so if you use the image component in an app which is quite image heavy for example if Amazon were to use nextjs then this specific image component having it to be a different size on different devices is honestly a game changer because the the Amazon app is going to be really fast so a lot of apps do care for that first load because the users don't want to wait around and images can really slow down because if you think about it a lot of our web is full of images and that can cost you performance that's really important for you to focus on images when when it comes to Performance and nextjs image component makes it really easy now that we have our card component let's just add the image and learn the nextjs image component right here component also does a lot it is a very powerful API that we we will be covering in this specific lesson instead of using the typical HTML image element we will be using the specific image component from next image copy this and head over to the code let's just add it over here and get rid of this now image will be from next image so I'm going to import that right here and now if we take a look we have the all tag and we have the source tag in Source we going to take in image URL prop which is what we have defined here and in alt we can just call this the name you can see that it gives us a error saying that invalid Source Prof you typically get this error and you can read more information here but you typically get this error when you haven't necessarily Define the subdomains that you'll be using inside of your project so what we need to do is copy this go to next config and add it here now if you may be wondering what is the host name that we need to add well if we take a look at the app products array that we have here in the image URL we are using rest. cloudinary dcom where I've hosted this specific image on cloudinary so in that case we can just paste what we copied and we don't have any specific Port we just want to allow it on all ports and we want to also allow it on all paths so you can also get rid of that now if you refresh the page you should see an image but obviously the image is not matching The Styling that we want and so let's head over to the documentation for that now what we need is we want the image to be basically the cover of the of the card and we also don't want a specific width and height we just want to kind of match to the parent element so that it just fills in the width and height of the parent itself and so for that let's just set a specific style now whenever we want to add a specific style to the underlying image element we can just pass it in using the style prop so what we could do is if we go to the card component we have the width and height here we can also pass in a style prop and we can say it's going to be object fit as cover we also need one more property which is going to be layout equals fill not have width and height alongside layout so let's just remove it and now as we do that you can see that the image is now a cover now if you head over to optimizing image section in the docs here layout fill is quite important to prevent any sort of layout shift what exactly is layout shift we head over to image sizing one of the ways that images most commonly hurt performance is through layout shift but images get pushed where the image pushes other element around the page now if you take a look at this specific documentation on cumulative layout shift it is a core web vital that means Google is going to rank your website based on how this specific core web vital it's a very very important metric you need to consider so if the images just suddenly bump down the content the user may accidentally click on something that they shouldn't be clicking on so keep this in mind this is a really good example here the user wants to go back but they end up placing an order because the content just immediately loads not exactly what we want so that's what we that's what cumulative layout shift is and scroll down if you click on the specific documentation you can read more on adding always including the width and height and or reserve the required space using CSS aspect ratio but thanks to the image component it does have the fill property which allows the image to be sized by its parent element so if you don't know the size of images that's totally okay so that's what we are doing here we don't know the size of the images but we're just saying layout fill and we need to make sure that relative is also defined here which makes it position relative and using fill the parent element must have position must have position relative this is necessary for proper rendering of the image element in that specific layout mode so that is very essential for us to do that but there is this weird space facing here and that's because of this width that we don't necessarily need so we can get rid of similarly one last thing we need to do is since this is a cover image we also want the round corners to be rounded and for that we could use a property in when called as rounded T so we can copy this and add it in class name here so you can just say class name rounded T there you go so now if you go back you can see how the image is basically rounded the top and top left and top right Corners are essentially rounded which is what you exactly want here let's just add the remaining styling so that we can display all the products and head over to setting up our database let's just add some styling here so again I'm going to provide the styling for us so let's just paste the specific structure here you can also find the same code inside of GitHub again what we're trying to do is we are giving it some styling we are making it so that the layout matches so we are saying that hey these two are Flex columns this is going to be a grid with three columns but as you shrink it's going to be two and one similarly these are four columns at the bottom but as you shrink it's going to be three and then two and then eventually one so that's exactly what we have pasted right here let's just move our card products at the bottom here similarly we can move our products here as well now if we go back to our app you can already see how the app is looking now I've definitely zoomed in here a bit so this is how it will look like but I'm going to keep the zoom back on so that you can see all the content on the page so here you have the all products as well as our top products so now our page is looking really good so let's go ahead and set up super base now super base would be what we would be using to create our database because superbase powers that but any time the user goes ahead and uploads the product from this specific form or any of these existing products all of them are going to live inside superbase superbase is an open source Firebase alternative it's you can start your project with a post database so that's exactly what we would be using but it's not just that it also offers authentication Edge functions realtime subscriptions you can also store a bunch of stuff such as we will be storing all our images in here as well as we'll be storing all our images in here as well so super Bas does a lot now let's go ahead and start your project now I have already logged in because I'm already logged in but you need to sign up using super base and it's completely free of charge so you can just get started so now let's go ahead and click on new project and here I'm just going to call this nextjs crash course but feel free to call whatever you like here I'm just going to select a password and going to select a server closest to me now let's go ahead and create this project so now as the project is getting set up we can see these API keys and we also see this URL so now what we can do is just copy this key and then head over to our editor and let's create a new file here called as n now in here we're just going to call superbase URL and superbase key let's just paste what we copied and also copy this URL and paste that here as well all right so now we have our environment and stored and ready to go now as the project is set up which is just did now we can go ahead and create a new table now what's really cool about superbase is that it does help you a lot and it also gives us this really good interface so we can interact with it without having to fully go command line if you don't want to so for example if you go to the table editor you can create new tables but you also have a SQL editor here where you can create a new table through this specific query and it does have superbase ai to build the query as well plus they also have so many different templates that you can use to essentially create anything you want then we can have our database table stored here at the same time there's a bunch of powerful options here too then Super B also Powers authentication now we won't be implementing authentication in this specific course but if you want to add authentication and extend this course then you can totally do that as well you can store everything here and we will be storing our images here so let's just let's just call the storage let's make this a public bucket and save it so now anyone can upload all the images here what we are going to do is we are going to upload the super super base images that I already have and upload them here now these are essentially the images that you see here so what we doing is we are storing the database with a bunch of different products already so we can query them and show it on to our page so as you can see we have all these different products all these different images so now let's go to our table editor and create a new table so now we going to call this easy sell products feel free to call whatever you like but the more you stick to the naming convention that I'm using then you won't get lost as much now let's go ahead and create a new column so let's just call this name and we can select any of these data types but we are going to use this as a text and we're going to make this a text now over here let's just call this description description is also going to be text then we have image URL also going to be text but keep this in mind that as you select these as you create these new Fields it can be any of these now let's also use price here add price here and then let's make this a float so that it also accounts for any decimals and then we also have a property called as boost which is going to be a boan property and by default it's going to be false now boost is what we would be using to show all our top products so if Boost is true then they will show up here otherwise it's by default false then we also have contact email so so folks know where to contact the person who created the specific listing so now let's also make this text so we already have our table ready to go now one thing I do want to call out is we want ID to be uu ID and uu ID is essentially a function already that they have which automatically will create a uu ID for us a universally unique identifier that it will just generate which is pretty awesome similarly the created ad date will also use now as a default value so what whenever we create the specific table so now let's just go ahead and save this now it's adding the eight columns and creating the table for us all righty so now we have our table ready to go we have have all the fields that are necessary and we have created them which is pretty awesome so now what we could do is we could insert a specific Row one by one or we could import the data from CSV now again I have all the CSV file which you can also download as well so you can just drop it in here now these CSV files is essentially mapped exactly to the columns that we have so which are pretty much the same so we can keep them as is and now let's go ahead and import the data there you go we already now have the list of rows the list of products that we will be using to show here and now you can also see that certain properties are true which is this Jeep which is this mushroom lamp and also this sneakers that's exactly what we see here mushroom lamp Jeep and these sneakers so now let's go ahead and connect super base with our nextjs project so we can start quaring the database now one more thing to note is that as you go to view policies this table is going to return an empty array of results if you don't provide some sort of a policy for example now we are going to just disable Ro level security that means anyone can publicly read and write data into the table now typically what you would want is the authenticated users be able to write and read data but for this specific crash course we'll be only focusing on giving everyone public access to read and write data but feel free to extend it in the future to whatever you like we want to fetch data from subbase and basically fetch the products that we have added inside of our database table is our easy sell products table and we want to show it all on the page here just and replace this dummy data Al together that is our goal for example but before we do that we need to learn how we can fetch data now there are a few different mechanisms that you can fetch data inside of nextjs and I also have this really handy diagram that we will take a look at as well but as we do that one thing you do need to know is how caching Works inside ofs you cannot talk about data fetching in xjs without thinking about caching as well cuz you may Wonder a lot of times why my data is stale I'm doing everything right but nothing seems to work and that's the answer to that is caching so what caching does is that it improves your application performance and it helps reduce costs and unnecessary Network requests so when you do let's say get data from super base then it's going to store that data it's going to cash that data until you tell nextjs otherwise so nextjs does a lot of caching by default fault so what you need to do is understand how it works under the hood so that you can understand what caching mechanism to opt into and how to opt out of so now there are a few ways you can cat data inside of nextjs now request memorization this is very typical for example in nextjs automatically memorizes request that have the same URL and options and memorization simply means that it's going to cash a lot of the request data so let's say in the same network request you're making two requests at the same time then it's only going to call once and just store that and this is very typical in Rea in the react wall use API such as use memo hook for example to cache data and to between rerenders or we also have memo as well which allows you to skip re-rendering a component when props are changed so we are already familiar with memorization in general so next year does this on the server itself and what it does is that it basically tries to avoid making multiple Network requests but this is not the one I'm talking about when I come to caching and stale data what we are mainly talking about is these three things data cache full route cache and router cash when you think of data cache what it does is that it will basically store the data across several user requests and it is persistent so even if you refresh the page it's going to still stay it's going it has stored that data somewhere on the server and you're going to get that same data back so even if you change things in your request because you haven't opt out of caching or if you haven't updated caching the right way way then this specific data will stay the same so this is the data cache I'm talking about the way they do that is by using something called as fetch now we already are familiar with fetch now if you go to fetch on mdn this is the fetch API I'm talking about what nexs does is that it extends the specific fetch API from the browser to add their own flavor of caching so there are three different types of caching you can do in inside of fetch it has a property called as cash Force cash so anytime you use fetch inside of next JS this property is there by default it is it's going to cash all the time and this is what DPS many beginner developers up because your data is going to be stale and you may wonder why it's not updating second is this one where you can revalidate the data and you can this caches for every 1 hour so every 1 hour a request will be made and that data will be stale but the the following one will get the latest request then we have service I rendering which means it will no C there's no caching and it fetches every single time so these are three different ways can call the static side generation incremental side regeneration or server side rendering but if you go back to this specific diagram there's also routing cache so again as the user routes from one route to the other then again it will render and cache routes at build time if you are going from one content to the other and you're trying to fetch data it's going to basically try to access what data it already has and show that to you now again this is an optimization that allows you to serve the cash route instead of rendering on the server again this is is something that it does as well and lastly there's also router cache too that means it will reduce server request on navigation and again this is something that we will take a look at when we talk about server actions but all of these this caching is really important for you to understand when you think of data fetching so the three API that we took a look at was on the server fetching data on the server with fetch which basically means we can fetch the data by default it's Force cash then you can revalidate data that is you every hour or every X seconds you can Purge the cache and refetch the latest data and that is basically time based revalidation you can add this number in seconds and lastly we also have service side rendering which basically means cash no store you want to opt out of data caching completely then you can add cash no store to fetch request these are a few ways you can fetch data and add these different apis itself so now let's go ahead and do super base and fetch data from the server so when it comes to using super base we will be using these specific packages so let's just go ahead and install them so what we can do is just install these packages and then we already have these two environment variables as defined automatically so what we are going to do is just copy this code and head over to our editor and let's create a new folder here called it superbase or I guess let's call this client and here let's just call this file superbase DS and now what we can do is we can just remove use client we don't need it and here let's create a function called as create client now I'm a big fan of the es6 syntax so that's what I'm going to use so let's just do create client our environment variable we don't have next public so we are just going to use it directly inside of our page we can basically start calling super base here so what we can do is go to the super base documentation and then let's go ahead and call whatever we want so in our case it's easy sell products we can basically just select specific columns or or get your data or whatever we want using the superbase API what we can do is just copy this and then head over to our page and then paste it now we do want super base here and we do want to make this an async function so that we can call super base and for that what we could do is we need to initialize the super base instance so here we can say super base and we can call this create client that we got from super base itself now let's just reverse this because this needs to be super base and this can be a client because that makes it more obvious when we import it whoops here this can stay the same and here instead of client super base we'll say superbase SL client all right this looks much better let's make sure that we are fully returning the client itself all right so now here let's just add easy oops sell products and let's just select the products itself so now let's just log them the server again go to Local Host 3001 our page should have run so if you go to the terminal now you can see that all our products are right here we got all the products from the data that means our superbase connection works but I want to talk about something here by default superbase is using fetch internally that means they are essentially using Force cache that means this data is cached now let's go ahead and replace the products data with this data and see what happens so now if I comment this out and let's call this products okay get rid of this all together because a lot of our column names are the same we can select it but we need to handle this condition that if there are no products then what do we do well if there are no products for example we can just for now say not found and we will replace this later so now if we replace the if you refresh the page you can see here that this specific image is not working out because earlier in the card component we are just passing in the URL directly right so now we need to modify that a little bit so what we could do is we can pass say image URL and here let's just say product. image URL which is what we have but we need to give it a domain cuz right now we don't have a domain yet so what we could do is inside of our superbase instance if we head over to Storage storage we do get a unique URL here and the way we would find that URL is by going to this specific location so let's just get rid of this now let's go here and paste it and and let's just save this for now now this specific URL is the same as what we have inside the superbase URL so what we could do is we can access anything any URL with superbase URL so let's go ahead and configure that as well so now if you go here and let's just duplicate it and just paste what we copied earlier whoops we don't need that we need this specific subdomain now let's just paste it to make sure that there's no https here cuz that's what's taken care of by nexts for us so what we need to do is copy the same thing and do it here as well now if you go back you can see the images are showing up already and our app is looking quite good but obviously we need to add another query to filter this but our super base is working as it is so now let's learn a let's revisit our caching data fetching caching principles so now as you remember cash cash is force cash by default so this means that it's these values are cached now they're not going to change so if I go to the database and go to any of these products so let's just go with yellow couch and I'm going to say yellow couch I'm going to say this is a pink couch no more a yellow couch even though it's a yellow couch Watch What Happens this is a yellow couch but if I refresh the page it still stays as a yellow couch there is no word pink here at all or if you want to be even more clear let's replace this value $2,000 with $0 this is a free product but again still 2,000 it doesn't it does not change whatsoever so one way is that what we could do is just get rid of this folder where all are caching is stored we can just restart the server refresh the page again and now you can see that it's actually a ping couch with $0 so now just like that we saw that how Force cash was making it impossible for us to refetch the latest data now if we were to do that inside of this code there's no way for us to do that because we don't have access to fetch fetch is internally called by superbase so now this is fine cuz a lot of our data is going to be static but let's say we change the name or we fix a typo then we definitely want every few seconds or every few hours for the data to no longer remain stale in that case what we could do is we could either choose to revalidate the data every hour or every few seconds or we could just serice side render it all the time so what we could do here in super base in order for us to expose it we can add a property called as revalidate equals z which means our data is going to be fresh all the time so now let's change this value to Yellow couch and $2,000 that we had earlier we can just say $22,000 and this is going to be yellow couch again and if we refresh the page you can already see it is a yellow couch with $2,000 same thing over here as well because the value is now no longer going to be cashed it has taken basically cash no store it doesn't Force cash every single time it fetches data every single time which is pretty awesome but in our case we do want to make sure that we cash it as much as possible because we want our site to be really fast we don't want to refe fetch new data it's not like there there going to be new data all the time maybe want to refetch new products that we add to the superbase t t table maybe every hour or something then what we could do is we can just add 3,600 this means that our data is going to be now fetched every hour which is what we have here it is going to be cashed for every hour and on the hour mark whoever requests the data will still get stale data but the following request will be fresh data which is what we want so that's the beauty of these specific products inside of our application so that is the beauty of nextjs you can basically cash data it can definitely trip you up if you don't understand caching in top products we only want the products that are boosted that means the products that have property equals true and right now we are showing showing all the products so what we need to do is perform another query here and basically filter through the reference tables so we can copy this code go here and again let's just call this we need to change this so we can just say top products and maybe top products error for example and now we want to select all but we do want to say out of all the values give me boost as true and that's the value that we have here so so instead of products here in the first section we will have top products again we need to perform the same condition that if it's null then just show not found so if no top products then not found for for example now it's saying not found well that's because we calling cities which doesn't exist let's just call this easy products there you go so now our top products are also ready to go we have three products which has boost equals true and all the other products are towards the bottom but did you notice how inside of our code when there were no top products then how it the entire page return not found because of this well that's not what we want right because when even if there are no top products it's not the end of the world but if there are no products maybe we don't want to show anything then what we could do is we could say if there are top products then only map through them because otherwise we don't even want to show anything really so now if we remove this condition completely and now in top products we can just move move this what we could do here is make a typo now you can see how it says there are no top products here for example we could say hey if there are top products then only show them else it's going to be a P tag all our products are gone now if I go back to making a typo again then it says all our products are gone we'll fix the padding in a second here we can say PT is going to be 12 and we can make this text Excel all our products are gone and also change the color to be 800 so now this looks more like it where all our products are gone and again we can give this 16 so that it's more aligned again in this case it's not going to be this case at all so we can just keep go back to how it was but now in case there are let's say no products whatsoever then we do want to return something we don't want to return not found like this we don't want to show the page at all because what's the point if there are no products so in that case we what we will do is we will use use the not found file inside of nextjs now if you remember took a look at a lot of the special files one of the special file is not found this means Whenever there is a not found file we can basically replace the content of the page to say hey products are not found essentially and we can also use the code so for example if I open this up when a not found function is thrown so if I throw not found which is imported from next navigation inside my code then also this specific page will get triggered so what we could do is we could say not found from next navigation and let's see what happens so now if I make a typo here and you can see how it says this page could not be found now we could choose to style it but let's just keep it as is for now but this is what the not found file does which is essentially a special file inside of nextjs all righty so now let's go back to what we had and let's just refresh the page now you can see that our page is looking quite good so now what we want is when we click on a specific image we do want the user to navigate to the product page the individual product page where we can fetch more data so right now our app doesn't do that a way we could do that is by using the nextjs component now it is a react component that again extends the HTML anchor link element to provide prefetching and client side navigation between routes so again we have taken a look at the link component earlier but let's take a look at it a little bit in depth again if they are internal links that means we are going from from one page to a another page that is in the same app and definitely use the link component because you will get capabilities like prefetching now what exactly is prefetching well let's take a look now I have our next year Scrat course Theta versal app ready to go it's hosted on a domain so now let's go ahead and make this image maybe a tablet size going to again empty cache and hard reload and now you can see that not as many images were there on the page only five of them are here now let's clear this let's start start scrolling as we scroll more and more images get downloaded onto the page but initially on initial load not all images were downloaded and that is the beauty of prefetching prefetching allows you to basically prefetch content onto the page as they become visible in the user's viewport as the user loads the page and as things are about to come in view through scrolling that is when nextjs will prefetch and that is the advantage of using link component so you want to make sure that you use the link component wherever possible whenever we are routing between pages so to revisit our header component here we are using the link component to navigate from one page to the other let's go ahead and add routing between Pages inside of our application let's just copy this and now what we going to do is in the card component is where we are going to surround this entire component with link why because we what we want is as a user clicks on one card we want the user to navigate to the other one so that's what we're doing here but instead of HRA we are going to basically route to another route so what we can do here is we can say basically route to products if we take a look at a reference here products and let's just give it the ID for example so we are already passing the ID from super base directly into the component so this should work if everything is set up correctly I click on this look at that we did route but if you think about it it this is a page not found because this page does not exist we need to create it so let's go ahead and create it so now in order for us to create a page a dynamic route inside of nextjs the way we could do that is by using box brackets so here we could say products cuz that's the page one to navigate to and then create another folder called as Slug and inside that let's create page. TSX this is how you create Dynamic routes inside of nextjs so now we can just call this page so it will be this now I can just say one hello here and see what happens since we already routed to this specific route it does say hello so if I click on G prangler then again it's a new ID but hello text so now we have created a dynamic route as well so that's what dynamic routes are inside nextjs when you don't know the exact segment names in ahead of time and you want to create routes that could be dynamic in nature for example if we take a look at this diagram then slug is a dynamic route now we don't necessarily know in this case that what the ID is going to be so it's going to be pretty Dynamic and that is why we have defined it a dynamic route so this could be/ product/ 1 2 3 4 5 6 ABCD it doesn't matter because that's the dynamic value and this is how you create the route inside of nextjs but there's also something there's also something called as catch all routes and what this means is we Define it by calling dot dot dot slugs with box bracket and with catch all routes what happens is the value could be slab b/ A/B or SL aab b/ C and so on so these values could be whatever but it was going to be caught in this specific route now what happens then well if I Define 1 to 3 and I also Define a catch all route what would take priority well this Dynamic route will get priority because it's more defined in structure whereas catch all route is going to be caught after Dynamic route so if I say SL 1 to3 it will be caught here but if I say say sl12 3/12 whatever then it would be caught here so that's how routing works and even though I'm using the word routes nextjs uses a word called as segments and that's pretty much the same as well so an app app directory is a root segment dashboard is a segment this is a leaf segment so dashboard becomes a segment this becomes a leaf segment so essentially this would be a dynamic segment route / segment this would be a index route or this would be a catch all segment or route so now we will be building the product page which is this specific page which has an image price if it's a premium product or not and this will depend if the property boost is true or false text and a button whenever you click on the button then and the email application opens up with this specific text bottom there will be description as well with some styling around it I'm going to be providing all the styling and the structure of the page so we can get into integrating it with superbase later on so now what we could do here is what we need is data now now this data could pretty much be copied from here just copy this whole thing and paste it here we can call this data and then just comment this out now this data will essentially be displayed onto the page before we start integrating that with super base so now let me just give you the structure of the page so that we could just focus on building the application so I'm going to paste the structure again it's very similar to what we had does have one additional property which is contact email and boost is false but other than that this basically gives a structure to the entire page we have the description we have contacting the seller and this basically adds a mail to prefix which means it's going to just open up the default mailing application with the contact email portion now we will also have premium product section if data. Boost is true and we have the name and also the image added as well this image does have a fixed width and height compared to earlier but we are basically getting the URL which needs to be replaced with our process. n. superbase URL all right so now if we head over to the page not here over here and refresh the page then we should see the everything look at that now our page is looking quite good but the image obviously needs to change to data. image URL that we have now you can see orange lamp is getting displayed but obviously we are going to quickly replace this with super base so let's just comment this specific URL out over here as well now by opting into revalidate equals 3,600 it means that by default all the pages all the products all the cards in this page are going to be static but then every hour it's going to refresh the data again call superbase and get me fresh data get us fresh data essentially now this is what revalidate 3,600 does but we also need to Define for these individual Pages which data will be static and how it can regenerate all the pages so when we go and run npm run build here this creates a production Bill and what this does is it basically goes through a function called as generate static params and it will statically pre-build all the routes that means it's going to pre-download all the data from super base and then generate all the routes for you now in our case right now it has only generated five pages it has/ product/ slug but it has not pregenerated any of the pages that we have let's restart the server again it has not basically pregenerated any of the pages that we do have that that is that is all all of these Pages if we want the performance of static with combination of dynamic then we need to give nextjs information to pregenerate all the pages and the way we could do that is by using a function called a generate static params it statically generates all the routs at Bill time instead of on demand at request time so what we need to do is implement the specific function you need to do here is Is What It Wants is a list of all the Slugs that we have so what we could do here is again get the superbase client create the function here from here so we can just copy this whole thing paste it copy super base initialize it here and import create client from locally then let's get the second function here and what we want is exactly what they're doing here we are getting all the products so all the products are here now if products are not null then they are going to be returned here so products. map and this is going to be product and this is going to be product instead of slug it's going to be ID because that's what we get from super base if products then that's what it will return so maybe by default if there are no products then it's just going to return an array but if there are products then it's going to just default return all of them you can get rid of array here and this as well what this would do is it would give you the Slugs of all the IDS from super base and this tells next sh is that hey generate all these routes with these specific IDs so then it's going to execute this function so now if we run npm run build again let's see what happens it should say it should give us the list of all the seven IDs now you can see already that all these IDs are created so now these three IDs along with nine more paths that are created for us that are pregenerated for us because we choose to add generate static params function here but obviously the static page stays the same so we need to obviously replace this data as well but this is how you implement generate static parameters njs so what we could do here is instead of getting this data here again initialize the client and now this time what we're going to do is instead of getting just selecting all the data we are going to filter it so we're going to select all the data but now we're going to call match on super base and this could be any query we want so here we're going to say ID from the database is going to be the slug now we don't have slug yet so let's just call data. ID for now and here we are going to return a single record because we know that only there could only be one specific ID which just going to return a single record now we want this to be slug that we get from nextjs and the way we could do that isting it from pams and then defining it as well so let's just Define props here so now we can say type props and params will have there will be params in them there will be params which will have slug as string from the URL as well as there will be search params but we don't need to worry about that for now so here we can just say params do slug now this just returns gets the pams and then do slug so now instead of products it's going to have only one single product so we can just get it from data we can get comment this data out completely so now everything works as expected then you need to restart the server again remember we commented out the URL so let's just do this just copy this and let's paste it here uh back Tex now let's refresh the page and look at that we have been we are getting real data from the database so now if I go back to home go to Jeep Wrangler I see gep Wrangler and it is a premium product because boost is in fact true for just the Jeep Wrangler itself and if I click on contact seller then it does get us to interested in purchasing Jeep Wrangler and opens up my mail client as well so that's exactly what we want so it's finally time for us to talk about server actions and mutations now you can think of server components for fetching data then you can think of server actions for mutating data on the server so they are essentially asynchronous functions that are executed on the server they're typically used on form submission for example upload form is the perfect example for us to use server actions and we will be learning a lot about serve actions validations with Zod and so on so I don't want you to get intimidated but follow along as I teach each concept one by one I also have a video on server actions and mutations so if you want one more example alongside this one then definitely check that out as well so if you head over to the documentation and go to examples you should see that this create invoice is a perfect example of server action we have a form we have this action attribute and nextjs makes it special where we can inject server action and it allows us use server directive here so how about let's just go and try it out now in order for us to use server action we need to create a attribute here called action we need to define the action here so let's just say say sell your item action and now we need to create a function so now in since we are going to do a lot in server actions let's just create a folder called as actions and here let's just create an index.ts file now we are going to make this an async function sell your item and now we are going to declare this a use server this makes it a server action now in order for us to use an inject server action like this in a separate file we need to use a hook called as use form state so we can just copy this hook and here let's just paste it now let's import it from react Dom and in the function here will be sell your item action which we're going to import and there will be some initial State now form will no longer take action directly but instead now it will take the return type of form action from use form State because this is the one that manages updates the state of our form and in initial state we are going to have two things message and errors this way if there are any errors we can show show it to the user and so on for now let's just Define this as any all right then let's go to actions and now action is going to take previous data or previous state and it's going to also take one more attribute which is form data which is of type form data now let's just console log form data let's go to our server refresh the page and let's just hit add you can you can see now form data does get printed but obviously we want specific values inside form data so for that we could say that okay let give me the name in form data let's see what happens so I'm going to say is a name and let's just hit add and you can see Ana right here so this is how we could pass data from the form to the server actions itself now what we going to do is Define the form completely and use a typescript for schema validation Library called a Zod static type inference and what this Library does and it allows us to perform for form validations on the server side way we could use a function called as safe pars we Define the schema and call Save pass and it will return two things to us it will either give us a success or a error if there's a success then it will give us data if not then it will just give us why what was the problem so what we could do is just copy it and paste it in here now we definitely need to define the schema so let's do that say schema is going to be Zod Doob but first let's just install Zord as Zod got installed let's restart the server and now let's import Zord here so we can say import Zed from Zord destructure it just like that now schema is going to have the safe par property but this is where we could start defining the schema itself we could say that hey this just like the user object we could say that hey our form is going to be this whole object and it's going to be of type string or if it's going to be of type any of these primitive types primitive values and then we can basically Define more things such as make sure that the email has minimum five characters or make sure it's a number and so on so what we could do is just copy this part and now let's just declare it here here it would be name and string same thing for description then we also going to have contact email price is also going to be string and the reason why price is a string is because form data has a limitation where you cannot have a number as form data so it needs to be a string itself now let's define image in a second but let's add some validations here so in the schema we can say hey I want name to be minimum four characters I want description to be minimum five characters I want contact email to have minimum one character and it needs to be email itself and if it's not a valid email then we can just say this is not a valid email address similarly for price we can make sure it's actually minimum one and then for IM URL we need to do something more so this way we can add our schema definition here and now we need to basically parse the data from form data now notice how we got name from form data similarly we need to get a bunch of other fields as well save pars we can just create an object and say name is going to be form data doget name Des so now we have our schema and defined and we're passing it safely as well now if it let's just call in of result let's just call this validated fields and if they're not successful then let's throw an error or let's return the data so now here instead of error we can just say return type is going to be error and here return type is going to be success this way we can check for that if you want but type is error then errors are going to be validate fields. error and then let's just flatten them and call field errors similarly let's just enter the message as well saying that some Fields were missing failed to create product we're just adding some validation here similarly if that it is successful then we can just return successful instead of just adding it here we can just return data type a success so console log the error here so we can say error validated fields. error so let's just check we get all the data necessary so we can just say name oops name then we have description we have contact email let's see what happens enter like it's like I said it does give us a validation message like we want it fresh the page and do this again and then let's add the lamp and the email now you can see that we have all the information here we have the file we have all these details now in case of any errors we definitely want to show that over here so that we know we are not making any mistakes While submitting the form so for that reason now we're just returning type success let's make sure that if there are any errors then we are also sending those as well and we don't necessarily need to return anything for success for now let's just handle the errors so if you go to the upload page here and let's just add this as any for now and now at the bottom we want to make sure that there are errors here so one thing we could do for adding errors is basically handle them if in server actions if you're returning errors and the type is error itself like we say over here and in that that case we want to show this message to the user we want to show whatever message that comes up this is the message that the for full form sends us when we submit but then there were other messages that we saw as well so do here is right above the form we can say state. type is error then you want to handle it specifically then we can say is error and then let's let's wrap that up in error and we can see state. message like we discussed close it now already have the styling for it so let's just paste that here now if I had submit now you can see it says fail to create product missing field which is what we want so that's pretty good but we also want to show all of these values because so that means that's an error array itself and we want to show the message from that so for that we could do state. errors try to look for those accordingly so again WR underneath name we can say if state. errors. name then we want to show a span here with state. errors. name. joint join so we are separating them if there are multiple errors and we are joining them all now again we can style this as well so now if I hit submit you can already see that string must contain four characters is already displayed here similarly we want to do the same thing under [Laughter] prise perfect so now you can see all the errors underneath it which is what we want so if I hit add without submitting it then you can see all these things so we know exactly what the errors are so that's how Zord makes our life so much easier because it is so such strict validation that the user can see what's going on when it comes to entering information inside the super based database on the form submission it's going to be pretty straightforward because here we have the insert API we're going to insert all the details as an object we're going to get all the data from from from Zod schema parser and then enter it all in the database tricky part is going to be image URL now remember we had to upload all the images in our bucket called storage so what we need you need to First do is whenever a user submits a form you first need to upload the image in the bucket and then reference it in the database that's exactly what we're doing here that's why we have these random IDs so what we could do is use the storage API at the storage API here which basically means that we just get the files and then upload them so let's just copy this and then go to server actions and paste the code so if it's not success then don't do anything return the error otherwise just do this but there's one more thing we need to do we need to also create a special superbase server action client because we're invoking now superbase inside not a browser but inside of a server so for that we definitely need to create a server action client so we could declare superbase here and then create server action client and pass in the cookies now these cookies will some will be something that can be retrieved from next headers and then we can get the superbase client create server action client from superbase Au helpers nextjs we just need to fill this data we were at data and error storage and then from this would be the bucket name itself and we just called this bucket name storage so let's just keep that this would be the name of the image and this would be the actual image itself so we could retrieve all the information now because we know that name image URL then we have contact email we have description rice all of that could be we could get it from validated fields. dat and let's add this whole thing in a track catch blog so that way in case of any errors we can also catch them so here you can just add console error error error perfect so now as usual we want to make sure that we return the error so again type is going to be error this way if there are any problems then you want to make sure that we are we're handling it so we can just say database error fail to create product perfect that's a lot of code and I really am glad that you're following along with me but we are very close to uploading the storage data and then we are going to up insert the data as well so now over here let's just give it the file name so what we can do is the file name could be math. random and I'll tell you why that is hyphen and here we could have the image url. name now the reason why we are adding matt. random is because if I don't add this math. random value then I a user could enter the same name image and this would mean that it would just replace that image that's not what we want so for that reason we're adding this unique number so this is the math. random value and now this could be file name and this could be the image URL itself but there's one more thing we need to have is we're going to also add cache control so that the image gets cached in the browser and at the same time you're also going to say you're not going to override the file if it exists for example this way whatever file is there stays all right so now we have this so if it's an error just in case then we want to say type is going to be error and the message is going to be database error fail to upload image this will we know that there's a problem with the image but if there are no there's no problem with the image itself then we are good and now we can perform insert as well so for that let's just go to the documentation and here let's just copy this now we can just paste it and we are going to call this easy cell products and now we want to just return everything from here and this could be products error and we want to return everything from here except we want to make sure that we get the path from data and that's it now we are going to just get data. path from superbas Storage as we get that then we can just add that path here this way we are storing this specific path inside of our image URL column we we can reference it later all righty so now we only want to call data. Path if it exists so let's just move all of this inside here all right so now we have a lot going on we have so many things that we have done so but we also handled errors so hopefully if we made a mistake then we should be able to see it let's refresh the page and now let's add the mushroom lamp the redefined that been that we've been wanting to 3,400 description let's add mushroom lamp here and let's just give it the email address let's hit add and it says database error fail to create product which is what we want if there's an error so let's see what the error is here it says either next public super are required for this specific server action client we need to make sure that this is actually in fact next public so so that it gets exposed to it so what we need to do is just copy next prefix it with next public so now wherever we are calling super base we need to make sure that we are passing it next public itself so now in the client over here we want to make sure we passing it next public URL similarly we are passing super and on key as well now we need to restart the server because we updated the environment variable now let's refresh the page and try again mushroom lamp redefined 400 description let's add the lamp all right now it says that new row violates roow level security policy now what we need to do for that is we need to go to storage policy so when we hit storage click on policies we need to create a new policy and create a policy from scratch here we need to say let's give access to all so we can just insert update delete to everyone and default to all if none selected and let's just hit review and save policy that's all we need to do so now if you go back and hit add you can see that nothing happens but the error goes away and looks like like it has worked so if we go to table editor and go to products we should see a new product look at that mushroom lamb redefine has been added you can see the image here as well but now if we go back to easy cell so we need to change one quick thing here it says undefined but rest of the URL is quite defined well that's because after we changed the superbase URL to say next public we did not really change the prefix of that so we need to also call this next public otherwise it's not defined in environment anymore do the same over here as well hide the page itself which is right here as well as right here now look at that P have all our cards rendered and ready to go and the mushroom lamp that we just created which is mushroom lamp un redefined is also added here with the values extracted if I click on the image then we also see see the description that we added that mushroom lamp defined and if I contact the seller then it's also at me me.com which is awesome so this means our upload form is ready to go so let's say I add kemx coffee for example and here I'm going to say 900 bucks again KX coffee coffee whatever and for now let's just give it a image upload a coffee image and again just give it whatever for example and hit add now even though the image and this specific product is added in our database we refresh it you can see that KX coffee does get added but in our page it's not necessarily showing up at all and that's because of caching well we know about this already we talked about this in the caching section but if we take a look at revalidating data inside of server action you need to purge the nextjs cache inside the server action so if we take a look at the nextjs cache I mentioned earlier it also has the router cach and the full route cach essentially we need to revalidate it basically we need to purge it so now let's just go to actions import revalidate path from next PATH from next cache and right here let's just call revalidate Path and let's just say slash this means that we are telling nextjs that hey there is some new data please revalidate the path but if I click on ADD and I re go here you can see there are two chemx coffees now and we will delete one of them so not to worry but at the same time we also want to redirect the user to a new page whenever there is a success you also need to redirect it can use the redirect function from next navigation and then again redirected here so we can say revalidate and redirect now it will only reach here if there is data otherwise it's going to throw an error for example so we can also say here if products error then we do want to return a error as well so for example we can copy this paste it here and here instead of f to upload image we can say fail to upload product now let's try it out again but if we go here and let's just say KX coffee 3 and let's hit add the minute we do that we do get redirected and chemx coffee 3 is added this means we have purged the cash essentially now in order for us to show the loading State inside of our form so whenever we go to upload this button should say change from add to loading and we should show that the form is in progress otherwise the user is going to keep hitting the add button and we are going to see multiple products of the same type even though they intended to upload only one product well what we could do is the next JS server actions again there is a react edform status hook that we could use this is from the from react and it is still an experimental hook so keep that in mind but what you could do is it will give you the status information of the last form submission which is views form status so what we could do is again if you go to the usage you will see how it works all you need to do is add this copy this and then go inside of your form so here let's just paste it import it from react Dom and now the button is going to be replaced with this information now if you go all the way at the bottom what we need is just copy this these values you already have type as submit and over here let's just add this instead of add instead of submitting let's just call this loading and instead of add let's just call add now let's just go ahead and try it out now if we go to our form and let's just add KX coffee 4 $20 let's just add the same duplicate values let's add coffee from here and then let's add a dummy email now when we hit add again again nothing happens we do get redirected we have chemx coffee 4 but we did not see the loading status and this is one gotcha you have definitely need to know about server actions what we need to do is we need to extract this into a separate function otherwise it's not going to work so we need to create a new component Al together called as submit button. DSX and here let's just paste this get the use form status and we can pretty much just copy this button paste it here similarly declare submit declare submit button here the gotcha here is you need to make sure that used form status is a child of the form and not in the same form itself all righty so now that we have this if we go back to our form and hit upload let's add kemx coffee 5 make it $90 description is going to be five description again let's add coffee search for it now here and hit add now you can see the loading State and and once it's done loading that's when it redirects and shows it on the homepage and this is how you can Implement loading States in server action as well so now it's finally time for us to start looking at improving our discoverability on search engines and for that we will be using something called as SEO now SEO stands for search engine optimization search engine optimization is a way for search engines to recognize what's exactly on your site so for example if we head over to to our easys cell app right now let's say we open up the browser developer tools and we head over to the Head element in the in the page now there is no description of what this specific mushroom lamp is the title is create next app which is not the title of this specific product and there is no image as well located or associated with the specific lamp so if someone were to take this link and share it with their friends they're not going to see any image as well just to recognize that this is a good product that's what we would do in SEO as the user looks for best mushroom lamp the search engines are then going to work behind the scenes as they look into their database to figure out which site to best serve for this specific query because they want to make sure based on your location based on your preferences based on what you have searched in the past based on the different websites and their ranking they basically rank different websites based on those categories now I won't be diving into too much into how that works you can look into the SEO starter guide here on how the Google search works and how the SEO is divided into crawling and serving different web pages and how the ranking Works in general and this is a really good guide to take a look at as well but to give you a quick overview in SEO the search engines are working really hard to make sure they give the results that the users are looking for so let's say they look for best mushroom lamp and in return they're getting results like orange lamb CB2 mushroom lamp top five mushroom lamps and so on now based on the title based on the description underneath every image every title so for example there will be some description here underneath it underneath every element as well as we see it on Google for example based on that specific description users are going to decide if they should click on the site or not now most likely if you are on the first page of Google the chances are higher that the users are going to click on it but what makes it so that that the the search engines are able to recognize your site well there are quite a few things but few of the basics are your site should have a really good description it should tell you exactly what the title is it should have a canonical URL that means it should point to the right product when the user clicks on it it should have proper semantics that means we should use image element for for an HTML image we should use paragraph tags appropriately for text we should use different headings for different items and so on so if your semantics are not right then search engines won't be able to tell what what's exactly on your site and then there's a lot more that goes behind the scenes in SEO then you need to look at but these are a few things that we will be configuring in this specific section of the course now just like you and I we are talking in English search engines use semantics and all these different things that we talked about to communicate with the website because initially when search engines crawl your website all they're going to see is an HTML page and that is also a beauty in nextjs because that's also known as pre-rendering for example if we go to the site that we have deployed and let's say we head over to the inspect tag now we are going to go ahead and disable JavaScript here JavaScript is fully disabled now if I go to the page source for example you should see all these different tags along with content we are able to see a fairly semantic driven site for example and that's because we are have used the right tags we have Rec recognize what the content is and before the JavaScript loads this is exactly what the search engines are going to look at and that's why it's important that your semantics are right because they're not going to care for what styling your app has they're not going to care of what JavaScript it has but because of this specific step in nextjs it makes it really exciting because search engines can discover the content on your pages so this is also known as pre-rendering going back this is what we will be focusing on this specific section we will be adding all of this inside of our application so next xjs has a metadata API that we will be using to configure our site for SEO so this specific metadata API allows you to Define your application's metadata so for example we can add metadata which is the description title different open graph images and so on now if you're not familiar with open graph then definitely take a look at the open graph protocol which allows you to define the different tags that search engine uses to recognize what's on the site so for example this is the OG title type you URL image and so on go ahead and configure our site metadata if you head over to the layout page you can see that there is this object that's already been exposed which is called the metadata it's already been exported as metadata now this is the metadata API that I was talking about again it's sayest it's basically used to describe all the metadata fields that can be set in a document and you can read more on all of those in the next year's documentation but for now let's just go ahead and say it's going to be a easy sell website and this one let's go ahead and Define what the website is as well let's just paste this thing and this is going to be the description for our website so if we go ahead and now take a look at our app you should and if you refresh the page just in case you should see there's a title now easy cell but at the same time the meta data description also has what we added in the app now what we also need is some sort of an OG image as well as well as a canonical URL now if we head over to the nextjs document ation and we should see the different ways in the API reference section for how we could configure all of this as well now what we are doing is we're focusing on adding static metadata that means we don't have anything Dynamic we are manually entering everything but we also may need to generate something Dynamic for things like the orange mushroom lamp or all the products as well we will get to we'll get to that in a second let's go ahead and configure our sites open graph image so if you look for open graph here you should you should be ble to see how we can configure a image let's copy this and here let's paste open graph now this image needs to be a image that we can share for example this image needs to be an image that when this website is shared can be shown we just need an open graph image for this one and now I already have it ready for us for example so this is the image for our open graph so anyone shares our website this is exactly what they will see so now if we go to our public folder where we would be storing all our assets we could create a folder called as assets and then move this open graph image there now we can just say assets SL OG image.png again if we head over to our website and refresh the page then in the head element we should be able to see the open graph image as which is right here now again we want to make sure that this specific URL will be changing when we deploy it whatever but since it already takes in the domain we should be good but let's call the this G canonical URL now what this is going to do is if process. n. noen is production or I guess if it's not production then we want it to be the host we are on so we can just say HTTP Local Host 3001 or it's going to be this is going to be the URL now let's not add any slashes towards the end because that's something that should be taken care of and now if we head over to our layout what we could do is convert this into into a back tck so that we can add the function that we created can say get canonical URL and then add it right here so this is how you can add the open graph image as well lastly we also need to add a canonical URL too and the way we can add canonical is by adding a attribute a property called as alternates and this is how you can Define the canonical URL like it says here so we can say canonical again is going to be canonical URL that we just defined so again it's going to be this on local host or this other one when we deploy it but we also need to add it specifically for the slug page as well we need to configure it in such a way that we are able to generate it dynamically and that is where the dynamic metadata comes in play in Dynamic metadata we would be able to generate data dynamically and basically dynamically generate the title open graph images and so on we could do is inside here let's dynamically generate that the metad data so what we can do is just just copy this code and paste it in here now we need to implement that from next and we don't necessarily need search prams right now you already have props which we have defined here and again we also need to get metad data from nextjs now instead of ID it's going to be slug because that's the ID we have and we need to fetch the data accordingly now we are we already have some code for that because we are already fetching it so let's just copy this code entirely and also just paste it in here now now what we want to say say here is we are going to enter title as empty and description as empty if there are no products for example what we need to do is essentially match the specific product ID and for that we need to copy this code instead and then paste it in here CU we are going to get the single product so let's just say product over here so if there is no product then it will return an empty title and description and we will also comment this out as well we don't we don't have any previous images and now now what we going to do is also add description and that's going to be product. description and instead of title this is going to be name and in images instead of this value it's going to be the image value itself so what we could do is create a function called as get image URL because as you can remember we also have this in several different places so what we can do is we can just call this function get image URL and pass in data. image URL accordingly now if you head over to a utils file and create a new function here called get image URL then we can use it wherever we want so we can say return get image URL and let's just add back tck here now instead of data. image URL that should be the job of the the file calling the function so we can just pass in image URL which is going to be a string now when let's just import this now whenever we want to add any sort of image we can just use this so again let's just just paste this and here instead of data it would should be product. MH URL so now we have been able to generate title description and open graph and all we need to do now is generate the canonical URL and in this case the canonical URL is going to be get canonical URL function that we have defined and then slash the name of the product for example so we go to slash products and then we also add in the slug as well so we can say ID is going to be the slug now again we can just use ID here because we have defined it right here all right so now we have a lot going on here let's go ahead and test out and make sure everything works as expected now if we go to that our easys cell website and now let's just go to a mushroom lamp is our favorite one so far look at that we do have the title as mushroom lamp we do have the description as well and OG description OG title and also an OG image so if I copy this and paste it it is the right image as well then in terms of canonical you URL also have the canonical URL accordingly because it's exactly this URL on Local Host but it changes when it comes to deploying on production which is going to be a domain so this is how you basically create a metadata for specifically individual Pages now let's say we want to create a metadata for the upload page as well so what we could do is we could basically copy this whole thing but in order for us to add metadata inside of the upload page we cannot just export it we need to add it inside layout so for that let's just create a layout file and here we can export The Meta data for example but what we also need to do is basically expose get it get it as children and expose it for example let's copy this and if we head here we need this this is going to be the layout file and we need to expose the children over here as well and we don't need to add it around any div we can just return the children import all the necessary UT PS here for example and metadata can be from next now in terms of upload we can just say easy cell upload and in terms of description we can just say upload your files easily or I should say upload your products easily using easy cell the image could be the same image and the alternates could be the canonical URL and it should be get canonical URL slash products SL upload because this is the URL that we have all righty so now if we go to upload as well it should have a title a description a image and so on but if we get rid of this image alog together it does still does have the image because layout does have the image so this is one way of overriding the metad data by passing in its own layout inside of upload when they search something and if our product show up then users should be able to tell as well as search engines what's exactly on the side so this is how you configure metadata and all the OG tags in nextjs nextjs would automatically optimize your form so they do have a next font package which includes builtin automatic self hosting this means you can automatically load your web phones without any layout shift that we talked about earlier and the good news is that you can automatically self-host any Google fonts you like now in our case we are using two different fonts one for the header easy seller and the other for the rest of the code so let's go ahead and configure that what we need to do is go to layout and let's close close this one but you can see that there is a font enter by default it's a great font but if you want to change it we can easily do that too so we will be using two fonts here nanito and Josephine Sans now nanito is going to be this specific font and Josephine is going to be this font add something like cute font here and this could be Nito default font by default the entire application is going to get the Nito font so you're going to say need your default font. class name and then if you remember header did have a font property that we made optional and now pass in font equals cute font do class name similarly we're going to do the same right here and again make this not optional so now if we go back to our app and refresh the page now if we head over to inspect and if we just hover over this one you can see the Nito font has been applied now similarly if you hover over this one then you can see that the font is in fact just so this is how you can tell that your fonts have been applied ACC correctly but in terms of fonts themselves there are other things as well that you could do you could also host your local font using a local font import from nexj again you can do next font local and then pass in the font and store that easily inside your public folder all your assets are going to be stored but you can play around with so many different fonts that you want to show on the page and make your app look really good lastly let's just go ahead and clean up our application so here if you see let's just remove unnecessary comments and there's one more tweak we need to do which is that we need to make sure that we're using this function everywhere we're using the domain so if we take a look at the page itself can get rid of all of this and at the bottom over here we can just pass in product. image URL here similarly we could do the same at the bottom as well so that we are using the same same function everywhere can remove any unused Imports we're just making sure that we cleaning up our application as we are getting ready to deploy it don't need to console log it unnecessarily so lastly if you review review our application accept the form where we definitely need to make sure that we are we have onchange handlers and form works as expected is when we are using a client component but rest everything in our app is a server component so this just goes to show how how a majority of your app can be a server component and can survive without having the client functionality and this makes the application but it makes a performance of our application really fast there's this one message that we keep getting saying that Meta Meta database is not set for resolving social open graph or Twitter images so if I go to this specific URL then we do need to set this specific URL and then the alternates could be the remaining path which makes our life really easy so what we could do is go to layout location is set up and here we can just set the URL and again we can still use the same function that we set up but we now no longer need to add this to every URL we want and this could just be slash for example similarly if you go to the individual Pages don't need to add canonical URL because that will automatically be included over here as well we don't need this because it will automatically includeed because layout will have the meta database itself the second thing we need to work on is the layout fill layout fill was available to us in a previous nextjs version but now the equivalent is using fill equals true which works the same way so if we go to Local Host 3000 and run our application the errors that we were seeing earlier are all gone because we have resolved it so that is why it's really important for us to learn learn how to run the production Bill and see what errors might come up before going and deploying anything thank you so much for checking out the specific crash course if if you did please subscribe to my channel and comment below and let me know what other crash course that I should create now as next steps check out this specific video on how you can add transitions to your app using frame or motion and a very special file inside of nextjs or check out this other playlist where you will learn all about next year in depth so I'll see you in the next one bye for now