Build a Pokedex with NextJS and Tailwind CSS - SSR vs SSG

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what is up everyone today i want to talk about next js and how to use it as a framework built on top of react to build both server side rendered pages and static pages and the difference between those and to do that we're going to build this really cool pokedex using the pokemon api and tailwind css to style it so let's go ahead and dive in all right so here's a look at the finished example of what we're gonna build uh we'll have a list of all of the first 150 pokemon this page is a static page so this page at buildtime will go out and grab all the information for these pokemon and we'll build this one page and then the details page for the pokemon is a dynamic server-side rendered page because in this case we may not want to build 150 static pages that might be too much at some point it's going to be too much so in this case we'll just do a server side render page for the details of the pokemon and we can navigate between these and so on i think this is going to be a lot of fun if you're new to the channel i do web development tutorials every week using javascript different frameworks things like that so if you enjoy this one make sure to like subscribe to the channel and turn on the notification bell so that you can get updates as new stuff comes out all right so we are ready to dive in now i already have created a create next app already so to do this you can run npx uh npx create next dash app this will give you exactly what i'm starting with here you also have the source code that i'll link in the description below that you can reference as well all right so to get ourselves started let's go and just kind of look at the files that next js gives us well by default it gives us a pages directory and then an api directory inside of that we don't need the api directory this will get into that more in future videos so stay tuned for that and if we look in our index.js this is our basic page that is going to be rendered so let's do let's go ahead and start this up let's do an npm run dev so let's go ahead and run this to show what we got this is available to us at localhost support 3000. so if we refresh this this is the boilerplate stuff that next.js gives us we're going to change the way we do a lot of this stuff this comes with css modules we're going to use tailwind instead so let's get rid of these styles and i'm going to do some cleanup so everywhere i see styles dot i'm going to go ahead and remove that and then i'm going to get rid of all the stuff inside of this main and then we'll get rid of the footer as well and then we'll be left with something a lot simpler which is more what we want to work with so here's kind of what we're starting with and from here we can go ahead and configure our project to use tailwind now i follow this article that i will leave in the description as well so you can have a link to this it's a pretty simple one there's a couple of dev dependencies we need to install so uh tail one css and post css preset env so i'm gonna paste in that we'll go ahead and install that and then down to the next instructions uh our npm scripts are already configured because we use create next app we already have an index page created uh we don't need to start the server yet what we can do then is run the npx tailwind init this command will create the tailwind config and while this is still loading if you're new to tailwind this is a css framework that is based on utilities first so you get all these utility classes that you can combine to customize your application in whatever way you feel is really useful tailwind is it's really gained a lot of popularity in the last year maybe several months people love it i wanted a reason to check it out myself i think you'll enjoy what you see in here so i'm going to do the mpx tailwind init this will create this tailwind config file so that should be created for you and then we'll need to grab or actually create a postcss config.js file as well so i'll copy this little snippet in here and then come over and this will be post css.config.js and just paste that part in there now the last thing we need to do is actually import actually use tail one stuff so importing this in the appropriate place so what we'll do is we'll copy these uh these three imports right here and we'll go into our styles global styles and i'm gonna get rid of everything that's in there paste in this new tail one stuff and then go into the home module and just delete that so now we're just sticking with our very own css that will be tailwind so if we go ahead and run this again we should see that now our application is going to look a little bit differently because tailwind is going to do lots of resets for us and this text up here this h1 should actually look a lot smaller okay so this is obvious that tail one is taking effect because this is much much smaller one of the things i want to do is i want to create a components directory and inside of here let's create a new file for a layout js and then i will stub this out i'm using the react es7 react redux snippets you can see a video on that i'll link to up here if you don't have this it's an extension in vs code that is really really useful for this sort of stuff and this thing is basically just going to be a little wrapper around the stuff that we get in our pages so we want to have a head in each one of our pages so i'm going to copy that little snippet so there's our head and we want to take in a property of title that will pass to this layout and we'll also need to import head from next head so this will be kind of our header information and instead of create react app we will or create next app we will just pass that to title and then what we want is this whole thing now to basically our html to have a little bit of background color so we can add a class name of and then we'll do bg gray 300. now what this is in tail one you can do a background on gray and then they've got different scales that you can use in there in this case 300 is going to be the shade that we're going to choose and then uh we'll have our main and we'll have a few classes on this as well mainly this is just going to be a container so we'll have the container class then we'll say mx auto this is like your margin 0 auto trick which will center the content we'll say the max width is going to be xl and these are kind of relative you could a lot of these sizes small medium lard x large xl and so on and so on we'll do padding top of eight and then min h screen means we want the min height of this to be the height of the screen and then here we'll pass in the children that we need to include in our props so all this is this little wrapper layout component that we can use inside of our different pages so that we don't have to repeat the same stuff so what we'll do in here is import layout from i'll lay our our layout file and then we'll wrap all of our content with layout and pass it the title of next.js pokedex and then we'll update our h1 to be next js pokedex as well i think this should be uppercase h for head so next slash uppercase h so let's see what this looks like uh we get you can tell uh the stuff is uh the main content here the container is centered and then we also have this background color of the bg gray so we see that stuff coming through now we can go ahead and actually style this a bit more with some of the stuff that is going to be really useful so inside of our h1 let's go ahead and style this thing so we want it to be text wise a lot bigger so we can do text dash for excel that'll be relatively big we'll do a margin bottom of eight and then we'll say text center now you can kind of see how after you get used to these tail one classes you can really style things pretty quickly based on just kind of using those classes and putting them together so we've got that now we need to actually go and get our pokemon information now here's the cool thing with next.js is inside of our different pages we can export export async function two different types of functions to determine whether a page will be statically rendered or server side rendered and the first one that we'll work with is get static props this is going to take in a context and then here what we want to return is an object that has props and then something inside of those props so by defining this async function git static props next.js will know this should be a static page before or at build time it will go and run this function grab all the information from the pokemon api that we go and grab in a second and then pass that into the index page so that it's a fully static page by the time it gets pulled down by the user so let's look at let me copy this url let's take this url into the browser and just to kind of show you what the pokemon api returns so this is polka api dot co slash api slash v2 pokemon and then i've got a limit parameter here of 150 this is so that we can grab the first 150 pokemon and inside of this results tab you can see it returns back objects that have a name and a url and really here we're just going to use the name of the pokemon so what we want to do is inside of the skit static props we want to go and grab all of that stuff we'll do that using the fetch api fetch is kind of built into next so you don't have to do any sort of import for that and then i've got a pretty cool snippet in vs code to stub out a fetch command surrounding it with tri-catch so we can handle any errors and what we'll do is we'll paste in that url so we want to get all 150 pokemon from that url we'll get back that response and then we'll get back the data but if you look data actually has a property called results so we can get the the pokemon from destructuring that results property off of uh the data that comes back from the body if that stuff is new i've got a video on the fetch api that you can look at as well for figuring out how the fetch api works with getting data especially using async await if that is new for you as well so the one other thing that i want is i want to for each pokemon on the home page i want to display an image but you see we don't really have an image here well there's on pokemon.com on the pokedex i looked at the images here so if i copy the image address and paste this up here you can see that there's a url that has a number at the end that shows which pokemon you want to get and these are if you're used to pokemon they're 1 2 3 4 through 150 the same indices or indexes that we have in the information that we just grabbed so what i want to do is i want to take these results and augment them to include an image property that we can then use so what we'll do is say kant's pokemon equals results dot map so we're going to take each result each individual pokeman or actually i guess we can call this result we'll get the result and the index and then in there we want to return a new object that has the the result all the properties of the result all the properties of that pokemon as well as an image url so the way we get that image url is i'm going to paste in this raw url here and surround it with es6 template literal strings and we'll say const image equals and then that string but this is not quite right if we look at this because we need to replace this part with the index of the pokemon now you might think you could just do this so you might just take the index and just put it in there like that but if we look back here if the index is one that doesn't quite work it needs to be padded with two zeros at the start so what we'll do is we'll get a const padded index equals and uh this may look a little weird we're gonna add two zeros to the beginning of the index plus one now the index is zero based but pokemon start at one so we'll so we'll just add one to the index and then we'll combine that with a string of two zeros so at this point what that will return is zero zero one or 0 0 10 if the index is 10 or 0 0 100 if the index is 100 so from there what we want to do is just grab the last three digits out of there so to do that we call dot slice and pass it a negative three so this is going to add on the prefix of two zeros and then whatever that string is it's gonna grab just the last three characters and that should be our padded index so let's throw this padded index into here and i will look in here i think i copied this https yeah so it should be the https there before pokemon assets so we're grabbing this image and we're basically taking the results that we get back which only have two properties a name and a url and we're adding on this image property so from here what we want to do is let's return after this map after we get all this data let's just return that data to the actual component so inside of our home component up here we can now get the pokemon and we can log it out so let's log out the pokemon all right so let's go back to our home page let's open up the console let's look in here and now you can see we're getting this array of objects and each one of these should have a image url here and if we copy this url hopefully and get rid of those quotes this should look like the real image cool so that looks like it's working which is pretty great now we can just kind of go through this and react and display each of the pokemon in the way that we want so underneath our title we will have a ul and then we'll iterate through pokemon.map so for each pokey man is the singular i guess we what are we going to return well we're going to return a list item so we'll have an li and each uh child inside of a map needs a key so we'll use the index as the key and then inside of that li we want to have basically a link to the details page if you remember that so the way links work in next is we need to import import link from next slash link and this allows us to do client-side routing with this link so we'll define the link here and we'll say that href for the link is going to be slash slash pokemon and then id so we're going to pass a query parameter of the index plus one so remember the indices that come in here are ray-based indexes so they're zero based we need to increment that by one to get a relative or relevant index for our pokemon so we'll have that link and then we'll close it out like this and i think this is a little bit interesting but you define your href inside of the link and then you add your anchor tag inside of that so the anchor tag itself in next does not need the actual href itself so inside of this anchor tag we will have an image and this will be a source of that image property that we added to pokey pokeman so pokeman.image and then the alt we can have just be the pokeman dot name all right so we'll have the image there and then we'll have a span with index plus one and then a period so this is just kind of like the index of the pokemon as you'd probably expect and then we'll just have the pokeyman.name all right and we can if we scroll back down we can get rid of this console log oh sorry up here we'll get rid of this log and now let's see what we got it shouldn't look great but now you see we have all of our pokemon so there's all the information that we need as well as if we hover on this notice it's uh showing you the url on the bottom left here of we will go to slash pokemon and then query parameter id and it's the right id so that looks good now all we need to do on this page is to style it which with tailwind we just add a bunch of classes so let's grab our anchor tag and we want to have this um have a border we want to have a padding of four we want to have a border of gray want to have a margin y of two so to give them some vertical margin between each other and let's just look uh to see what that looks like all right so you can kind of see some of the stuff coming together you see those classes are applying but one of the main things we need to do is go ahead and add some styling to this image and we can set the width to 20 and the height or h to 20. now this is not 20 pixels this is kind of the relative i don't even know exactly what tail one is using here but it's a relative to m's or rims probably is what it is and then i added some margin right on the image so let's just now see what this looks like where now it's a lot smaller okay so now we're getting closer to what we want but we want uh several different additional things so we want the name of the pokemon to be capitalized so let's see if that's gonna capitalize this pokemon yep so that worked there so capitalize the name of the pokemon and then a few other things we want to do a display of flex because we want to display the image the number and the name right in line and then we'll have items center this will vertically align the items and then we'll say text lg we'll say bg gray 200 this will be a slightly lighter color than the background of the um of the body and then we'll have a rounded md which is just kind of a border radius so now that actually looks pretty good now the one thing we could do is add a little bit of padding to the number so if we go down to the span we can add in here we can add the margin right of two maybe and then a font of bold and now look what we got that's pretty cool with tailwind just adding those classes will get us what we need so if i try to click on one of these it will take us to the pokemon id or pokemon and then query parameter id equals one but it says the page is not found well this is where we are going to create the page for this so inside of pages to add a new page you add a new file here and this will be pokemon.js and then i'm going to stub this out with my rfc command and inside of here we're going to need to import the layout from components layout and we'll also want to add a link back to the homepage so we'll add a link from next slash link and eventually this page will get the actual pokeman as a parameter and be able to display the information about the pokemon or pokeman but the thing we need to differentiate here is if you remember this index page is a static page so it's grabbing all the information about the pokemon at build time statically and then this details page is going to be a server-side rendered page so to tell the page to be server-side rendered instead of get static props we export an async function called get server side props and inside of here instead of just getting the contacts by itself we want to grab something called the query because based on that query parameter the id of the pokemon we need to then query information about that pokemon specifically so we can get that id by saying conts id equals and then query dot id and from here we'll do our little fetch snippet again so you can type this out obviously if you need to and i'm going to copy this url so this is now the url to get a specific pokemon and you'll see in a second when you grab a specific pokemon you get a lot more information about it so the data that comes back here is a pokeman and we want to do kind of the same i idea with the image stuff that we did before now we could create a helper function in here and do this if we wanted to but i want to grab the padded index so for this pokeman i want to grab the padded index and this thing will be the id plus one so we get that id from the query parameter and actually this does not need to be this should be the regular id this is not zero base so we don't need to add one there so we'll grab the padded index and then we'll grab the image again so that same little snippet will use the padded index in there and then we'll just say pokeyman.index or dot image equals image and lastly we need to return our props in here so return props and then inside of props will pass the pokeman and the only reason i'm a reason i'm specifying pokeman is just like singular uh versus plural this page maybe should have been pokeman but the routing would be next mixed up and so on whatever so uh hopefully if we now log the pokeman up here we'll see the actual information for that pokeman so let's come back and refresh and see the log here hopefully we see all the information about this user or about the user about the pokeman coming through here and now we just need to display it to wrap up this little pokedex in next.js so inside of here let's use our layout component and this will have a title of pokeman.name and then now we'll want to start to add all the details so we'll start with the title right we'll have an h1 and this will have a class name and you'll see the same tail one stuff again text dash for xl mb2 text center and capitalize and this will be the pokeman.name all right so there's our title then we want the image so we'll have an image with a source of pokeman.image like we had before the alt would be pokeman.name again and then we want to have some classes on the image as well so let's do a class name of and we just want to be able to automatically kind of center this thing so we'll have an mx of auto and we can get rid of the log here let's see if that image is coming through okay this should be a bigger image yeah so that's a pretty good sized image there so we got the name the image and then we'll just add a little bit of some of the properties of the pokeman so we'll have a p tag here and then a span with a class name of font bold and then mr2 so a little bit of margin to the right and we'll say this is going to be the weight and so this will be the pokeman weight and i'm gonna copy that line and do the same thing for the height all right so there's two little pieces of information hopefully those show up okay uh hot weight and did i misspell height maybe i did yep lower case height so that should be looking good now and then the only other thing or a couple of things i was going to add is an h2 with a class name of text 2 xl so a little bit smaller than the bigger one and then margin top of 6 and margin bottom of 2 and this will be for our types and then the types in here uh the the information is a little bit kind of convoluted you see types is an array of objects that have a a property of type inside of that it has a name a little bit convoluted but what we want to do is take our pokeman and call types dot map and we'll get each type as well as the index and then what we'll return is a p tag and we want to show the the type dot type dot name i know this seems a little convoluted it does to me too but we'll make sure that we have a class name or actually a key for each one of these of index i'm missing a parenthesis there see if that will auto complete for us and so let's just see if that gives us our height should fill in then we got our types grass and poison cool that works and the last thing i want to do is i'll add a p tag with a class name of margin top 10 and text center and then i want to have a link in here so this will be a link with an href to home and then inside of there we'll have our anchor tag with no href again that's a little weird in xjs to me but that's how it works and this will have a few classes as well text to excel and underline and then we'll just say home so this should be our last little bit here if we load this up and see our home page we can go back to home notice all of that at this point is still doing client-side routing which is pretty sweet and we'll click on bulbasaur we'll get those details we'll click on my favorite pokemon which is charizard there's those details and so on and so on so to me this is a pretty cool one it's pokemon how can you argue with that so it's kind of a fun demo but this shows some really powerful stuff in next.js where you can combine statically generated pages static pages like this index page with dynamic or server-side rendered pages which are going and grabbing information at real time at request time when a user requests this page we go and grab the information about that pokemon and return it back now in theory we could take all of this information and have it kind of static inside of a json file or something so we don't have to make an api request but just to kind of show you the cool mix of static versus server side rendered i thought this was a pretty cool example now one last thing i want to show you is you can run an npm run build and this will go through the build process and generate the static as well as server-side rendered pages and i want to show you how next will kind of let you know which is which here in a second all right so this finished building and notice that they show you a little symbol here's the symbol for a server side rendered page here's the symbol for a static page automatically rendered a static html uses no initial props then they also have statically generated html with the get static props so if you remember we use git static props in our index page so it has this little icon here which means statically generated as well as slash pokemon now shows you that it's a server-side rendered page uh with that little kind of serverless icon there i think this is super cool next.js is really really powerful to be able to combine these two things the combination of these in my mind i'm going to use next.js a lot going forward probably not using create react app and maybe even not using gatsby for a lot of things going forward next.js is super cool i hope you enjoyed it let me know in the comments if you've ever used next.js before if this video made sense and what you might want to see built with next.js in the future as always thanks for checking out the video if you enjoyed it give a like subscribe to the channel and hopefully i'll see you in the next one
Info
Channel: James Q Quick
Views: 13,115
Rating: 4.9840636 out of 5
Keywords: nextjs, tailwind css, nextjs tutorial, nextjs ssr, server-side rendering, static pages, static sites, jamstack, ssr vs ssg, statically generated pages, reactjs, static site generation, server side rendering vs client side, nextjs routing, nextjs fetch api, pokedex, pokemon api, javascript, web development, javascript tutorial, server side rendering react next js, static site generator tutorial, next js tutorial, next js, next js api, tailwind css tutorial, tailwind css react
Id: LMRAEUPkFXI
Channel Id: undefined
Length: 28min 59sec (1739 seconds)
Published: Tue Aug 25 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.