Build and Deploy a Modern Next.js 13 Application | React, Next JS 13, TypeScript, Tailwind CSS

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
next 13. a react framework so powerful it became the new standard for creating react applications and recently its interest peaked which means that now is the perfect time to build a state-of-the-art next 13 application to Showcase your abilities in this course you will develop a modern car showcase platform that leverages all of the latest and greatest of what next 13 has to offer a minimalist hero section will be a Gateway into our complex search and filtering capabilities that will leverage nextgs's server-side rendering features establishing application routes implementing advanced search and filtering capabilities handling and displaying data in chunks optimizing applications metadata and SEO creating custom filter combobox and model elements maintaining a well-organized file and folder structure embracing the principles of writing clean code and much more the entire application is fully mobile responsive this app is perfect for all car enthusiasts and due to its complex functionalities and the ability to leverage next js's newest feature it makes for an exceptional educational course you must watch if you want to become an expert next GS developer specifically we'll be transitioning from client-side rendering to server-side rendering unlocking the next jss full potential after we develop the application I'll even teach you how to deploy to the Internet so you can share it with your friends potential employers and put it on your portfolio now you might be wondering what are the prerequisites for building such a great application you need to know the basics of modern web development using reacts.js other than that this course is entirely beginner friendly if you're completely new to react I would recommend checking out our react crash course then if you haven't already watch our latest nextgs crash course first by clicking the card that'll appear on the screen or click the link in the description and then come back to build your first real next gs13 application by watching this video in the last video we've revealed that we are working on the ultimate next 13 eBook that covers everything you need to know to become a professional next.js developer this ebook covers the complete nextgs roadmap essential next year's Concepts new next 13 features extensive guidance on building scalable next JS projects and project ideas you can build and deploy to put on your portfolio and get a job this ebook is the most resource we have ever created so we put it up for sale as a paid premium ebook thankfully as the last time the first 1000 people that clicked the link in the description will get it for free so sign up right now to find out if you're in the first 1000 definitely don't miss out on this opportunity alongside building this application you'll learn the most important Technologies needed to make any website next yes Tailwind headless UI typescript and Concepts like mobile responsiveness and API management we're going to start simple and move to more complex Concepts I'll explain every step of the way if this video reaches 20 000 likes I'm recording more next year has 13 videos now before we dive into the project there's something exciting I need to share with you the app you'll build today is a light version of a more complete application our master class students have built in the program so after building this next gs13 app you can develop its more detailed web version by join the master class the JSM masterclass experience helps Junior and intermediate developers Fast Track their careers you will develop real world applications in a team which is more challenging than simply following a YouTube tutorial but this also means that you will learn so much more from the experience you will use modern tech Stacks get personalized mentorship from senior developers and get exceptional hiring support you can graduate in six months land your dream job in the six months after graduating or get your full money back if you want to apply click the link in the description or go to jsmastery.pro forward slash masterclass and apply Now by filling out a 15 minute quiz I'll personally reach out to you before we officially begin with the next cohort so you can be sure not to miss it with that said let's dive right into the course [Music] before creating a folder for our project code we must first visit rapid API the link is going to be down in the description the making of this entire app is Possible only because of Rapid API we're using their cars by API ninjas to allow us to get detailed information about every specific unique car model to use this API click the rapid API Link in the description and then you can click sign up or log in I will log in in this case since I already have the account and once you're in you'll be redirected to Rapid apis Hub where you can find hundreds of thousands of apis this was our first step in our video now let's create our great car showcase app and then later on we'll call this API Straight From Within it with that said let's get started as we always do on the JavaScript Mastery YouTube channel we're going to start from bare Beginnings by creating a new empty folder on our desktop let's call it car underscore showcase you can open up an empty Visual Studio code window and then drag and drop the empty folder into it once you're in you can go to your top left View and then terminal this is going to open up the integrated built-in terminal which we're going to use to initialize our project as you already know by now in this project we are using the latest version of next JS so let's set up a nextgs project by running MPX create Dash next Dash app at latest and then we can use the dot slash to create it in the current directory and press enter it might ask you if you want to install create next app in that case simply press Y and then enter then we're going to get a quick questionnaire of how we would like our app to be set up so first of all we have to say would we like to use typescript and in this case we're going to press yes then it's going to ask us if we want to use eslint I'm going to say no then Tailwind of course we're going to use Tailwind when it comes to using the source directory we're going to say no and finally we are going to use the app router would you like to customize the default import Alias we're gonna say no and that is it all the necessary dependencies to run our sample next GS application are getting installed there we go the process has been successful and we can run our application by running the npm Run Dev command this is going to spin it up on localhost 3000 so simply Ctrl click it to open it and as you can see we have this beautiful new starter by resell for the new nextgs application now let's put our browser and our editor side by side so we can see the changes that we make live there we go let's explore the file and folder structure of a new modern x13 application we're going to have the app folder which is going to be our Central hub for working with our routes and pages and the only other thing we have is the public for our icons and assets everything else we're going to add ourselves we can start working on our application by going into the app and then page.tsx inside of here we can remove everything that is within the main directory so just keep scrolling down and let's create a clean slate for ourselves to start working on this great application if you save it you should see just an empty screen let's start by creating a bit of a layout so we know where what is in our application first we're going to give this main a class name of overflow Dash hidden and if you're unsure what some of these class names that we add mean that means that you must be new to Tailwind CSS but not to worry Tailwind CSS is a really simple utility first see SS framework packed with utility classes but behind the scenes it is nothing more than CSS so if you're wondering what a specific class means simply go to quick search and search for it right here you're gonna immediately get the answer of how to use that specific class so at any point in this video if you're unsure what some of these classes that I add mean simply go to Tailwind docs go to search and type it out you're gonna immediately get an answer also I want to point your attention to a great Visual Studio code extension called Tailwind specifically it is going to be Tailwind CSS intellisense it's going to allow you to hover over specific properties and get these specific styles that it's applying so you can see the Overflow hidden of course is applying the Overflow hidden Style and with that said we can start creating the layout of our application and just to be able to see the code better I'm going to zoom it out one time so everything fits in one line wonderful immediately within our main we can start creating our hero section which is going to act as an entrance point to everybody wondering what this app is all about so if we open up the finished site just so you know we're building something that looks like this on desktop devices we have a nice left side text and then right side image and if we collapse it to a tablet view or a smaller laptop it's going to look something like this so let's go ahead and build this simple hero section so that we can get started with the more advanced functionalities such as search filtering and server-side rendering so let's get started by calling our hero component right now if we call it we're of course going to get an error saying that the hero is not defined so what we can do is go to the Explorer and then we can create a new components folder in the root of a directory right here the reason why we didn't create it in the app directory is because with the new next 13.4 syntax in here you only want to put Pages layouts and specific next 13 files that are going to be presented as a route in the application and everything else we want to have outside So within our components we can create a new hero.tsx file and yep you heard that right it's going to be TSX for typescript this is one of the First videos on the JSM YouTube channel in which we're using typescript but I know that you've been asking for it for a long time so here it is if you're happy about this and if you'd like me to do more typescript videos please comment down below so that I know that you guys are happy we're transitioning JavaScript Mastery to typescript projects with that said inside of here we can run rafce this is going to create a basic hero component and if this didn't work for you that must mean that you don't have the es7 plus react react native Redux Snippets extension installed so simply install it and that's going to allow you to Simply spin up a functional component so with that said in here we're gonna import image coming from next forward slash image and we can start creating the structure for our hero section but first of course we have to import it within our page.tsx so what we can do is we can create a new file called index.ts right within our components and we're going to use this file as a single file that's going to export all of our components so we can import them in a simpler manner within the pages where we're gonna use them so let's simply say import hero from dot slash hero and then we can say export hero right here that's going to allow us now to go back into page and then you can select the hero and press Ctrl space on Windows or something similar on Mac and it's going to allow you to immediately import it if that didn't work for you no worries you can still manually import it by simply saying import inside of curly braces hero from add forward slash components that is great and as you can see we are now rendering the hero component which looks something like this now to make the styling of our application just a bit simpler I prepared some utility classes that we can use throughout the rest of the project you can think of this just as a nudge in the right direction because it's going to allow us to focus on what matters which is learning typescript learning nextgs server-side rendering and more and not necessarily just focusing on styling so in the description down below you can find a GitHub gist that's going to contain a globals.css file simply copy the code go to the app and then override the current globals.css by deleting it and pasting the one you copied as soon as you do that you're gonna get an error saying that apply text black Dash 100 does not exist and next.js is right here it doesn't and that's because we have added that as a custom style inside of our Tailwind config.j yes so once again in the same GitHub just down below you're gonna find the updated tailwind.config.js simply copy it and then we can override the current one right here that's going to fix the error if it doesn't you might do a hard reload which is Ctrl shift and then r on Windows and that's going to fix the error if the error is still there simply open up the terminal press Ctrl C and then y to stop it and then finally just re-run it and then you should be able to see just a single string that says hero on our home page we can close the global so we can close everything and just jump into the development of our layout and the hero section to start creating our layout we can first give our div a class name equal to Hero this is one of those utility classes that we have created and if you're wondering what it does you can simply go to ourglobals.css and search for hero and then you can see that this is going to apply some Flex properties extra large Flex row usually Flex column Gap relative and so on this is going to just make the styling a bit simpler and cleaner finally we're gonna remove this text of hero and move down below within dot hero div we're going to create a new one with a class name equal to flex-1 padding top of 36 6 and padding of X which is going to apply some horizontal padding within there we can create our primary heading which is going to have a class name equal to Hero underscore underscore title here we're using the bem methodology where we specified that the hero is the block and then the title is the element within that block once again if you're wondering what any of these classes mean simply go to search and then find the CSS directives for them to see which styles are being applied it's primarily going to be changing the font size and font boldness inside of here we can say something like find book or rent a car quickly and easily there we go and we can use a long Dash right here simply Google for the long Dash and you should be able to find it and we have a huge heading right away below the heading we're going to have a P tag that's going to have a class name equal to Hero underscore underscore subtitle there we can say something like streamline your car rental experience with our effortless booking process there we go this is looking good and then we want to render this button that you can see right here that's going to point to explore cars but immediately I want to teach you about reusability and creating components that we can reuse all across the page you're going to notice that most of the buttons are gonna end up being similar so we want to have one component that can then be abstracted and changed depending on where it is being called and that's exactly what we're gonna do for this button so let's create a new custom button self-closing component and of course if we call it right now we're going to get an error that's going to say custom button is not defined so not to worry let's go into our components and let's create a new custom button dot TSX component there we can also run rafce and we can also export it right from our index.ts where we can say custom button and we can also export it right here now if we go back to our hero section we can double click it and then import the custom button right here by saying import custom button from dot slash custom button and the error should go away that now allows us to control click into the custom button and start creating this great reusable component inside of our button we can import image from next forward slash image as some of our buttons are going to have some kind of icons as you can see right here and we can start creating the structure of our button by wrapping everything within a button component this button is going to have a couple of States first of all sometimes the button is going to be disabled right now we're going to Simply hard code that to false but later on we can modify that then the button can have a couple of different types it can be a submit button or just a regular button so later on we're going to pass this dynamically but for now we can simply hard code a string that says button then we want to give it a class name now this class name is going to have a custom BTN class but then later on we might want to add some additional class names so we're going to leave this as a template string so we can add the classes later on and of course it's going to have an on click which for now we can leave as an empty callback function we're going to update it with the corresponding logic later on now immediately as soon as we provided an on click function it's going to say that we need to convert this into a client component and that's great we can thank nextgs for doing that because by default all components in next.js are server side rendered they're called server components but this button is just going to be a client-side component which is usually the case when you have some browser actions such as clicks or using hooks so if you watch the next JS crash course that we recently posted then you know what we need to do if you haven't watched it already even though you've Dove deep into this video right now I would recommend to posit bookmark it somewhere else and go watch the next Jazz crash course because it's going to make the watching of this video so much more educational if you have the foundations laid out with that said what we need to do is use the use client directive to turn this component into a client-side component and that's going to fix the error for us then we can create a span element within this button and it's going to have a class name equal to it's going to be template string of flex dash 1 and we're going to make it a template because later on we can pass some additional styles and we can render some kind of a title of this button so for now we can simply say title and there we go we can see it right here now how do we turn this into an actual reusable component well the way you do that in react and xjs is through props so depending on where you're calling this button you have to pass some additional props to it so in this case we can go back to where we're calling this button and we can pass some props in this case that's going to be title which is going to be equal to explore cars then we can pass some additional container styles which are going to be BG Dash primary Dash blue text Dash white rounded Dash full and margin top of 10 or Mt 10 for short finally we need to provide the handle click which is going to be equal to a function that's going to allow us to scroll so on top for now we can create a new empty function called const handle scroll which is going to be an empty hero function for now and once we click the button we can pass the handle scroll function with that said you're going to notice that if we save it our typescript is going to complain it's gonna say first of all you're using some kind of a handle click right here that must mean that your hero is a client-side component and indeed it is so right on top we can use the use client directive to turn it into a client component then you're going to notice that we have one more error or a warning right here saying that our title property is not assignable to our button and that's because if we go into a button we're using typescript but we're not specifying what props can it get so what we can do is we can create a new file or rather a new folder in the root of our directory called types and then within those types we can create a new index.ts file inside of here we can export and create an interface an interface specifies how a specific structure should look like what variables and values should it have and in this case we can create a custom button props interface and it's going to have a couple of things as we said it's going to have a title which is a string it's going to have a container Styles which is going to be optional and it's going to be a string and finally it's going to have the handle click which is going to be a mouse event handler specifically an event handler on the HTML button element and that's going to look like this and this mouse event handler has to be imported at the top from react so that's going to look something like this and the handle click is going to be optional as well which means that we can add this question mark because sometimes it's going to be a submit button so we don't necessarily need a handle click now if we do that you're going to notice that the error right here should disappear or rather it's going to disappear once we actually accept these props into the button so right here we can destructure the props that's going to be a title a container styles as well as a handle click and now we have to specify which props does this component receive and that's going to be custom button props and of course we can import that from add forward slash types just like so now if we save that you're going to see we have no errors typescript is no longer complaining and we are ready to actually utilize these props and turn this into a reusable button first of all to our button we can pass additional Dynamic container styles this is going to make our button look like an actual button and on the handle click we can pass the handle click function which in this case is a handle scroll and most importantly we can pass a dynamic title and there we go we have our explore cars we have the title and it is looking great now we can go back to our hero section and continue by creating this wonderful image that we can see below so to do that we can go below the custom button and Below one more div and then we can create a new div that's going to have a class name equal to hero underscore underscore image Dash container within there we can create one more container div that's going to have a class name equal to Hero underscore underscore image and finally within we can have the next JS image tag that's going to allow us to pass a source and now in here we have to pass the path to our actual image so far we don't have any assets in our project besides some icons for next anniversal which we don't really need so please allow me to give you all of the assets we'll be using throughout our project in the description down below you can find a new zipped public folder so simply download it unzip it then delete the current public folder and simply paste or drag and drop the new public folder right here within the root of our folder there you're going to have access to a lot of different icons we'll be using as well as the hero Dash BG and the actual hero car image which we'll be using for our hero section now once you have your public folder it's going to be really easy to specify the source it's going to be simply dot slash hero dot PNG our image tag also needs an ALT tag which is going to be a hero it's going to be fill and it's going to have a class name equal to object Dash contain for it to remain in its aspect ratio and you can see that the next image must start with a leading slash which means that we don't want to do the dot slash it's just gonna be slash and our car appears now below our image we also want to create a new self-closing div that's going to have a class name equal to Hero underscore underscore image Dash overlay and this is going to give it that nice effect that you can see this rectangular shape appear that is great now our hero is looking wonderful it is exactly the same as here but we're missing this simple navigation bar as well as a simple footer so before we move into the main part of this application let's quickly add the navigation bar and the footer not in here in the main page but rather by utilizing the next js's layout so if we go into the app folder and then to the layout.tsx you can notice that in here we can specify what our page is going to look like of course it's a body that's going to show the children but above or below the children we can render some different things out and in most cases you want to do something like this first of all we don't need this font right here then you have our metadata which is incredibly cool because right here you can simply say car Hub or whatever you want to call it and that's immediately going to change on top right here of course once the error is fixed and the description can be something like discover the best cars in the world there we go and of course the class of our body is simply going to be relative we don't need that font right there and if you do that you can see the car Hub changed on top and now what you usually want to do in your applications is show the nav bar above the body and the footer below the body so immediately right here we can create a nav bar self-closing component as well as a footer self-closing component and then you want to of course create them within our components by creating a new navbar.tsx file where we run rafce and you want to create a footer dot TSX file where you run rafce and we go into the index.ts and finally we create or rather we import both the navbar as well as the footer and then we can export them right here navbar and footer not filter it's gonna be a footer and finally we can now go back into the layout we can double click the nav bar and then get it imported same thing for the footer so that's going to be import footer and nav bar from add forward slash components if we save this you can see that we have a simple text that says nav bar on top and footer on the bottom which means that we are ready to control click the nav bar to go into it and start creating a really simple navbar layout to do that we can import a link coming from next forward slash link because after all we're going to use the navigation bar to link to different pages and then we're going to import the good old image coming from next forward slash image finally we're gonna also import our trusted custom button component because we'll be reusing that reusable component we created before making our workflow even simpler now for our navbar we don't want to wrap it in a div rather we want to wrap it in the HTML5 semantic header tag and give it a class name equal to W Dash full to take the full width absolute and then Z index of 10 which is going to allow it to show on top of the other content then we want to use the nav tag and give it some class names first we want to give it a Max W Dash and then inside of square brackets 1440 pixels that's going to be the max width then we want to set the margin X to Auto make it a flex container and specify justify Dash between this is going to ensure that the items show on the left and on the right side finally we want to Center them vertically by giving it items Dash Center on small devices the padding is going to be 16. usually padding is going to be 6 and we're talking about the horizontal padding PX and PX here and then the pying vertical is going to be 4. this now allows us to add the link tag and every link needs to have an ahref in this case it's going to point to forward slash which is just home and it's going to have a class name equal to flex justify Dash Center and items Dash Center inside of it we want to have an image which is a self-closing tag and it's going to have a source equal to forward slash logo.svg of course it needs to have an altag as well which is going to be car Hub logo a width of 118 pixels a height of 18 pixels and then it's going to have a class name of object Dash contain to remain in its aspect ratio and that's going to show this wonderful car Hub logo finally on the other side of our navigation bar meaning outside of the link but still inside of the nav we want to create our custom button and check it out how easy it is going to be right now we can create a custom button give it a text sign in give it a button type so BTN type in this case it's going to be button and give it a container Styles equal to Tech stash primary Dash blue rounded Dash full BG Dash white and then min-w Dash instead of square brackets 130 pixels now it's going to complain because if we go into our button you can see that we don't have a property called text and I accidentally type text and not title which is great because it immediately lets me know hey you cannot put text there but now it's also complaining about a button type that's because in the custom button props we don't yet have a button type so if we go into the custom button props let's add an additional BTN type property which can be either a button or it can be a type of submit so that's going to look like this button or submit and it can also be optional so now if we go back we can now accept that BTN type and we can simply put it right here under type by saying BTN type or button now if we close this and go back to the nav bar you can see it's no longer complaining and we have a wonderful sign in button on top right with that said our hero section is looking a bit more complete because the nav bar is there as well and if we open it up and expand it it is indeed looking great now the next thing we can do is focus on the footer as well since we're already here so let's close the nav bar and simply go into the footer component inside of our footer we're gonna also import the image tag coming from next forward slash image as well as the link tag import link coming from next forward slash link finally we can start creating the footer structure by giving it a HTML5 semantic footer tag and wrapping everything within it now bear with me we will have to add a couple of class names to achieve this specific structure where we have a line and then we have a couple of different rows and columns that expand depending on the screen width so let's create that structure right away we're going to start with the outer container by giving it a class name of flex which is going to make it a flex container and then Flex column which means that the flex children will appear one below another we want to give it a text Dash black Dash 100 as well as the margin or mt5 on top we want to give it a top border so border Dash t and a border Dash gray Dash 100 is going to be the Border collar so now if we go back we should be able to see a line but it's barely visible next within the footer we want to have a div that's also going to have a class name equal to flex Max Dash MD is going to be Flex Dash coal meaning on medium devices it's going to be Flex Dash call then we want to give it a flex wrap that is going to allow it to wrap the elements no matter the width justify Dash between gap-5 to provide some spacing between the elements on small devices padding X is going to be 16. usually padding X is going to be 6 and padding y meaning on top and bottom is going to be 10. within this div we're going to have another div that's going to have a class name equal to flex Flex Dash call justify Dash start items Dash start and gap-6 finally we can render this car Hub image right here by rendering the self-closing xgs image tag and giving it a source equal to forward slash logo.svg same as in the nav bar the alt tag can be logo width is going to be 118 pixels height is going to be 18 pixels and class name is going to be object Dash contain if we now save this and go back you can see the logo and the line right here below the image we want to have a P tag that's going to have a class name equal to text Dash base and text Dash gray-700 to make the caller a bit grayish finally we can say something like car hub 2023 put a Break Tag right there and then say All Rights Reserved and then put the and sign copy semicolon this is going to allow us to have that copyright sign right here we want to go outside of this B tag and outside of the div and create a space for our footer links so this is going to be a div tag with a class name equal to footer underscore underscore links inside of here we want to map over all of these different sections the about company and socials as well as all the links within it you never want to have this data within your jsx you want to put it somewhere separate because this is considered business logic and not necessarily what's included in the application so to simplify our life so we don't have to type it all out I've created a constants.ts file in the GitHub gist that is in the description down below so go there and copy it and then together we can create a new folder called constants and then within the constants you can create an index.ts file and paste what you just copied I want to teach you how to do a proper application not just put all of this content within the footer itself so as you can see this is nothing more than some manufacturers which we're going to use the years of production the fuels that exist and finally the footer links which are consisted of the title and then the actual links with the URLs this way you can simply add a new one delete one and it's going to be reflected straight in the code so with that said we can go back to the footer and we can import those links by saying import footer links coming from add forward slash constants then we can scroll down and we can map over them by saying footer links dot map we're going to have each individual link and then we can have an instant return by simply putting the parentheses for each link we're going to return a div and that div is going to have a key equal to link.title then it's going to have a class name equal to footer underscore underscore link within that div we want to render an H3 and that H3 is going to render the link dot title that's going to be the category we're rendering so if you save it you can see about company and socials and let's make that bolded by giving it a class name equal to font Dash bold great now below it we can do another map by saying link dot links dot map and then in there we're going to get each individual item and then we can simply return a link element for it that link has to have a key equal to item.title it's also going to have an href property equal to item.url and it's going to have a class name equal to text Dash gray Dash 500. finally inside of there we're going to say item dot title now if we save it you'll be able to see that all the links show and we have almost a finished footer we just need the bottom part right here of course it might look a bit weird like this but if you expand it you're going to notice that it nicely wraps to the width of our device finally let's do that last part which is that line and then privacy policy and terms and conditions so to do that we can go below this div with the footer links and then create one last div that's going to have a class name equal to flex justify Dash between items Dash Center Flex Dash rap mt10 border Dash t border Dash gray Dash 100 on small devices padding horizontal 16 usually padding horizontal 6 and padding vertical of 10. finally within it we can render a div and that div is going to have a class name equal to footer underscore underscore copyrights Dash link and within it we can simply render the link that's going to have an href equal to forward slash and a class name equal to text Dash gray Dash 500 and within it we can simply say something like privacy policy we can duplicate that link and then inside of it we can say terms of use if we save it you can see that we have a structure that looks like this and we're just missing the copyright on the bottom so right here above our div containing those two links we can create a P tag that's simply going to say at 2023 car hub All Rights reserved and we can save it there we go now this fits nicely we have the All Rights Reserved and privacy policy in terms of use and as you can see right here the privacy policy in terms of use is getting connected to this it seems like the Justified between is not applied and on the finished side they're nicely put one to the left and one to the right it looks like we have to close this div that we had before on the top right here so we only have two divs before the footer we need to remove one and close it sooner we have to close it after the footer links so if we now save this you can see everything is structured nicely because we have a div right here for the footer links and that is together within this Flex justify between and then the last part is on its own on the bottom with that said if we now turn this out to be a full width application we have a wonderful looking footer as well as a navigation bar and finally we have the hero section if we compare the two they're going to be I was about to say the same but we definitely have some differences so it looks like this shape is not appearing right on our side it's getting a bit cut out so let's go ahead and make sure that that shape is right because that makes this button look so much better than here so going back to our code to finalize the hero section we can go to our components and then hero and here we are using the self-closing div with the hero underscore image Dash overlay but I've made a mistake this image should have been closed right here so one div that's going to get closed is for this image and then the div is right next to this div not next to the image if we fix that and expand it you can see that now it is looking perfect and with that said we are ready to transition to the most important part of our application which is the car catalog it'll allow us to search through the different models as well as modify the fuel or the year of the car and all of this is going to be server side rendered so let's get started by collapsing our browser closing the hero section and going all the way to our app page.tsx we are done with a hero and we're also done with everything in the layout such as the nav bar and the footer and we are ready to continue with our home page of course the next part of the home page as we discussed is going to be the car catalog so great job for coming this far into the video and let's get started to get started with the car catalog below the hero we can create a new div which is going to act as a wrapper div for the catalog so let's give it a class name equal to mt12 to divide it a bit from the top and padding Dash X also padding Dash y this is going to give it enough space for it to act as its own section and we can give it a Max width so it takes the full width of the screen finally we can also give it an ID equal to this cover so once we click the above button we can dive into this section great within this div we can then create a new div that's going to have a class name equal to home underscore underscore text Dash container and this is going to be of course the container for the car catalog text so right inside of here we can simply create an H1 element give it a class name of something like text-4xl and font extra bold and within it we can say car catalog if we save that and scroll down you can see it right here and below it we can create a P tag inside of which we can say explore the cards you might like okay this is better already and right below this div we can focus on creating the filters so we can create a new div that's going to have a class name equal to home underscore underscore filters inside of there we're going to render a couple of things first of all we want to render a self-closing search bar component and below that we're going to create a div it's going to have a class name equal to home underscore underscore filter Dash container and within it we want to have two custom filter components the first custom filter is going to have a title equal to fuel and the second one is going to have a title of year so now if we save this of course we're going to have a couple of Errors because these components don't exist yet so let's go ahead and get them created by creating a new component in the components folder called search bar dot TSX run rafce inside of there and we can repeat the procedure by creating the custom filter dot TSX and again run refce inside of there now as we discussed we can Import and Export them from our index.ts so right here we can do the search bar as well as the custom filter and we can export both of them search bar and custom filter if we now save this and go back we can now double click and then command or control click to automatically import it from components if that didn't work for you you can scroll all the way up and import it like this import custom filter and search bar from add forward slash components and you should be able to see a search bar and two custom filters which fit nicely in the layout same as we have it here search bar on the left or in this case on the top and then on the right side we have two custom filters this is looking great now even though typescript is complaining a bit because we haven't yet specified the props to this custom filter component no worries we're going to do that later let's focus on the search bar first so let's control click to go into the search bar and let's start implementing first of all its looks and then soon enough its functionalities right within the search bar we can transform our search bar from a div at the start into a form element and give it a class name equal to search bar we can also give it an add submit property which is going to be equal to handle search for now we have to Define that handle search above so we can say const handle search is equal to and just leave it as an empty callback function we're going to get back to it soon now as soon as you have an on submit that is a browser event so we need to transform this into a use client directive there we go this is working and now within the form we're going to have a div and this div is going to have a class name equal to search bar underscore underscore item like this we're going to have two items in the search bar the first one is going to be the manufacturer and the second one is going to be the model even though they might appear to be the same we have gone ahead and added extra functionalities to the manufacturer where it's not just a search bar it is something known as a combo box or an autocomplete search where if we expanded you can start typing the manufacturer and then you can select them based on the predefined array of manufacturers so let's go ahead and Implement that so-called combo box right away to implement it we're going to create a new reusable component and we're going to call it search manufacturer of course if we now save it it's gonna break because this component doesn't yet exist and we can create it by creating a new component search manufacturer dot TSX and we can run refce inside of there and finally export it within our index.ts that's going to look something like this search manufacturer there we go and the error should go away if we export it and then import it properly in our search bar it's going to be coming from import search manufacturer from dot slash it looks like it didn't pick up the import properly an alternative is to just put it within the curly braces and then just get it from dot slash like this because we have exported it from that component right here and it's within the same folder now we'll be handling the state of which manufacturer is currently chosen so in this case we can import use state from react another reason that we need to use the use client component because we're using hooks and then immediately right here we can say use state we can call it manufacturer set manufacturer and at the start it's going to be set to an empty string and I'm going to expand this just a bit so we can see it more clearly now that we have the manufacturer and set manufacturer we can pass those State as props to our search manufacturer like so of course typescript is going to complain at first but once we go to the search manufacturer and accept those props as we should it's going to be fine so right here we want to accept the manufacturer as well as the set manufacturer and we have to say that this is equal to search manufacturer prompts and of course we have to Define the types for that so alongside the export interface custom button we can do export interface search manufacturer props and of course that's going to be just the manufacturer which is going to be a string and the set manufacturer which is going to be a function that takes in manufacturers a string and doesn't return anything it's just a Setter state now with that said we can here say search manufacturer props and import it from add dot slash types like so and with that we can start creating this wonderful combo box to create it we'll be using headless UI headless UI contains completely unstyled fully accessible UI components designed to integrate beautifully with Tailwind CSS and it gives you a couple of things that you can use such as menu list box combo box or the autocomplete which we're going to use modals and more so let's look at the combo box or the autocomplete it looks something like this you have Wade Cooper and then it allows you to start typing and then immediately see other people as well so headless UI is really great if you want to use some of the components that they offer out of the box if I'm not mistaken we'll be using the dialogue or the modal as well as transitions for some animations and we'll be using the autocomplete so with that said let's get started with implementing headless UI autocomplete first of all we have to install headless UI and we can do that by stopping our application from running and then running npm install add headless UI forward slash react once it is installed we can simply rerun npm run Dev and be good to go then at the top we can import the combo box as well as transition coming from add headless UI forward slash react finally we can start with the layout and I'm going to collapse this just a bit so everything fits in the screen we're going to give this div a class name equal to search Dash manufacturer and inside of there we're gonna immediately render a combo box component within the combo box we'll have a div and that div is going to have a class name equal to relative and W Dash fool now if we save this and reload the page because otherwise we won't be able to see the changes we make because we reloaded the application now we get an error saying that you're importing a component that Imports client only it only works in client component but none of its parents are marked with used clients so they're components by default maybe you should try marking one of these as a used client so right in the search manufacturer you can say use client and if we reload it it works which means that we can proceed with creating our combo box the combo box is going to be consisted of a couple of things it's going to have a combo box button like this one then it's going to have some kind of an input and then finally another button to submit the search so what we can do is first we can render the combo box dot button we can also give it a class name equal to Absolute top Dash 14 pixels not 140 just 14. inside of there we can render a self-closing xgs image tag it can have a source equal to forward slash car dash logo.svg it can also have a width of 20. height of 20. a class name of margin left-4 and finally an altag equal to car logo but as you can see we haven't yet imported the image so at the top we can import image from next forward slash image and if we save that we should now be able to see this Volkswagen button right here appear which is great that's going to be our placeholder meaning that we can type in different car manufacturers or car makes whatever you prefer next we're going to have an input so below the button we can render the combo box dot input it's going to be a self-closing component that's going to have a class name search Dash manufacturer underscore underscore input and a really cool thing about headless UI is that it's built on top of Tailwind which means that you can simply provide a class name in tailwind and it's going to work we can also give it a placeholder we can type something like Volkswagen and this is looking good and we can also give it a display value this is something you have to provide to an input and this is consisted of a callback function that gets the value and then displays the value and since we're using typescript we have to say that the value is of a type string right here finally we're going to have an on change and in the on change we have to update the value so let's go ahead and create a new state by first of all importing use state from react and then we can create a new use State snippet by saying query and set query and that's going to be an empty string at the start that's going to be the search query and on the on change we can simply say we get an event and then we can set the query to be equal to e.target.value so once we change the value in here it's going to be changed now right now this is just a regular input but we want to turn it into a combo box so that once you start typing it actually gives you some predefined options so to do that below the combo box we can create a new transition that's going to just provide us some animations as well and a transition has to portray itself as a specific element and in this case we don't want to add additional elements to the Dom so we can simply import fragment from react and we can say transition will act as a fragment like so then on that transition you can provide additional properties that are gonna animate it so we can do something like leave is equal to transition ease in and duration 100 this is going to make sense soon we're going to say leave from opacity 100 and leave to opacity 0 and then after leave we have a function that's going to Simply clear the query now within this transition we can put some elements and in this case we're going to put the combo box dot options again we're talking about these options right here in our case it's going to be different car makes so before we go ahead and add some Styles let's first map over all of the options it would have been simpler if I call these makes instead of Manufacturers but since we started calling it that away let's stay consistent now in this case we want to filter out through the shown manufacturers but we only want to show the ones that the user is searching for so if we start typing something with an a we don't want to show a B and W which starts with a b or doesn't even contain an A so first of all we have to get a list of all the manufacturers and then filter it depending on the search query where are all the manufacturers well we can import them by saying import manufacturers from add constants if remember correctly I provided you with a list of all the manufacturers and if you're wondering where I got this I simply went to Cha GPT and I said hey give me a list of all car manufacturers and thankfully you have to make a check they have to correspond with the API we're gonna use soon so in this case we have the manufacturers but we need to filter them out based on our query so we can say const filtered manufacturers is equal to query is equal to an empty string so if query is equal to an empty string then we're going to return all manufacturers but if it's not if query exists then we can do manufacturers dot filter and then do a filter you pass a specific item and then you provide the conditions based off of which you want to filter it so let me first indent this a bit more nicely so you can see what's happening so we're first checking if we have a query if we don't have a query return all manufacturers else return the manufacturers which we're going to filter in the following way here we want to say item dot to lowercase dot replace and in this case we want to replace all the empty spaces we can do that with a regular expression where we have S which is an empty space plus and then G Global and we want to replace all the empty spaces with an empty string and then we want to check if the search query we have or rather if the manufacturers were filtering through include the query that we have which we also lowercase just to ensure that we're searching everything as lowercase and then we also replace that query with the same regular expression so we are removing empty spaces from the query removing empty spaces from the manufacturer list and we're ensuring that everything is in lower case great again we had to do some detailed extra work but this is to ensure that whatever our users search be that Volkswagen with a lowercase V or with an uppercase V or even if they put some spaces before or after it it's still going to work so we always have to be careful of what people are searching for great so now we have this and we can first of all close this properly by giving it one more parenthesis and then we can utilize the filter manufacturers to show some options So within the combo box options we can first show an empty option meaning if we don't have any filter manufacturers so we need to make a check for that by saying filtered manufacturers and we're gonna not do the dot map first but rather we're going to check the linked and check if the dot length is triple equal to zero and if the query is not equal to an empty string meaning if it exists in that case we want to show that empty option so we can say and end and then show the combo box option like so and it's going to have a value equal to query and a class name equal to search Dash manufacturer underscore underscore option and it's going to say something like create and dynamically query so we want to let people know that they can search for something meaningful like so and this is the case right now because it doesn't exist so if you search for a a nothing's gonna have beer so this is only going to be the case if we don't have anything but if we do so we don't want to use the end end here we want to turn this into a ternary at the end so if we have nothing then we show nothing otherwise we're going to lube through all the possible options so here we can say filter manufacturers.map where we're going to get each one of these items and then for each item we want to return something specifically we want to return a combo box dot option since we're mapping over it each option needs to have a key which is going to be the item itself and it needs to have a class name now combo box option allows us to pass a function as a class name where we can de-structure the active tab that's going to allow us to turn the options as a template string so we can style the active option differently from the non-active option all the options are going to be relative and they're going to have a class of search manufacturer underscore underscore option but for active ones you can provide additional class name such as BG Dash primary Dash blue and text Dash white and for non-active ones we can have a text Dash gray Dash 900. there we go so now if we save this we're going to see that we have a couple of Errors first of all we're missing one parentheses right here to close the combo box secondly our combo box option also needs a value which is going to be the currently selected item or the manufacturer and then within it we want to show something maybe for now we just want to show the item to show what it is now if we save this we're most likely going to have some more errors and we do it says right here that we have the unexpected token div at the search manufacturer which is all the way at the top which means that something is not properly closed so in here we're closing this we're starting a new one and then we have to properly close it at the end there we go once we fix that we can see that we have our search and if I start typing a thankfully you can see all of the options that include the letter a in them if we start adding more letters for example we want to go for Audi we can do a u and then only one option appears so this is looking great and now that I think about it we don't even need this create because in our case we cannot create anything so the only thing we have to do is just filter through them so if we do this it's going to simplify our code significantly and if we save it it should still behave and work in a similar fashion if a search for something doesn't exist it's not there and else we get the options great so of course whenever you take some code out of somewhere you have to know how to make it work and how to adapt it to your own needs great or we could have simply taken this which is the final example from the code and you can see it's quite similar to what we have in this case it might be cool also to show nothing found that's going to be up to you but in this case we want to style our options just a bit differently to match our design so right here instead of Simply rendering the item we're going to show some different things let's do this and thou bear with me see how they're doing it on the final website instead of Simply rendering a div they have this weird structure right here since this is a built-in component they implemented some additional logic into it so you can open a block then open a function like so and then right here the structure be selected and the active and that's going to allow you to know which one of these is currently selected or active So within there we can simply return a react fragment and then start rendering some code so let's do that right away within this fragment we can see what the combo box or the Headless UI team did themselves and we can copy their example all the way from the top span to the bottom where they close the fragment and we can paste this code now if we save it you're going to see that we're going to have some errors or at least I would hope we would maybe when we start typing yes you can see their example is done using people but in our case our example is going to be using cars so in this case we're not going to do person.name we're going to Simply do an item because that's our car manufacturer and we have a span right here at the bottom indicating which one is currently selected we don't necessarily have to show an icon just a span is enough now if we save this and scroll down and start typing you can see that we have some options but we cannot really see what's happening inside of here so let's look into that together the reason why we cannot see anything is because we are never returning it as you can see right here I put a curly brace instead of a parenthesis so right here I'm gonna remove that and simply show a parenthesis at the end as well which signifies an immediate return and now we can see all the car brands and if we select one and we're gonna know which one is currently selected so this is looking great to me let's test it a few more times by starting to type something and selecting wonderful with that our combo box is getting much closer to being done but of course right now it's not yet doing anything it's just allowing us to browse through all of the cars in a really nice manner but of course we have to pass that data along somewhere to be able to search for it and make use of it for that the combo box accepts a couple of properties it accepts a value which is going to be equal to the manufacturer and it accepts a unchanged property which is going to be set manufacturer now if we save this and try it out one more time there we go Volkswagen is selected and even though we cannot see anything now we're selecting the value in the state within the search bar is getting updated which is all that we need that's going to allow us to later on actually filter through the cards data that we have wonderful now it might not make sense to proceed creating the other part of the search if we don't have anything to filter yet so what do you say that we immediately jump into fetching the data from the API fetching all of these great cars and then we'll have something to filter so for now we can close all of the currently open files and get started with fetching all of this great data from Rapid API more specifically we'll be using cars by API ninjas it has only one endpoints in within it it allows us to do everything we want so what you can do is you can click subscribe to test it is completely free it's going to lead you to this subscription page and you can subscribe to the basic plan with 3 000 requests a month which is going to be more than enough for our needs there we go once it's subscribed you can go back to endpoints and you can start exploring what properties can you pass to the API endpoint we can filter out everything from the model to the make to the minimum City mileage per gallon maximum City mileage per gallon and we can do a lot of stuff right here cylinders transmission year Drive fuel type limit and so much more but for now let's make a test endpoint to see how the data that's going to get returned looks like it looks like each car has 12 different properties and it looks like we're getting five cars per page we can definitely modify that later on that's just the default limit so this is looking great to me now we can go back and we can actually make a request to this API based on the keys that rapid API provided us so simply click copy code right here collapse the browser and then create a new folder called utils in the root of your folder this stands for utility functions within it you can create a new index.ts file and for now simply paste what you copied right here this is going to be everything that we need to make that request and now that I look at it we don't necessarily have to use axios we can simply use the good old fetch there's nothing wrong with axios we just didn't install it in this case so let's proceed with fetch I'm going to override this and now we have the good old fetch right here now we have the URL we have the options and everything let's go ahead and create a function that will be able to use to make a call to that API that's going to look something like this export async function fetch cars for now we can leave the params empty later on we're going to pass some props to it and inside of here we can provide the headers for Rapid API and the headers are within the options so simply copy them and right here say cons Heathers is equal to and then paste the headers right here that's going to be the X rapid API key equal to this key right here and then X rapid API host equal to the URL of the API then we want to Target a specific endpoint you can see here we have the base URL so let's go ahead and copy this URL paste it right here and we'll be able to slightly modify it so we can see const response is equal to a weight Fetch and we want to fetch this specific URL by default it is a get request now we don't want to just fetch the main one where the cars is always set to Corolla we want to be able to modify it so for now let's simply fetch all the cars and then later on we're gonna pass additional properties of course for this to work we have to provide a second parameter to our fetch which is going to contain the headers equal to headers that's going to allow us to get this key in there as well now of course your key right here is going to be different because you copied it from your own rapid API account finally to parse the response as Json we can say const result is equal to await response.json and then we can return the result which are the actual cars and we can delete all of the things that we copied before from Rapid API because now all of it is contained in this nicely packed fetch cars function which is a so-called utility function because now we can reuse it across different files first of all let's go back all the way to app and then page.tsx inside of here we want to make use of all of those cars so what we can do is right on top below the home we can say const all cars is equal to a weight fetch cars we can import those fetch cars from add forward slash utils and believe it or not next.js allows you to put the page as asynchronous so we can simply say export default async function home and you can use the await right here that's pretty cool right now let's see what do we get back from old cars by simply saying console log all cars if we save it and go back to the browser and reload the page and inspect open up the console and reload the page are we going to see anything nope nothing's there what happens if we open up our terminal we can see an error saying invalid parameters trying to call this API so if we look at the API documentation you can see that all of these fields are optional but they do provide in that model so let's go back to our utils index TS and let's provide a question mark model is equal to Corolla just to test it out and see if we get anything back again nothing is going to be in the console right here but the data is actually going to be inside of your built-in Visual Studio code terminal you can see all the different Toyota Corollas right here Isn't that cool now you might be wondering why that is the case well that's because every component and every page by default in xjs is a server side component so this is actually being fetched on the server which is why the console log is coming right here if you converted this into the use client component then it would be shown on the browser but we don't want to do that if we don't have to so we have all the cars and now we can focus on showing them down below so let's go ahead and do that right away going below the search bar going all the way below the home filters and then creating some space for where we're gonna go over the cars first we have to check if all of the data is empty and we can do that by saying const is data empty is equal to if not array dot is array all cars meaning if it's not on array or if all cars dot length is lower than one or if not all cars so if any of these is true that means that our data is indeed empty so we can use that as a check down below so if not is empty data in that case we can return a section and here we can say we have cars else we can return something else and that's going to be a div and this div is going to render an H2 that's going to say something like oops no results and we can render the message that we get from the API by saying all cars question mark Dot message now even though we cannot see this right now let's give it some class names for example home underscore underscore error Dash container and then to this H2 to make it a bit more standout we can give it a class name equal to text Dash black text XL and fonts Dash bold wonderful now in this case we do get we have cars because we saw those couple Toyota Corollas right here so what do you say let's go ahead and show them all on the screen So within this section we're going to have an additional div right here and that div is going to have a class name equal to home underscore underscore cars Dash wrapper inside of there we can simply put a dynamic block of code say all cars question mark dot map where we get each individual car and for each one we return a car component that looks like this that car card is going to accept a car as a property and let's just put it in a new line so we can more clearly see what is happening over here it looks something like this we have a section where we map over the cars and then for each car we show the car card component and then we pass the card data to it hopefully all of this is clear so far but now you can notice that we have an error because the car card doesn't exist as of this moment so what we can do is go to the components folder and create a new car card dot DSX we can run rafce once again export it as all the other ones so far so just rename it to car card and if we do that we can now import this car card on top right here from components and if we save it and reload you can see that we have one two three four Toyota Corollas even though we don't know which ones those are we can see it by the data now is our job to get into the car card and actually render the meaningful information about that specific card such as the price per day the name whether it's all-wheel drive or front-wheel drive if it's automatic and what is it miles per gallon great so let's do it right away our car card is going to utilize the use State field to be able to manage the open state of the modal that's going to pop up and therefore by default since we're using hooks it's going to be a use client component alongside the U State we're going to also import the image coming from next forward slash image now we already know that we are passing the car into our car card so we can accept it as props but since we're using typescript we also have to specify the type so we can go all the way to our types folder and inside of here we can create an interface for the car props something like export interface and then car props will do the trick of course how do we know which props does our car have well we can go straight to the API documentation and check out the demo of the results right here and simply copy all the properties and we can paste them right here now of course we have to add commas so right now I'm holding the ALT key and clicking with my mouse and that's going to allow me to Simply add semicolons at the end of all of these lines at once and instead of the actual value that we have we have to specify the type of the value so the city mile per gallon is going to be a number then we're going to have the string of course then we're going to have a number and we can repeat this process where I can immediately select all the numbers holding the ALT key and put that out as number and we can repeat the procedure with all the strings as well and that's going to look something like this and we immediately have our car interface that's going to be of so much help because we'll never be able to miss a specific property for example if we start typing City MPG for miles per gallon it's going to say hey that property doesn't exist you only have this one great now we can go back in here and we can utilize those props we can create a new interface which is going to be called car card props where the car is going to be equal to car props like this and the only thing we have to do is now say car is car card props and we're just missing the car props which we can import from add forward slash types great later on we'll also be using our custom button which is going to come from dot slash custom button and with that we are ready to start creating the main structure of our car so immediately right here below we can destructure the main cars properties that's going to be City MPG year make model transmission and drive and that's going to be equal to the car that's going to allow us to Simply say year instead of car that year now we can see that it's complaining that the year doesn't exist on a car and that points my attention to this missing property which I unfortunately missed so I'm gonna add the year at the bottom as well and turn it into a number and with that we are good to proceed so our car card is going to be a div that's going to have a class name equal to car dash card group and we can go back to our app and you can see that this is going to give us a nice looking element or a div for our card immediately within it we can create a new div that's going to have a class name equal to car dash card underscore underscore content immediately inside of there we can create a new H2 and this one is going to say make and then it's going to say model that's going to give us the full car name let's call it that way and we can see that all of these are Toyota Corollas and let's give it a class name of car dash card underscore underscore content Dash title this is going to make it look just a bit better finally we can dive below this div and create a new P tag that P tag is going to have a span element that's going to render the car rent that's interesting so later on we could convert this application in a car renting app right now we don't have the information about how much each car costs so we're gonna play around a bit and try to calculate the price of the rent of the car based on the year or the mileage so if we go back to our folder called utils we can create a new utility function and that's going to be export const calculate car rent as you can see I simply pasted it here and you will be able to do the same by simply copying it from the GitHub just down below this is nothing more than just setting up an imaginary rental price for your car based on the base price mileage Factor age Factor we calculated and then we come up with a specific price you could have used chat GPT to create a similar function as well that's going to allow us to export this function and go back and then utilize it right here where we can say const car rent is equal to calculate car rent and we can pass in City MPG and year and of course don't forget to import calculate car rent from utils and now we can show the car rent right here within the span element that's going to be 54 for most Toyotas funny enough what we can do is style it a bit so we can do something like on the speed tag give it a class name equal to flex margin top of six text is going to be 32 pixels and font is going to be extra bold now to this span we can give it a class name equal to self Dash start this is going to align itself on the start text-14 pixels and fond Dash semi-bolt and finally we can duplicate this pan below this time instead of car rent we can say forward slash per day and then instead of self start we can do self end and we can do font Dash medium and this is going to show the price per day now I noticed I made a mistake right here the car rent should have been in between those two spans and the dollar sign should have been in the first pan so we have a dollar sign here car rent in the middle and then the span with the day right here which gives us something that looks like this so it's going to be dollar price per day there we go looking great now below that we want to show our image so that's going to be below the P tag but the image is going to come from another source so what we can do for now is simply do a wrapper for that image and now we can focus on showing the image the image is going to come from another API so for now we can just do the wrapper for that image and a demo image for all cars and then we're gonna fill in the details later on so in here we can give it a class name of relative W Dash fool h-40 margin y 3 and object Dash contain that's a wrapper for the image and then we can render the self-closing image in there and for now for the source we can put the forward slash let's go into the public just to see what's there and then we could do the hero PNG I think that's that's a car so we can do just Source forward slash hero and let's give it a width of something like 50 and height of 50. just to see how that's going to look like for now we can also give it an ALT tag equal to car model we can give it a fill and a priority meaning that it's going to load first and the class name object Dash contain if we have fill I don't think we need the width and the height so if we save this we have this great looking demo car model for now for all of these Toyota Corollas as I said car images are coming from another API so once we fully finalize the car and the search will be able to add real images now let's go to the div below to create all the additional information such as the automatic all-wheel drive and miles per gallon for that we can give this div a class name equal to relative Flex W Dash full and margin top of two to divide it a bit from the image we're going to have one more div inside of it that's going to have a class name equal to flex and then on group Dash hover we're going to make this completely invisible yep that's a property visibility is going to be hidden this is going to allow us to show the button instead then we're going to do W-4 and justify Dash between as well as text grain and inside of there we can have a final wrapper div that's going to have a class name equal to flex Flex Dash call justify Dash center items Dash Center and GAP Dash 2. inside of there we can show the steering wheel image by rendering a nextgs image tag with a source equal to forward slash steering Dash wheel dot SVG we can give it a width of just 20 pixels as well as a height of 20. and the alt tag equal to steering wheel and below it we can render a P tag and this P tag is going to have a class name equal to text Dash 14 pixels and we can check the transmission so if the transmission is equal to a then we can show automatic else we can show manual if we now save this you can see this great looking steering wheel and it says automatic now if we duplicate this two more times we'll be able to have two more icons the second one is going to have the tire image so Tire dot SVG it can also say Tire here and it's simply going to render instead of a P tag Drive dot to upper case like this if we save it you can see FWD for drive and the last one is going to be a gas SVG and that's going to render the city underscore MPG MPG so that's going to be how many miles per gallon it spends in a city great and we have our great looking car card now if we go down one div and then one more div we can focus on creating that button that's going to show up so we can create a div for the button it's going to have a class name equal to car dash card underscore underscore BTN Dash container and within it we can render our own custom button component that custom button is going to have a title equal to view more it's going to have container Styles equal to W Dash full padding y of 16 pixels rounded Dash full and bg- primary Dash blue if we now save this and hover you can see it looks good but we also have to change the text Styles so let's do text styles and that's going to be equal to text Dash White text Dash 14 pixels leading Dash 17 pixels and fun Dash bold now you can see the typescript is already complaining because so far we haven't used textiles and it's going to complain even more because we want to give it a right icon so something like write Dash arrow.svg as it is right here we haven't made that happen yet on a reusable button but that's what reusable components are for you can style them depending on the context where they show and finally we're going to have a handle click that's going to open up the model so we can say set is open it's set to True which we don't yet have so at the top we can create a new use State snippet that's going to say is open set is open at the start set to false of course indicating the modal state great now let's dive into our custom button and let's first change the custom button props right now we obviously don't have the text Styles so at the bottom let's add text styles specify that it is optional and make it a string we also have the right icon which is going to be optional and also a string later on we're going to have the is disabled property which sometimes can be true so that's going to be a Boolean and now we can go back to our custom button accept these additional properties such as text styles and right icon and we can utilize them the text styles are going to happen here next to flex 1 where we can simply render the text styles if we save that you can see the text is now White and the last remaining thing to do regarding this button is to add an arrow so right below the span we can open a new Dynamic block of code and say if right icon exists then render a Dev that's going to contain a class name of relative with or w-6 h-6 and we can render a self-closing image that image is going to have a source equal to write icon an ALT tag equal to right icon a fill and a class name equal to object Dash contain if we save that you can see it appear right here this is looking great and of course if you click it nothing happens yet but soon enough we're going to show a model that's going to give us more information about this specific car so if we go back from the custom button and the types and the calculated car rent back into our car card the last thing to do is to Showcase dot car modal so right below this div with a custom button and Below one more div meaning right here near the end we want to create a car details component and if we save it now of course it's going to break but that means that now it's time to create a new component so right click new file and let's call it car details dot TSX we can run rafce export it as we usually do that's going to be car details and go back and import it at the top right here you can do car details from dot slash car details and we have to pass a couple props to it we have to know are the car details going to show or not which means that we have to pass the is open State equal to is open and we need to be able to modify that state meaning close the model so we can pass the closed model function that's going to have a call to set is open is set to false it's going to toggle it off and then of course we want to pass the car is equal to car so we pass over all of the details about a car to car details now as you can see the car details currently complains because it's not accepting those props so let's control click the card details accept all those prompts properly and let's typescript know that it has nothing to worry about so what we can do is create a new interface right within here car details props and what do we need we need the is open state which is going to be a Boolean we need a closed model which is going to be just a function that's not going to return anything and check this out we can use another interface we created before car is going to be equal to car props which are coming from our ad types Isn't that cool we are reusing all of the car properties within another interface and then adding two additional things typescript really is extensible and now we can simply accept them is open close modal and car that's going to be of a type car details prompts wonderful and with that we are ready to start creating a model that's going to look like this if you pay really close attention you're going to notice that it doesn't open instantly there's a transition that happens it takes about a couple hundred milliseconds and then it opens so we're going to achieve that transition using the Headless UI transition property so let's get started with creating this phenomenal model we can start by importing the image tag which we've used many times so far from next forward slash image next we're going to need to import a fragment coming from react we're going to also need to import a couple of things from the Headless UI for example a dialog and a transition from headless UI forward slash react and don't forget to put the add sign up front now the transition is to add that animation and the dialog is the modal that you can see that opens when you click on view more and with that we can start creating the structure of our card details car modal dialog however you want to call it so first let's wrap everything in a react fragment then we're going to create a new transition this transition is going to have a tag of appear meaning it's going to show up and then on show we wanted to show when it is open once we open the model and it's going to act as a fragment there we go now within that transition we want to open up a dialog that dialog is going to show as a div and it's going to have a class name equal to relative Z10 to appear on top of things and it's going to have an on close property which is going to be equal to close modal function which we're passing to card details within that model we're going to have something known as a transition dot child and this is going to be the backdrop So within the transition child we can render the self-closing div that's going to have a class name equal to fixed in set 0 BG black and BG Dash opacity-25 if we save this you're going to see that it's going to complain because it wants you to transition this over to the use client because headless UI uses use client so if we fix this you can see that now it works and you have this backdrop visible of course on top of the backdrop we want to show some other things but first we want to make this backdrop appear slowly so to this transition.child we're going to add some properties it's going to be as a fragment and when it enters it's going to enter with an ease out duration 300. it's going to enter from opacity 0 and enter to opacity 100 when it leaves it's going to leave with the ease in in duration 200 it's going to leave from opacity 100 to opacity zero I really love the way how they put the starting and the ending position and you can do that for each and every property so now if we reload the page and you click view more you can notice how it slowly appears and you can close it with the Escape key on your keyboard now of course we don't want to just have the backdrop below the transition.child we want to create a real dialogue modal so right here we can give it a class name set to fixed in set 0 overflow Dash Y dash Auto and inside of it we want to create a new wrapper div that's going to have a class name equal to flex Min Dash H dash full items Dash Center to Center them vertically justify Dash Center to Center horizontally p-4 for padding and text Center inside of there we want to render another transition.child as a matter of fact we can copy the one we had above so you just have to close it again it's going to be a fragment ease out duration opacity but alongside opacity we also want to change the scale from 95 to 100. this is going to make it appear like the dialog is expanding while it opens if you pay close attention to the Finish side you'll see how it expands from 95 to 100. it's barely noticeable but it is there and then we want to remove the scale from 100 back over to scale 95. there we go and within it we want to have something known as a dialogue panel so let's create a new component dialog dot panel this dialog panel is going to have a button within it and this button is going to have a type equal to button it's going to have an on click equal to close modal and it's going to render the image that's going to have a source equal to forward slash close.svg and I'll tag equal to close a width equal to 20 a height equal to 20 and a class name equal to object Dash contain if we save this and open up the modal we can see an X appear right here it's hard to notice it that's because we don't yet have the actual modal card but let's create it so we can style first of all this dialog dot panel by giving it a class name equal to relative W Dash full Max w l g Max Dash height or H dash 90 VH so we never wanted to take the full height of the screen only 90 percent overflow Dash Y dash Auto transform rounded Dash 2XL and then BG white now if we save this we cannot see anything yet but if we reopen it you can see some kind of a modal now let's give it a text Dash left Shadow Dash XL transition Dash all Flex Flex hash call and GAP Dash 5. if we save this and reopen it again nothing really happens but soon enough as we start adding all of the elements it's gonna start making more sense for now let's style the button a bit by giving it a class name equal to Absolute top Dash 2 write-2 z-10 W Dash fit p-2 BG Dash primary Dash blue dash 100 and rounded Dash full this is going to make it look like this although now everything disappears so we cannot see anything we're going to look into this as soon as we add some more stuff to our dialog panel so going below this button we want to create the div that's going to serve as the actual content of the final card and to that wrapper div we can give a class name equal to flex-1 flex Flex Dash call and gap-3 inside of there we can have a wrapper for the image so it's going to have a class name equal to relative W Dash full h-40 BG pattern BG cover BG Center and rounded LG if we now save this we can finally see something because now it's taking a height of 40 which is 10 rem or 160 pixels so the card got some height and therefore it is visible we can also see the close button which fully works and it slowly animates in now for now inside of here we can render the same demo car image as we did before so let's scroll all the way up in the car card and let's copy this image right here and go back to card details and paste it within that div this is going to render the car as you can see here now we can go below this div with the BG pattern still staying in the other div that we have created and we're going to create a div for three smaller images down below so right here we can give it a class name equal to flex and gap-3 and we can create a div for one of these three images it's going to have a class name equal to flex-1 and immediately we can just copy the image that we have right here and paste it you should be able to see two of these images appear really soon not yet though alongside Flex 1 we also want to give it relative W Dash fool H-24 BG Dash primary Dash blue dash 100 and rounded LG now you can see the other car it's taking the full width because it has flexor one but now if we duplicate this div two more times we should have two additional images right here of course now it's all the same car but soon enough we're going to be able to show different images from different positions of every single car brand and type wonderful so what we can do right now is go all the way down one two three divs down still staying within dialog panel because now we can focus on adding the additional content right here first we want to show the name and the brand so right here let's create a div it's going to have a class name equal to flex-1 Flex Flex Dash coal and gap-2 we're just making some space and ensuring that the elements are going to show one below another then we want to create an H2 element and within it we want to render the car dot make as well as a car dot model and you can see Toyota Corolla right here and finally we can change the class name equal to font semi bold text Dash XL and capitalize this is going to make it look just a bit better now below this H2 we can start adding all of the other content and you might think it's going to be a real pain in the ass to add every single little line but of course we're going to map over it so let's first create a container that's going to have a class name equal to margin top three to divide it a bit from the title Flex Flex Dash wrap and gap-4 and within it we need to wrap over all of the car properties now the way in which we're going to do that is gonna be really interesting we know that we have our car right and if we look into the car type the car is going to have all of these properties it's going to have class combinations cylinders displacement drive and so on and we have a specific value corresponding to each one of these so-called keys so a car is going to be an object with keys and values and this is one of the rare occasions where we don't simply want to show the values but rather we also want to show the keys now how do you get the keys of an object do you know that this is a plain JavaScript question so really try to put some thought into it and think about how can you get the keys of an object usually you need values well you do it using the object dot entries you pass in an object to the object that entries and that returns you an array of key and value pairs or properties of an object then we can do a DOT map and then we can get if we do array destructuring right here the key as well as the value and then we can instantly return a div for each one of these key value Pairs and that looks like this that div is going to have a class name equal to flex justify Dash between because we want to show the key on the left side and the value on the right side gap-5 to give it some space w Dash full and text Dash right finally the key is going to be the key then inside of that div we can render on H4 and here we can just render the key and below that we're going to render a P tag where we can render the value and as soon as we save that you can see all of the properties appear immediately now let's make this look just a bit better first of all to rh4 we can give it a class name equal to text the hash Gray because it's not as important as the value of course and then we can capitalize it again a really cool property from Tailwind right here text transform capitalize we can also remove the underscores right here so what we can do is say key dot split by the underscore and then dot join with a space it's a little detail but it makes a big difference finally let's give this p a class name equal to text stash black Dash 100 and fond Dash semi-bold to make it stand out a bit more now you can see that we don't have enough padding on this card so if we go all the way up where we declare the initial dialog panel it looks like we missed some padding right here so let's see where is it missing from it looks like a couple of things are wrong right here so we have the Overflow y Auto then we have transform rounded Dash 2XL BG white and then we can also add a p dash six a padding of six if we save that and click again this is going to look like a completely different card then it's text Dash left but I also missed the shadow it's going to be a shadow XL not XSL so if I fix it if we reopen it it's going to have a small shadow on the bottom making it appear like it floats on top of the screen and I think everything else is good now we have a wonderful looking car details page or in this case just a model or a dialogue however you want to call it but that's good we can open it we can also go for the Toyota Corolla wagon and that's looking great as well we just have a bit more information about the details of the car now we've been staring at these Toyota Corollas uh this whole time well at least the title says it's a Toyota Corolla so let's just go to our API a bit which is in utils and let's try to go for something a bit more interesting so if we go to fetch cars let's try to change it to a model and let's see if they have some Carreras that might be a bit more interesting so that's going to be a Porsche and there we go we can see some different models right here 911 Carrera and we have a couple of different variations of them and yeah this is the all-wheel drive as you can see and the top one is the rear wheel drive but still now I'm assuming that the images of these Porsches would look a bit different than they look right now so I think now is the perfect time to tap into the second API of the day and properly get it to show the front side as well as all the other sides of our vehicle so to do that we can now close the car details close the car card and the page as well and then go to utils this is where we're gonna tap into that second API in the same way that we tapped into the first one so we can collapse these functions and create a new one called export const generate car image URL and it's going to accept a car which is going to be of a car props right here and later on we're going to also pass it an angle because we can angle those images so that's going to be an optional property of a type string and of course we're gonna open up a function block and we have to import our types into our utils index TS great now let's set up the call to our second API to start using this API you can go to imagine.studio forward slash car dash image Dash API and when I say they have a lot of cars I really do mean it I mean every single make and every model family for that make in all the different colors so this is pretty crazy it is a paid API but you can sign up for their free trial by clicking the get access now you need to enter your company email address and then you will get additional instructions so feel free to use your company email address to get a free trial once you do get the key feel free to store it right here as a comment because we're going to use it later on and if something goes wrong with getting this key I'm gonna show you how I got mine so right here first we need to specify the API endpoint that's going to be const URL is equal to new URL and we're going to pass a string of https column forward slash forward slash CDN dot imagine that's going to be imagine without the e dot Studio forward slash get image and it's going to be studio with an O here now if you control click it you can see that for now it gives you an empty model because it doesn't know which model or make or model family are you looking for so now we can append additional information to this API to be able to get the data first of all we're going to destructure the make the year and the model from the car that we're gonna pass to this function and then we can say URL dot search params dot append and we need to append a customer which is going to be equal to your key right here so if you manage to get a key with a company email feel free to put it here in case you didn't I'm going to show you mine it's going to be HR JavaScript Dash Mastery and now you're gonna have the key and keep in mind that by the time that you're watching this video it is possible that this key gets expired so I'm Gonna Leave the entire generate car image URL with the always updated key in the GitHub just down below so simply visit it and you can copy this entire function now we're going to pass some additional properties such as URL search params dot append and we can append a make and a make is coming from our car model and now we can duplicate this many different times one two three four five after the make we can provide a model family and we can do that by getting the model dot split we're gonna split it with one space and get the first element out of it that's going to look something like this after that we want to get the zoom type it's going to be set to full screen we want to get the model year like this which is going to be set to it has to be a string of year and finally we want to get the angle of the car which is going to be a dynamic angled property and it has to be within a string as well finally once we form that URL we simply want to return it as a string like so great now we can call this generate car image and see what kind of URL it will spit out so let's go to our first of all app and then the page and then car card in the car card this is the first time we're using that demo hero image but this time we want to utilize a real one so we can see those great Porsche 911s inside of the image we can call a generate car image URL as a function and of course you have to import it coming from add forward slash utils once you do you have to pass one property to it a car that's it and if you save it and we get an error that's because the hostname cdn.imagine studio is not configured under our images in next.config.js so let's go to our next Dot config.js and inside of here we can add images object and we can specify domains as an array where we're going to say cdn.imagine dot studio and if we save that we might need to reload our application because we change the next not config.js and once it reloads hopefully it's gonna work okay the Moment of Truth we're going to scroll down and there we go beautiful car images appear right away this is looking great now if we open it up we again have our demo images so now we can go into our car details and there instead of calling the same old hero image we can again call our new function which is going to be right here but as a matter of fact we can just select the entire string of hero.png and we can open a control F or command F if you're in mac and then press this arrow and then say curly braces generate car image URL we pass in a car and then we're going to pass the angle which is going to be the second string that's going to be right here now if we save this you can see how it's going to change it oops I'm going to go back because we forgot the second curly brace to close it and click this right here and there we go now it's not going to be the URL it's going to rather be the car as the first parameter so I'm going to fix this in all cases there we go and we have to of course import this function from add forward slash utils now if we save this you're gonna see that we have cars it's looking great but we want to pass the angle for these different ones so for the first one we don't have to pass an angle at all for the second one we want to pass an angle of 29 then we want to do 33 and finally we want to do 13. I found these angles to work the best if you save it you're gonna see a car from completely different positions and it truly is looking wonderful and it makes a big difference in this application again all of these are the same but once you have a variety of different cards it's really going to make your app feel more polished because these are professional images just to see if the images are working fully we can go back to our utils and then inside of there we can change the model since we don't have the search implemented yet we're going to have that soon for now we can do it manually within the API call let's do something from Audi like a Q3 if we save this you can see Audi Q3 Quattro and the images haven't changed but they did now so we just needed to wait for a second or needed to reload and now it's looking good and we can see the images appear from all sides this is looking great now that we're properly fetching the cars and that we have the images and the details for the cars and everything else we are ready to go back we could put it that way to our search so if you remember we have a search bar here which works to change the manufacturer but our search is currently not doing anything so once we update the search we want to update which cars are we showing by making another fetch to our rapid API so let's do that next and then we're going to focus on adding the model filtering as well right here and finally the filters for the fuel and the year to make it even more precise and of course we're diving into the server side rendering here so we're gonna see how that works wonderful with that said let's go back to finalize the search now that we have all of these wonderful cars the only thing we have implemented within our search bar right now is this search manufacturer component but we also need some kind of a button to submit that search so let's create a reusable search button self-closing component and in this case this component is going to be reusable only for the search bar file so we don't necessarily have to put it within the components folder rather we can declare it right here above by saying const search button is equal to just a immediate return arrow function inside of there we can create a button and that button is going to be of a type is equal to submit because we want to submit our search form and we can pass some class names we're going to make this Dynamic by creating it as a template string give it a minus ml-3 meaning it's going to jump into the input just a bit and a z index of 10. and later on we'll have to provide some additional classes depending on where we're calling the search button from so we can pass the other classes as well which can be a prop right here other classes so right here in the search button in this case we can create a prop called other classes and here we're going to put it on small devices it's going to be hidden this is for the initial search button great and now of course since we're working with typescript we have to say that the other classes are going to be of a type other classes is a string right here there we go this is great and now within the button we're going to have an image where the source is going to be forward slash magnifying Dash glass dot SVG the alt tag is going to be magnifying glass width is going to be 40. height is going to be 40 and class name is going to be object Dash contain and of course we have to import the image coming from next image so just import it right here and if you save this we should be able to see something but no it's not there yet the search button it could be because we're in the small window so if we expand it no nothing appears right here although it should be there so let's go back and let's see where our search button is we have the search manufacturer we have the search button we pass other classes and then we show it right here if we check the Finish side we see that we don't even have it right here at the end but if we expand then it's still at the end of here so yeah it's going to be after the model not necessarily immediately after the search so this is looking good for now now below our search button and below our div we're going to create another div and this div is going to have a class name equal to search bar underscore underscore item as we had it above but this is going to be for the second input so inside of here this one is going to be just a bit simpler we can render the image this image is going to have a source equal to model Dash icon dot BNG it's going to have a width of 25 a height of 25 and a class name equal to Absolute W Dash 20 pixels as well as a height of 20 pixels and a margin left of 4. as well as the altag equal to car model if we save this now we have this second icon right there and we can create a new input tag right below that input is going to be of a type is equal to text it's going to have a name equal to model a value equal to model and this is something that we haven't yet created it's going to be within a state so alongside the manufacturer State we'll have to keep track of the model State as well at the start set as an empty string now of course we need to be able to change that model as well so it's going to have an on change property where we get the event and then we call the set model e.target.value it's going to have a placeholder and since we had a Volkswagen right here as the make we can do something like TIG Run for the model which is the model and then the class name is going to be search bar underscore underscore input if we now save this we can see that now we have a complete make and model search and we can also now reuse this search button right here into it we can pass the other classes equal to SM hidden like so so we can see it on medium devices but just below we're going to duplicate it one more time below this div and here we're going to say Max SM hidden so we're going to show them in different places depending on where we have them and it looks like I misspelled the hidden here so if I fix it we should only have one and if I expand this is looking good if I bring it to mobile size now we have one for each exactly how it should be wonderful we can bring it back to this size and we can try to make this actually work right that's the whole goal well to do it you might think that we'll have to make a new API call from the search bar whenever something changes but that's not going to be the case the only thing that we are gonna do is we're gonna change the url parameters on top to something like make is equal to let's do Volkswagen and then the model is equal to the Tiguan that is great because then next.js is going to make a server side call for us and get the data to us the only thing we have to do is change the parameters so to be able to do that we're going to jump into the handle search function here as a parameter we get an event which is of a type react dot form event and HTML form element specifically we have to do it like this and we have to make sure that we have react imported at the top now inside of this function first we want to do e dot prevent default because the default behavior of the browser is to refresh once we submit the form but we're working with react and xjs so we don't want to do that now in case we don't have the manufacturer or the model we want to throw some kind of an error so we can say if manufacturer is equal to an empty string or a model is equal to an empty string we can return maybe some kind of an alert that's going to say please fill in the search bar so now if we click we get an alert but if we actually have some data then we need to update the URL bar to look something like this and to do that I'm going to create a new function call const update search params it's going to take two params the model which is a string and a manufacturer which is also a string and then we have to form the new URL and how that's going to look like so first we can say const search params is equal to new URL search params and we pass the current window dot location dot search so if there was something else before we need to know it and store it right here then we want to update it or delete it if we have a model we want to check out then we can do the search params dot set model and model if we don't have a model we simply want to delete the previous model that was there and we can repeat this with the manufacturer so if we paste it below just replace every model to manufacturer there we go finally once we got the new search params we can say const New Path name is equal to a template string of window dot location dot path name then a question mark and then what do we add to it search params dot to string so you can see what we're doing here we're taking the current path name appending all of these search params to it and coming to the final path name or the final URL and then we can do a router that push and we can push the New Path name of course this router is undefined because it's coming from next.js so at the top we can say import use router coming from next navigation and then we need to call it as a hook const router is equal to use router like so and now if we save it we will be able to click search and it should append specific properties on top so let's go ahead and give it a shot by saying something like Audi and then what do we have we have maybe a Q5 so let's press search nothing happens why does nothing happen because we're never calling the update search params so we can call it once we handle the search right here by saying update search params and we're going to pass in model but we want to make sure that it is too lowercase and manufacturer also to lowercase just to ensure we don't have any inconsistencies so to this function we pass a model to lowercase manufacturer to lowercase and it will end up looking something like this if we now save it and press search one more time as you can see it updated the model to Q5 and the manufacturer to Audi in The Next Step I'm going to show you is how as soon as you update the params nextgs is going to automatically refetch the data to do that we have to go all the way back to our page.tsx where we're fetching the cars in the first place so what we can do is we can try to get all the data from search per apps how does that look like well in nextgs you can immediately extract all the search params straight from props of a specific page right here and then in the fetch cars we can pass all of the options by saying object where we can pass the manufacturer which is equal to search params.manufacturer we can pass the year which is equal to search params.year we can pass the fuel equal to search rams.fuel we can also pass the limit equal to search params dot limit and a model equal to search rams.model now in case we don't have any search params we can also provide default values for all of these so we can say or it's going to be an empty string or for properties like year we can do something like 2022 and for limit we can do 10. this is how many cars are we gonna see at the start now if we save this you're going to see that we have an error or a warning from typescript saying that fetch cars didn't accept any Properties or didn't expect any params and that is true because if you check it out right here you can see that it's not expecting any so typescript really saves us right here saying that hey expected zero arguments but got one what are you doing with this well what we can do next is go into our utils and modify the fetch cars so that it accepts filters and filters is going to be equal to filter props so this is something that we have to create in the types so going all the way to our types we can create the filter props by saying export interface filter props and we're gonna pass exactly what we had before in our page we can copy all of these properties paste them here and instead of passing all of the search params we just have to provide their type in most cases it's going to be a string but we also have two numbers a year is going to be a number and a limit is going to be a number as well so now we have the filter props if we go back to the utils we can now import the filter props from types and now our fetch cars knows what it is expecting and it's no longer complaining so now we can actually utilize this function to fetch the right cars how are we going to do that well we can append it all to this response you can use something similar to what we did with this approach I think this is a bit cleaner but an alternative is just to turn this into a template string and then you can pass all the parameters you want for example cars and then you pass a make which is going to be equal to manufacturer and then you pass a make which is going to come from filters which we need to destructure at the top so we can say something like const manufacturer let's also get the year the model the limit the fuel which is coming from or rather is equal to filters and now right here we can just use it we can say make is equal to manufacturer let's keep going we can say and year is equal to year and model is equal to model that we're going to pass in and limit is equal to limit and finally and fuel type is equal to fuel again make sure to use the underscore for the fuel type now our API is going to respond to whatever we put into the search and immediately you can see it worked we can try with some other make for example let's do BMW and let's go with something like M8 if we now search it Scrolls all the way to the top but you can see the parameters have changed but if you scroll down you can see the BMW competition and you can see that all the images and everything else is working as well wonderful with that all of this is being done on the server side we are just changing the search parameters and next.js is refetching it immediately by taking those search programs and making a call now you might have noticed that when you search for a specific brand or make the website Scrolls all the way to the top which breaks the app's usability now with all of the latest and greatest Technologies you cannot always win you get some you'll lose some and that's how real web development is I wanted to include this part in here to show you that this is not a bug in our application it is bug in the new nexgs 13.4 and there's already an issue on GitHub open for it I'm gonna expand this just so you can see on the official Versa next.js GitHub repository there's an issue reported that the scroll position is reset when search programs are updated a couple of people have presented their bugs and described it right here before 13.2.4 updating search params was working as intended the client state was kept and scroll position was kept too later on that's not the case so in here we have a couple of example where the application Scrolls all the way to the top even though that shouldn't be the case these guys are creating some kind of a Form application and when you update the state it Scrolls all the way to the top breaking the application's usability similar case happened to me as well so you can see my bug report right here I showcase how and what is happening in our finished application it's the same thing so by the time you're watching this video it is possible that this issue is fixed in which case you will be able to find an updated explanation down in the description maybe you'll have to add some kind of a parameter to the router.push command that's going to keep the scroll or maybe it's going to work by default we're gonna keep you updated in the description Down Below in case that is not fixed there's going to be a link to this GitHub issue where you can come in and you can upload it as well or you can even add an additional comment requesting this to be fixed that's going to be up to you but I just wanted to keep this real for you guys and wanted to point out that developing software especially phenomenal tools like nextgs is not easy so sometimes it will take developers some time to fix these specific bugs but again no worries here in JavaScript Mastery we always try to show you the latest and greatest stuff and later on I'm gonna show you how we can create a fix for this solution although there will have to be some drawbacks to it but still we're gonna make it work without it scrolling all the way to the top before we Implement that additional solution which is going to be a great lesson on happens let's try to find an alternative solution let's first finish the custom filters as well as the show more button on the bottom right here and then I'm going to show you how to apply a fix so with that said let's go back to the development by putting this on the right side we can close the issues and everything that we don't need and go back to our current application we're currently in the page but we might want to move below our search bar now onto our custom filters so let's control click into the custom filter component and let's start implementing it our custom filter is going to use use statehook for something we'll need as well as a fragment component coming from react and by default since we're using a use State it's going to have to be a use client component alongside using use State we're going to also import the image coming from next forward slash image and we're going to import the use router coming from next forward slash navigation finally we're going to use some things from headless UI so we can import that's going to be a list box as well as transition coming from add headless UI forward slash react finally in our custom filter for now we are passing just the title but we're gonna have to pass one additional prop which is going to be options so you can see that if we click the first one we have three things and on this one we have a bit more so we'll have to pass an array of these available options for each one of these filters and that's not going to be tough we can simply say options is equal to and the first one is going to be fuels and immediately it's going to recommend us to import the fuels from constants and in the second time it's going to be years of production which we can also import at the top that's going to be fuels and years of production coming from add forward slash constants and if we go into it you can see that alongside manufacturers we have some options as well as the options for the fuels great now what we can do is we can go back to the custom filter and now we know which props are we accepting it's going to be a title and it's going to be options and that's going to be of a type which we are yet to create we can go into the types index.ts and create a new interface right here export const interface rather it's going to be just the interface not const export interface custom filter props which is going to have a title of string and options which is going to be now bear with me we're going to create an interface within an interface so that's going to be option props and array an array of option props and what is option props well we can create a new export interface option props which is going to have a title of a string and a value of a string as well and now we're utilizing this we're saying it's going to have an array of title and value pairs great finally we can go back and here we can say custom filter props and we can import it from add forward slash types great and we can start creating the jsx of our filter using headless UI so going back to our unfinished application we can wrap everything in a div that's going to have a class name equal to W Dash fit and inside of it we can create a list box component inside of the list box we're going to create a div and that div is going to have a class name equal to relative W Dash fit and Z index of 10. inside of that div we want to create a list box dot button and we can give it a class name equal to custom Dash filter underscore underscore BTN if we now save this you can see that the custom filter should go away and it does there's nothing there but if we add a span element that's going to say something like filter you can see two filters appear right here now we can create a new state at the top that's going to be created by using the use State snippet and we can call it selected as well as set selected and then we can get the options and use the first one so if it's fuel the first option in the fuel is going to be just Fuel and year is going to be a specific year on there now what we can do is then we can update that selected field by automatically passing the values to the list box you can read more about this in the Headless UI documentation the way it works is just like a regular select element where you pass a value equal to selected and then on change parameter where we have a callback function with an event and then you can simply do set selected and pass the event and that's going to update the value now in the span we want to show what is currently selected so we can do selected dot title and that's going to look something like this Fuel and year we can of course give a class name to that span such as block and truncate in case it's too long so it still fits on the screen and below the span we can render an image that image is going to have a source equal to forward slash Chevron Dash up Dash down DOT SVG it's going to have a width of 20 as well as a height of 20 and a class name equal to ml-4 object contain and we can give it an ALT tag equal to Chevron up and down and therefore you can see that this is now a filter and you can click on it to expand it of course it's not going to work yet but we're gonna make it work really soon and it looks like I misspelled it right here it's going to be custom filter not Builder so if we fix this it's going to look so much better now below the list box button we want to create a transition this transition is going to slowly open up the menu options for the other Pickers that we can choose so a transition that transition is going to act as a fragment like so and once it leaves it's going to leave with a transition of ease in and duration 100 it's going to leave from opacity 100 and leave to opacity 0. that's going to look something like this you can notice how the opacity changes and it looks like it's slowly opening and closing great now if we go down we can put something inside of that transition and that something is going to be a list box dot options it's also going to have a class name equal to custom Dash filter underscore underscore options and we can map over the options by saying options.map where we get each individual option and we instantly return one single list box option that looks like this inside of there we again have that similar statement where we can see which one is currently active or selected so we open a new Dynamic block of code call a callback function and then within parameters right here we can de-structure the selected and then we know which one is currently selected and then we can instantly return something and that something is going to be a span element that's for now going to say just the option dot title if we save this you can see everything is working and we have three different options for fuel and many different options for the year now let's go ahead and style this a bit and also make it actually work so we have to provide a key with the list box option such as the option.title because we are mapping over it and we can give it a value which is going to be equal to option finally we can style it just a bit we can expand it here so we can see how it looks like and then we can give it a relative position cursor Dash default select Dash none padding Y2 padding x 4 to give it some horizontal space and then we can choose whether it is active so for this we need to turn it into a template string like so and then we can see if it is active then give it a BG Dash primary Dash blue as well as text white and then else just give it a text Dash gray Dash 900. now if we save this it's gonna break because the active is not currently here and the way we get to active is this is really cool since this is a custom component from headless UI it allows you immediately within the class name to know which one is active so how does that work in the class name believe it or not you put a callback function like so that Returns the Styles but then within the parameters you can de-structure the active State and then you'll be able to know is it currently active or not so if we go down you can see this looks good now we can select them if I select gas you can see that is the currently selected one this is good same thing for the year so now we have our options the last part is just to style those options just a bit so on the span we can give it a class name equal to block and truncate and now if it's selected we can just make it a font medium so we can do the same thing right here where it's going to be a template string and we can say if selected then we can give it a fawn Dash medium else we can give it a font Dash normal and that should look something like this if we select gas you can see that maybe we cannot see it because it's hard to see because it's blue but this one has just a bit more boldness on it there we go this is looking good and that is it when it comes to our filters but of course we're not yet changing anything so this is changing the selected state and now is our turn to use these values in the same way that we used our search to update the search parameters that's good for a couple of reasons as the last time it's going to help us with server-side rendering and another reason is that if you want to share a specific set of filters or search to your friends you don't just have to send them for example carcatalog.com and then they have to implement the search themselves you can send them a complete URL that's going to automatically forward them filter the cards that you want to show them that's the benefit when you have those e-commerce or similar types of application you want to share a specific link and it's going to be server-side rendered so what do we have to do well we have to update the parameters of the search bar so that's going to be cons handle update programs is equal to a function where we need to get our current path name and then we have to update it so what we can do is say const New Path name is equal to and then finally we want to do router dot push and go to that new path name which is then going to trigger server side rendering now the router is not defined so we can Define It On Top by saying const router is equal to use router and now the only thing that's left to do is to figure out the current path and the search params and then append the new currently selected ones so doing that is going to be quite similar to what we have done with our search so if we go to our search bar you can see that we had right here update search params so we can copy this entire thing and then go back and then paste it here now in the search it was a bit more complicated because we had a couple of things here it's going to be simpler the only thing we have to do first is get the current search parameters and then we simply have to call the dot set which is going to look something like this search params.set and we want to set the type of the search which is going to be either fuel or year and then we have to give it a value to be able to know these we can accept a type which is a string through params as well as a value which is a string through params as well and we can set them once we set them we can simply navigate to const New Path name which is going to be a combination of the path name plus all of the search params and then we can simply route now this is a function that we can reuse a couple of times it's not specific so what we can do is we can copy everything from here to here and move it into a utility function that's going to be inside of utils and then index DS and right here next to generate car image URL we can export const update search params and we can now just create a function that's going to accept a type of string and a value of string and we can open a new function block inside of which we can pass the con search for Rams search for Rams New Path name and then we can simply return the New Path name that's going to allow us now to reuse this update search param function inside of our custom filter so we can say const New Path name is equal to update search params to which we pass the title as well as the value and where is the value stored well the value is going to be stored in the event where we update it right here so instead of passing the type and the value immediately what we can do is we can get the event which is going to then contain the title which is going to be of a type string and it's going to contain the value which is going to be of a type string that's the case because we're going to call this function right here within the on change of the list box if you check this out after we set selected we can handle update params and pass the event which then holds the E dot value finally we can call the update search params with a title and finally e dot value dot to lower case and that is it of course we have to import the update search params from utils that's going to come from here and then we simply push to the router.new path name now if we save this and try to switch to gas and press you can see we scrolled all the way to the top again that same bug but now you can see that fuel equal to gas is appended to our search query so now if you see all of these are gas and for example let's see if there are some m8s that are not gas I doubt it but let's check it out and we have no results which means that this works let's go back to gas and let's also try to go for year something like 2022 and we have a couple 2022s so this is looking great that means that the filters work and now the filters are done as well the last part to do this is to add a show more button as you can see on the finished site we have about 12 cars at the start and then if you click show more again it Scrolls to the top but if we go down you get more cards to check out so we're gonna Implement that pagination or lazy loading however you want to call it using similar principles that we've used with the search and the filtering so if we go back that's gonna happen at the end of the page.tsx because that's where we have all the cars so below the cars now we need to implement the way to just show more so what we can do is we're checking if the data is empty and if it's not empty we're showing all the cars so what we want to do is below the div containing all the cars we want to show a new component called show more that's it and of course that's going to break the app right now but we can go to our components and create a new component called show more dot TSX we can run rafce and we can export it from our components that's going to look like this where we have show more and finally we can now import it right here that's going to come from add forward slash components show more and if we now save the file if we scroll all the way down you can see the show more button which now is not a button just a text but soon enough we'll be able to do it before we go into it we have to pass a couple of props to it the first one is going to be a page number it needs to know where we're currently and the way we can do that is get the search params Dot Page number or 10 which could be by default and then we need to divide that number by 10 because we're showing 10 cars per page like this and that's going to give us the current page number the second thing is is next does the next page exist unfortunately the API doesn't give us the total number of pages so we have to do it manually and we can do that by checking the search params dot limit or 10 by default is greater than all cars.length if that is the case then it must mean that we don't have any new cars to show now that we know which props are passing to the show more button let's control click it to go into it and let's start implementing it inside of here we're going to make this component into a use client component because it's going to modify some browser functionality such as routing so we can immediately import the use router hook coming from next forward slash navigation and we can immediately get the props it's going to be the page number as well as its next which is going to be equal to to a specific type so we have to pass an interface inside of the types and that's going to be export interface show more props the page number is going to be just that a number and is next is going to be a Boolean great we can go back and we can simply put this as a type of show more props coming from add forward slash types we can immediately initialize const router on top by saying const router is equal to router and then later on we're going to have a function that we're going to use for navigation so we can say const handle navigation and for now we can leave it as an empty function the jsx of the show more button is going to be pretty simple because we're going to reuse our custom button so first let's create a wrapper for it by giving this div a class name of w Dash full Flex Dash Center Gap Dash 5 and margin top of 10. then we want to check is there a next page if there is a if not is next is true then we want to show a custom button and it's going to be a self-closing component which we of course need to import right here on top and we need to pass a couple of props to it the title is going to be show more the BTN type is going to be button the container styles is going to be BG Dash primary Dash blue rounded Dash full and text Dash White and finally on handle click it's going to handle the navigation and now if we save this and scroll all the way down we should be able to see something although we don't see it yet that's because we have a lot of different filters we have an M8 filter right here which means that there aren't more pages of M8 models but if we remove this and just go to the home page and scroll all the way down you can see that we have more cars and if you click it nothing's going to happen but once we implement the handle navigation function you'll be able to see how we can show more cars implementing the handle navigation is also going to be pretty simple because thankfully before we have created a utility function that's going to come in quite handy right here we're going to say const New Path name is equal to update search params and you already know where that is coming from add forward slash utils and then we can pass the limit as the new param and then we need to update it with the new limit so the way we can do that is create a const new limit variable which is going to be equal to page number plus one and then we're going to increase the limit if remember correctly the initial limit is 10 if we go to the second page the number is going to be 1 that's going to be 1 plus 1 is 2 and therefore the limit is going to be 20 30 40 and so on so we just want to update the limit to the new limit and the update search for Rams accepts a string as the second parameter so we have to either wrap this in a string Constructor or simply wrap it in a template string like so finally we can use the router.push to push the New Path name and by itself this should make it work so let's expand our website to check it out I'm going to reload the page and ensure that there are no additional parameters in search we can currently see 12 cars right here and if I click show more and scroll all the way down we can see that this was the last car before and now we have a list of new cars that shows and you can see that the limit changed to 20. now if we click show more once more the limit remained 20 which is weird but if you click once more it's 20 again so something doesn't seem to be right with the way we're changing the limit so let's look into that together so we can go more than just the second page we are passing the page number through props from the page.tsx right here where we say search params.page number no that is not a property search params.limit is a property so we want to get it right here at the start read that value pass it over and then it's going to know that it's currently 20 but we want to move it to 30. so now if we click once more show more it's going to be 30 40 and so on and we'll be able to see a new list of cards which is looking great of course that's scroll to the top alongside the filters search and now even the show more is really annoying but we'll try to find a way to fix it really soon with that said if you look into our app it's looking much closer to what we have on the finished website it has the car catalog title it has the search for the make and the model as well as the filters for the fuel and the year and finally it has the show more button for the pagination we have implemented the different images for different cars so we have the BMW M8 competition here 2022 and also a Mini Cooper which we get different images for this is looking great and with that we're slowly approaching the end of this phenomenal project we have the navigation bar we can check how does the mobile app feel and look like and it's looking phenomenal it is completely mobile responsive and the pagination is on the bottom so the only thing that's remaining to do is to fix this current bug in the next JS 13.4 and try to find an alternative solution and don't worry we're gonna do that right away and try not to look at it as a pain in the ass but rather as a lesson as I said by the time that you're watching this video it is possible that this is already fixed so definitely make sure to check out the description and check out that latest issue for the new updates but even if it's not fixed it is a good thing because the only alternative solution to this is to transfer the code to client-side rendering so now we have everything with the new nexgs 13.4 server side rendering but we're gonna show you how to transfer it to client-side which is going to show you a clear differentiation between server-side code and client-side code rendering this is going to strengthen your foundation on how and when to approach server-side rendering if anything think of this as an extra lesson to really see the benefits of server-side code so with that said let's convert this to client-side to show you the differences and to fix these annoying bugs that we currently have let's collapse our browser to the right side of the screen and let's close all of the currently opened files first we can collapse everything and dive into the app page.tsx here is where most of the changes are going to happen because this is the component that's going to be transitioned from a server side page to unfortunately a use client page so this is no longer going to be server side rendered so let's explore the differences between the two in this case it's no longer going to be an async function so just export default function home and we also cannot get search parameters from here with the client-side approach it's going to be more similar to your typical react application we cannot fetch the cars right here immediately rather everything is going to be spread through more use States so let's create all of the used states that we're going to have I'm going to create a use State snippet and the first state is going to be all cars set all cars and that's going to be equal to an empty array at the start then we can create a second use State snippet called loading set loading and that's going to the start be set to false then we can create all the different search states that we're going to have so we can say use State snippet manufacturer and set manufacturer at the start equal to an empty string then we can create another which is going to be for the model so model set model and then an empty string finally we need to have our filter States and if you're wondering how am I creating these dates so quickly well I start typing use State I click use State snippet which allows you to use a tab key to Traverse through different parts of this so first of all you say fuel you press Tab and then immediately you can specify the default value which is going to be an empty string so let's keep this going we also need a state for year and set year at the start set to 2022 and finally we need to get the limit which is the pagination state so that's going to be use state limit set limit at the start equal to 10. and I can see that I didn't even import use state so we can import it at the top coming from react right here and now that we have all those States we're going to also use a use effect hook it accepts a callback function and it's going to be executed whenever any of these parameters change so whenever fuel changes the year the limit the manufacturer or the model change we're going to recall our use effect which we also have to import at the top from react now inside of here we want to call a function that's going to re-fetch the cars so we can say get cars and this is a function that we can create just above the use effect const get cars is equal to an async function where we're going to do something similar to what we did before so maybe I shouldn't have removed the initial fetch for all cars because we need something incredibly similar so right now I'm going to go all the way back by holding Ctrl and then Z just to remove all of those States and you can do the same but be really careful and now I can copy the fetch cars and hold Ctrl shift Z to go all the way forward it's going to be something similar on Mac as well so within the get cars we want to do what we were initially doing in the server side approach where we do const all cars or rather we're going to call it a result in this case a weight fetch cars and then we pass all of these additional options but no longer are these gonna come from search params rather we're getting them immediately from the state once we get the cars we can simply set all cars to be equal to the result again this might be something that you're used to if you were working with react for a long time also a good practice here would be to copy this and remove it and put it within a try and catch and finally block which looks something like this the code that we have goes into the try in the catch we can simply console.log the error and then in the finally we're going to set the loading to false and initially we're going to set the loading to true so we want to have some kind of a loading State because next.js is no longer doing that for us so now we have all of the states and we are fetching the cars and if we now save this we haven't saved in a long time and go back you're going to see that we have some kind of Errors because we're still referencing search params here on the bottom so no longer this is going to be search params now we immediately have the limit in the state if we save it we get a couple more errors but it looks like we're good believe it or not we can see all the cars so now we're back at status quo we're back at where we started where we can see all the cars we're fetching them client-side now but we are not utilizing the set States so now we cannot modify anything using these things right here so that's going to be the next step in the search bar right here we'll have to pass some states down and that's going to be set manufacturer is equal to set manufacturer and we're going to also pass the set model is equal to set model we're passing it true in the filters we're going to have to pass the set state so in the custom filter we're going to pass the set filter to be equal to set fuel and for the second one we're also going to pass a set filter which is going to be equal to set year then below the all cars that length right here we no longer have this is data Mt so what we can do is we can say if all cars that length is greater than zero like this then we display all the cars and also below this div we can render a loading tag so we can say if we are loading we're going to show our loading right here that's going to be a div that's going to have an image and that image is going to have a source equal to forward slash loader dot SVG I'll tag equal to loader width of 50 height of 50. and class name equal to object contain the div itself is also going to have a class name equal to mt16 to divide it from the top W Dash full and flex Dash Center now we haven't yet imported the image so let's import the image from next image right here at the top and that's good now if we reload we should be able to see some cars loading right here and we also have to change the show more button to the show more button we're going to pass the page number which is going to be just limit divided by 10. the is next is going to be if limit is greater than all cars.length and then we can simply pass the set limit to it as well because now it's a manual state that's all that we need to do in our page but now we have to dive into the search bar into the custom filter and into the show more to be able to make these work with the client-side approach and now we can go into the search bar and accept the set manufacturer as well as set model you can see that these names clash with our current states that we have here so let's rename our manufacturer to search manufacturer and search model and let's also rename their Setter functions to set search manufacturer and set search model now you can notice that we have the name clashing here so let's rename our manufacturer to search manufacturer and we can rename all of the instances of this variable by simply pressing the F2 key on windows at least and you can simply type search manufacturer you can repeat the procedure with the set manufacturer to set search manufacturer and repeat the process with the model search model and this is going to be set search model like so so now we can see that here it's going to say search manufacturer search model search model search manufacturer and we no longer want to update the actual URL params the only thing we want to do is set them to the state so now we can say set model is equal to search model like so and repeat that for the manufacturer set manufacturer is set and then we pass the search manufacturer great so this part is now good and then we no longer need to use this function to update the search params so we can delete it now keep in mind we have to pass the data to the search manufacturer sub-component because it is the one that's actually changing those values so here we can pass the selected as the search manufacturer and set selected as the set search manufacturer there we go finally we can modify the input for the model it's no longer going to say set model this time it's going to be set search model right here and ensure that the variable is search model right here and we now can go into the search manufacturer to modify these values no longer we're getting the manufacturer and the set manufacturer now we're simply renaming them to selected and set selected which make more sense so here in our combo box we can pass the value as selected and on change set selected there we go so now if we try out the search it should be working let's try with Audi and click search and we get an error which is okay it says set model is not a function on search bar line 33 so if we look into 33 it's going to be here we have a set model and it looks like I missed the curly braces which we need to destructure the params being passed into the function so if I fix it and try to go with something like Aston Martin and click search it actually works you can see that the images change and the titles change as well and let's try to go for a specific model let's try to search Vantage so I'm going to pass that as a model right here and we can see that there is only one so that means that the search for both the manufacturer and the make work and as you saw this time no longer do we have an issue where it just Scrolls all the way to the top of the page now we can immediately see the changes live right here which is great now let's fix the fuel and the year as well so for that we have to go to the custom filter component and then in the custom filter we're getting an additional parameter which is set filter and the only thing we have to do is no longer update the params right here so we can delete that part as well as delete the use router and instead of handle update params we simply need to set filter like so now if we save this this should be working so if we change the fuel to electricity we don't have any Ferraris that are electric but if we try to go back it doesn't seem to work so let's try that one more time by removing everything from the search query and let's try to go with something like let's do something different this time let's do a Chevy and search okay that worked the image has changed and now we can switch to electricity no cars what about gas no the gas didn't seem to work so let's go check out if we're properly updating the filters in the page we have the get cars that update when the fuel or the year change so in here we can console log the fuel or the year and see how does that look like as a matter of fact why not console lock all of them to see what the current state of the properties is so I'm going to open up a console and reload the page immediately we have a warning for the key prop which is okay but now if we try to do the same thing we did before that's going to be a Chevrolet and let's try to see if it gets updated if I expand it just a bit we have the search here yep that's good the values are updated and now we can change to gas as you can see the title and the value seem to be gas that's from the fuel that we can see right here and then we have the additional properties of year and everything else so it looks like for the year we get just a year but if we try to change it again now it turns into this object key value pair where you have the title and the value not necessarily just the value which we need so let's fix that the only thing we need to do to fix it is here in the set filter we need to say e dot value which then should update it properly so now if we go back scroll down go for something like Chevrolet one more time and check the electricity it's going to go to none back to gas and we are good now let's try with something we had before just to verify it is working so let's go back to Audi search this is looking good and the images appear one more time let's see if ADI has some electric cars no results for the Q5 2015 but if we reset the year nope still nothing so Yep this is looking good to me if we go back we have some cars wonderful the filters and the search are working and the last thing that we have to do is going to be the show more so if we scroll all the way down we should have a show more button right now we don't because we are just searching for it but if we reload the page the button should be right here at the end and if you click it right now it's not going to do anything but if we go into it right here in the show more we can now make it work by accepting the set limit property and instead of pushing to this new route and updating the params the only difference we have to make is set limit to be equal to new limit and no longer we're using the router this is the only difference so now if we save this and click show more you can see how immediately the cars appear and it's not scrolling all the way to the top which is exactly what we want wonderful and with that we have successfully converted the app from server side to client side again just use this as an educational lecture on the differences between the two as you saw the new next GS way where we simply call the fetch cars immediately on top based on the search params was in my opinion cleaner with the client-side approach you're going to have a lot of states and you'll have to manage it all manually and then refetch it using the use effect hook another thing that you can notice is that now if we switch some parameters like fuel to gas or year to 2022 and maybe go for something like an M8 right here you're gonna notice that no longer does our URL change so now if you want to copy this URL and share it with your friend when they reload the page and come back they're gonna be back to all the regular cars and not the series that you had and also since it's client side it should be a bit slower but again take it as an educational lesson to see the differences between the two in case you want to revert it to server side you'll be able to see that in our code base there's going to be a couple of branches right here there's going to be the main branch with the server side code and then the client-side version so if you want to see the differences from the two versions immediately checking them out in the pull request right here should be possible so this is going to allow you to see all of the differences between the two how we had to add all of those States remove the search params way and then manually fetch the cars but hopefully the next.js team fixes that small bug of changing the scroll position when we change the url parameters with that said we came to the end of this phenomenal build and we are ready to get it deployed to the internet so let's do that next we've created this application using nextgs and nextgs is owned and created by versel so we're gonna use it for deployment go to versel.com and click Start deploying then continue with your GitHub next in here you'll be able to see all of your GitHub repositories which means that now is the time to deploy our project to GitHub so go to github.com and then create a new repository I'm gonna call it cars underscore showcase and I'm gonna leave it as public next create a repository back in our code we can stop the terminal from running by pressing Ctrl C and then y we can clear it and then run git init git commit Dash M initial commit and we must not forget git add before and then git commit Dash M initial commit finally we can do git Branch Dash M Main copy the following command get remote ad origin and finally git push you origin Master that's the only thing we need to do to push our repository to GitHub once it's there you can go back to Versa and immediately it's gonna show right here so you can just click import now in case you use some environment variables you'll have to copy them from your dot EnV and put them right here into environment variables in my case I put the keys in the code so I can just go ahead and click deploy it looks like I have to navigate to my other account right here and I'm gonna just try to click deploy again and hopefully everything goes right and there we go the deployment process has started let's give it a few minutes and I'll be right back it looks like the build has failed and if we checked it out that's because now we're getting all of the typescript errors that we didn't necessarily fix in our application when we were converting it to client-side for now just to go through this quickly I'm gonna go to next.config.js and then within here below images we can say typescript and there we can say ignore build errors is set to true now of course we have to commit this so we can do git add git commit Dash M ignore errors and then git push this is going to push it and immediately we can reload the page and you can see a new ID is going to be added to your project name which is when you can click deploy and there we go our application has been deployed and this is looking great so let's click it and that's going to open it right on this URL which means that the application is now live so if we scroll down and try to go with something like Audi and let's do something like A4 this time and click search you can see it is actually working the images are getting reflected and let's see if there are any electric ones I don't think so but if we go back it works and you can also change the year to something like 2022 and that works as well wonderful with that said we've came to the end of this phenomenal build where we had an extra lesson of discussing the differences between client-side and server-side rendering and hopefully with this now you can see the benefits of next gs's server side rendering as I mentioned in the intro this application was a lighter version of the application that our master class students have built here is the final design as you can see it is much more comprehensive and it allows you to actually add your own cars not just fetch them from the API search them based on filters and then see car details and finally run them this is going to of course allow you to implement full crowd functionalities turning this into a full stack nextgs or more an application whatever you prefer so if you're with us in the master class and you account after an issue such as that bug in nextgs where we had an issue with the scroll position we would be there for you to help you immediately solve it and ensure that you learn as much as possible from the process so if you're sure you want to become an expert software engineer join us graduate within six months get your dream job within another six and get all the support from the mentors or you get your full money back with that said thank you so much for watching this phenomenal build it truly was a pleasure to build it and to have you all with me alongside in the process and please let me know in the comments down below what would you like to see next maybe a clone of a popular build maybe more next yes Super Bass Charisma I don't know let me know what you'd like to see more of in the comments down below thank you so much for watching and have a wonderful day thank you [Music] [Music]
Info
Channel: JavaScript Mastery
Views: 154,775
Rating: undefined out of 5
Keywords: javascript, javascript mastery, js mastery, master javascript, next.js, next.js 13, Next.js 13, Next.js, React, Server Side Rendering, Static Site Generation, Web Performance, Vercel, SEO, Web Application, API, Web Frameworks, Next 13, Next 13 App, Next 13 Development, Next.js Development, Next.js Web App, Build With Next 13, Next.js Tutorial, Next 13 Tutorial, Learn Next.js 13, Next 13 Features, Next 13 SSG, Next.js 13 Tips, Next 13 Project, Getting Started With Next 13
Id: pUNSHPyVryU
Channel Id: undefined
Length: 206min 9sec (12369 seconds)
Published: Fri Jun 09 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.