NextJS 12.1 SSR & SSG: Everything you need to know

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
with next js 12.1 you can render your react application on the server or you can render it at build time and that actually gives you three different architectural models for rendering your application you can do client-side rendering server-side rendering or static site generation and you have to pick each one of those on a per route basis it can be pretty complex and i'm here to guide you through it hi i'm jack harrington a principal full stack software engineer and in this video we are going to build out this pokemon application it has an index page that lists all the pokemon and then it's got a dynamic route for the detail page where you can see details on each one of the pokemon so what we'll do in this video is we'll start off building our application using client side rendering and then we'll deploy that to versal so you get to see how that's done then we'll convert it to server side rendering again deploy it and then we'll convert it to static site generation and you can see all of that and see how that's done and of course all the code is available to you for free on github let's go all right so before we get into building our version of this let's take a look at what i've already deployed to versal so you can see the versatile deployment over here this is the pokemon list page is the index page and then you can click on either one of the pokemon and get some detail and all of this is driven by some data that i've deployed to an s3 bucket and that's available to you as an independent project that's listed in the description down below so what we're looking at at the top level is an index.json file that has all of the different pokemon listed out i think there's about 802 of them then there's a detail page so it's pokemon one.json in this case and that's bulbasaur you get the name you get the type you get some stats and you get the image so these basically just drive the different elements of the ui this index.json drives the index page and then the detail json drives the detail page so pretty simple stuff and all the images are in there as well all right so let's go into building out our next application so i'm going to go over here to our terminal and go into my 2022 directory and then i'll do yarn create and then next app and we'll call this one next js pokemon modes okay and then i'll bring it up in vs code and i'll bring up the terminal and then i'll use yarn dev and that's gonna run it for us now let's take a look at localhost 3000 and we've got our next js boot page cool so now let's go over here to pages and we'll start hacking around on that boot page so the first thing i want to do is i'm not going to use image in this case since the images are all external i'll call my home page the pokemon list and then we'll get rid of pretty much all the contents of that okay so the first thing we want to do is go get our data so i'm going to bring in use date and use effect we need a place to store it so that's going to be use date and we need a time to get it and that's going to be use effect so i'll create a local value called pokemon which is just me the array of pokemon since this is the list page we're going to go get an array of the pokemon and then we'll use use effect but only on startup that's so i'll give it an empty dependency array there and we will go and fetch our list of pokemon so i'll go get our url here and i'll create an async function called get pokemon and in there i will get our response i'm going to wait to fetch the pokemon and then i'll set pokemon to be the json version of that so rest is going to give us our http response and then json is going to give us our actual data both of those are promises that's why we're awaiting them so let's do our git pokemon here and there we go so how do we know if this is going to work or not well we need to go and display that data so we'll go and take pokemon and then head down here and we'll put a div in there and just json stringify the data and that's just going to dump out the data for us so let's go take a look at the website over here localhost 3000. hey nice okay so next up let's go and make this pretty so i'm going to go over here to our styles and go and change out the styles so i'm going to create a grid it's a four column layout got a little gap there and our images are going to be capped at 200 pixels high all right let's bring in our tags and what we're going to do is wrap our list of pokemon in our grid to give it a four column layout then we're going to have a card that's going to cap again that image to 200 pixels we're gonna have a link to the detail page so slash pokemon slash id that page doesn't exist yet but we'll get there and then within that we're gonna have an image and our pokemon name so let's go and import that link so that works this is the next.js router we'll bring in next link it's going to handle all of our routing for us super nice and the only extra thing we need to worry about is this eslint issue here and that's just nexjs telling us that we aren't using its image component and that's because we're using external image so let's not worry about that and i'm just going to go and paste in an eslint that gets rid of it and looks clean let's check it out yeah nice all right cool but if we click on one of them we get our 404 because we don't have that detail page so let's go and implement that so the next thing you need to do is create a folder in here that corresponds to that route so pokemon here needs to correspond to this slash pokemon here and then the id is going to be mapped to brackets id.js and so in this case that one that's here or pokemon 2 in this case is going to get mapped to an id 2 coming in here in params but for the moment let's just go and export a default function and we'll call it details and we just want to return some like hello world okay looks good okay now we want to get that two i want to figure out which id we're looking at so we're gonna bring in the router from next router and then with that we can get the id so we're gonna bring in id from the query and we can just put that in there as id cool looks good try it out hello too awesome i do want to bring it in a little bit from the sides let's go over here and add a little bit of padding one rim all right there you go that brings it in a little bit nice so we've got our id now so let's go get the data so i'll bring in these imports because we'll pretty much use all of these and also bringing my eslint because again i'm going to have an image in there and i'll bring in my use effect and my use state from down here because it'll pretty much be the same ish so let's take a look so pokemon in this case isn't going to be an array it's going to be an object y because if we take a look over here at this detail route what we get back is an object and that's got the name and type and the stats and all that so we don't want a an array in here we want null which will be replaced by an object once we get it but if we have nothing in there so no pokemon then we're just going to return null for the moment so we don't need to go check it all the time and and then we want to go and make that request to that particular url so we need to put the id in here so let's put in id in there and we need to run this effect whenever id changes so we'll put id in here and then we'll say if there's an id then go get our data and to check out make sure that it's working we'll do our json stringify trick and then let's take a look okay we're getting an issue on that import of the styles that's not the white one anyway but for the moment we'll just do this all right cool so we're getting our data awesome so now let's go and set up our styles so i'm going to create a new file called details.module.css details.module.css and then in there i'm going to bring in the css for that layout again it's going to be a grid i'm a huge grid fan uh and then we're going to have some waiting bold on name type's going to be on italics and then mostly for the picture and for the table cool next thing to do is define our head tag so let's go down here and give ourselves a title so we'll say that we are titled the name of the pokemon makes sense and then we'll give ourselves a link back to the home page let's take a look nice okay so yep ivysaur back to home cool let's go hit by bulbasaur nice all right nice so let's start building out the content so i'll put the picture on there let's take a look oh nice all right now let's build out the second column so up at the top we'll put the name and the type which we will is an array so we'll join that using commas okay looks pretty good and the last thing we need is that table of attributes so let's pop that in there and we'll just use our header styles to give our name and our value and then we'll go and just iterate through the list of stats get the name the value and build out a row for each one with the tds nice okay so yeah beautiful okay so this page is client-side rendered what does that actually mean well if we take a look over here and inspect and then we go over to the network tab and we hit refresh we can see that we're actually making a request on the client to that s3 bucket to go get that data so what's happening is that nexjs is server side rendering the page our component in this case says no we don't have any data yet so we're not going to render anything that's when we say if no pokemon are going to return null but we wait until we get on the client that's when that use effect runs and that's when we make that request now i can show you that that's the case by going over here to view page source and this is what we actually get back from the server and you can see that inside this div id next which is where we mount the app it's completely empty there's nothing in there so we can experiment with this a little bit further by going back to home and it's doing the exact same thing but if i were to go in here and put like say an h2 up at the top here and say pokemon list we can see that we get a pokemon list at the top of the file that's really cool and if i you view page source we can actually see pokemon list right at the top of the file right here so so in xjs you're always doing server side rendering you can essentially choose to do client-side rendering by writing your pages like this and that might be the right choice for some applications you might want to forestall rendering until you get to the client so when would i use something like client-side rendering well if i was doing an e-commerce app i might use client-side rendering for something like the cart and the checkout page which are completely dynamic and really you don't get any benefit at all from doing any server side rendering on them so let's go and deploy this application in order to do that i need to go over to github and then i'm going to create a new repository and i'm going to call with the same name as our application so next.js pokemon modes and we'll say that this is our demo and now we want to go and add our code to it so let's go here and stop our server and then add the remote and then we're going to add all of our code commit it with the traditional first commit and then i'll use the push origin main to push it up to github okay we're good to go let's go reversal and get it deployed all right so we'll do a new project here and we can see that our next.js pokemon mode's up let's import that and get it deploying all right looks like we're good to go let us go to the dashboard and click on our domain and there we go and i can click on ivysaur and there you go and of course again it's all client-side render so let's go now and port this to side rendering and see what that's going to take so we'll go back over to our code and we'll start off with our index page and so what we're going to do is we want to do this request this fetch at server side time and so you need to do is create a new exported function out of here and that function is called get server-side props and so what it does is it makes any requests that you need to any services gathers up all that data and then returns an object that has props in it and then those props are then sent to the react component which then renders them so this is going to be an asynchronous function so add on async there and then we'll grab this request and then we'll return an object that object will have props in it and the props will have pokemon as the name of the prop and we'll get the act.json and that's going to give us our list of pokemon so now down here all we need to do is take pokemon as a prop and we can get rid of all of the client side code all right let's do yarn dev and make sure it works okay we'll go over to three thousand all right it looks like it's working but the truth is if you do view page source will i go and see that huge set of tags so we'll do vph source here line wrap and wow yeah we get a lot of tags so what's happening is that when you make the request to the home page that's calling our get server side props function first we're then going getting all that data we're turning it as props and then this home component is getting rendered with that pokemon prop and rendering out our results now you could use this in conjunction with client side rendering you could have some data that is requested on the client after the page loads so it's not really an either or thing here you can do both all right now let's go and take a look at how to do the id page that's a little bit more interesting because now we've got a parameter we've got id so how are we going to manage that so again we're going to do export an async function get server side props now server side props takes us context and in that context when you know it are the params and that params includes our id so down here we're gonna do our fetch and we're going to return our props with our pokemon and the only difference is here is that we need the params.id all right let's get rid of our client-side stuff we don't need the router and we don't need our use state and use effect and let's try that let's go over to our page and we'll hit ivysaur and we get pokemon is not defined fair enough so go over here pokemon and let's see if it's server side rendered by doing view page source yep here we go so now everything is getting written on the server side and going over the client so in terms of network traffic it's really great because now all of the network connection to like your backend services like your database or whatever that's all happening on the server side in your part of the cloud so it should be uber efficient and you don't need to waste your customers bandwidth by having them go back to your apis all right let's get this deployed go into the terminal again i'll stop the server then i'll add our changes i'll commit it moving to ssr and i'll push that out i'm going to use my ggp this is an ohmygish extension to push to the repository just a little bit cleaner and easier let's go and check over on reversal to make sure it's actually happening all right there we go moving to ssr wow that was fast okay let's try it out right looks like it's good let me make sure that it's ssr yep looks like ssr cool and now we got charmander perfect awesome okay okay so server side rendering when would i use server-side rendering if i was doing like an e-commerce application i would definitely use server-side rendering for something like search where you're getting a query you don't know ahead of time what all of your potential queries are going to be so that's an excellent time to use something like server-side rendering again you can use it in conjunction with client-side rendering if you want to have some stuff that you get on the server and then some stuff that you get on the client so let's move on to what i consider the most fascinating part of next.js particularly in 12 and 12.1 which is static site generation so running a server means running a server you got to monitor it you got to make sure that it's up and running all the time you got to scale it when your site gets big so what if we could have a system where we just basically go in at build time build out all these pages and then deploy them to a static asset store and then we can sleep happy at night because there's no server and there's nothing to go down well turns out that you can do that in next.js which is awesome and you can even do it in the same site as some other pages that are server-side rendered so you can have some pages that are csr you can have other pages that are ssr you can have some pages that are statically gender right generated and it's all part of the same application so let's go and take our application now and turn actually all the routes into ssg or statically site generated routes but you know you can decide for you on a per rap basis which one you want to use so let's go over to our visual studio code again and take a look at how to port over our index page i mean this is going to be a lot of work to go make this change you got to change this to get static props yeah that's it honestly that's that's all there is to it okay so let's try this out yarndev and look and there you go now there's actually no visible difference here in development mode between statically generated versus server side generated but trust me once we get this built and deployed you'll see a big difference in the build times because we're actually going to be building out all those html pages and deploying them all right so now how do you do this with the dynamic route this is actually where it becomes a bit more interesting so let's go over here to our id and then again we do get static props that's the same but here's the rub with a dynamic page like this you need to know what all of the routes are so the way that you do that is you create another function called get static paths and what it does is return an object that has a list of all of the different paths that we should be generating and those paths are basically just specified by their params so in this case it would just be the id so how we're going to do that well first thing we need to do is get our list of all of the pokemon so we already thankfully have that code so let's go and grab that and put that in there that's got our list now we need to go get the data so we need to await that data and then we're going to return a list of paths and we're going to take each one of those pokemon and we're going to map that and with that we're going to create an object and that object is going to have params and it's going to have that id the only little twist here is that we need to convert that id to a string that's it and the other thing we need to do is define whether we want a fallback page now a fallback page basically means hey if they hit that route and it's not one of the pokemon you want to go and generate essentially an empty page let's not do that in this case but you know it's pretty simple to do so we're going to say fallback false all right let's go check out our page and see that's going all right looks pretty good okay so now let's deploy it so again i'm going to stop i'm going to get add dash a i'm going to commit say moving to ssg and then i'll push that ggp and we'll go over reversal and watch it go okay because it's a bit more complex i'm going to go in here and we're going to take a look at the build as it's running so what you can see is it's generating static pages so it's got 802 static pages that means i guess there's 801 pokemon and then there's the one index page and so it's actually going and literally building out files for every one of those and then it's going to upload those to a static asset store and that's what's actually going to run our site super cool all right you can see down here the kind of pages that we built and the sizes so we got pokemon one pokemon 2 and 792 more paths cool as well as the webpack stuff and now it's uploading all those build files so it does take a while to build this it is slower to deploy one of these sites because yeah we're going and building out all of these pages all right looks like it's done let's go check it out and there you go yeah it seems to be going now you really can't tell the difference between this and a server-side rendered site but if i were to go for example and change this data like let's go over here to bulbasaur and let's say i want to go and add a new type it's not going to change on our statically generated site because it's not going to know that that data is changed if it were a server-side render page or if it was a client-side render page it would be consistently going back to that api endpoint and if i were to make changes to it then it would show up here so let's go make a change and make sure that that doesn't happen first and then i'll show you how to make it happen even with a statically generated site so go back over here original studio code and i'm going to bring up my finder and what i've done is i've gone and mounted my s3 bucket to my finder in os x using a system called mountain duck there's a link to that in the description it's a pay for product i think it's like 40 bucks and it basically gives you the ability to mount any kind of exotic file system like s3 to your finder pretty cool so i'm going to go into the pokemon directory and i'm going to drag that onto here and now if i say that one of his types is being super awesome and i can save that and i can go and take a look on s3 and we can see that here's bulbasaur and if i refresh then yes he is indeed super awesome but if i go over here to our deployed site and hit refresh that's not going to show up it would show up again if i did ssr or csr it would be making that request and it would be getting the fresh data so how do we get fresh data back into our statically generated system well they offer two different options in next.js and the first one is pretty simple i go over here to our ide.js and down here after prompts i can say revalidate and i can put in a time say 30 seconds and what this means is any time that that route gets hit it will go and actually make the update to the page if it hasn't done that update within the last 30 seconds or so so this is basically a throttle basically means that you will update that page but you'll only update it every 30 seconds and you get to pick that time so let's go and update the code with this and see how this works so add it then commit it and push it and we'll go over to reversal and check it out all right we're building our deployment i expect that it's probably going to take about two minutes huh it'll only take a minute 50. okay cool so let's go over here to bulbasaur and see what's up well we've added super awesome and we would expect that because during the build process it will have gone and gotten the new data okay fair enough but now let's go and make a change and see how long it takes to show it up all right so let's go and add on crazy awesome and now we'll hit refresh and so basically ah there we go and now it's updated cool so we hit it within that 30 second window and we it went off and got new data so this is really nice if you have a high traffic page where the serious contents of the page aren't going to change that often a really good example of this is in an e-commerce application like the product detail page of the home page where you might have some reviews or comments you don't want them updating with every single request right so this gives you the ability to revalidate that page but throttled at the level that you want it okay but what happens if you want to actually force the page to revalidate so i have an update i want to do it right now so they actually offer as of 12.1 another option for that so let's go back over here and i'm going to take out revalidate and then what i'm going to use is the api so currently when you build an xjs application it comes with this api hello if i go do yarn dev here and then go to three thousand and hit slash api hello we get back name is john john doe sure whatever and that's basically the output here so what this is is this is an express endpoint effectively and you get to define that it's really nice that next js has this ability built into it and one of the cool new things they've added is the ability to do for example res dot and you can say unstable revalidate and put in your url so in this case it'll be like for example pokemon one but we want to go make a real endpoint here so let's go and create a new one called revalidate.js paste that in there and we'll say revalidate true and what we want to do is we want to get a list of all of the urls to invalidate so we'll use the body for that so the body will be an array so we'll do four and then we're going to assume that our we have a url and it's in rec.body and then i call that unstable revalidate it's an asynchronous function so this needs to be an async function and yep that should be good okay so what we're expecting is we're expecting body to be a json array and that's going to have the urls that we want to invalidate all right so let's go and deploy this and we'll do add dash a we'll commit that and we'll say adding forced revalidation i'll push that up and while we're waiting for that to go let's go and build ourselves a little curl little post to that endpoint the url that we want to invalidate so let's go here and create a revalidate sh file and we'll put in there curl and what is our endpoint so we'll go back over here to our deployed site and it's going to be api revalidate we'll go to the next line we'll say that we want this be a post and then we want a header so we say application json so that is a json post it expects that the content type in this case is json and then finally what do we want for the data so we put little d and then we put brackets for an array and then we escape out a string and put in there our url so in this case it's going to be pokemon one so we're going to invalidate the bulbasaur pokemon url all right let's go take a look and see if we are deployed all right we're still busy building okay it looks like we've deployed something hit bulbasaur again and we've still got super awesome and crazy awesome now let's go and make our change so i'll go over here to that one.json file and i'll say mucho crazy awesome hit save and i'll hit refresh and no bueno nothing's happened so what we want to do now is run our revalidate and it says revalidate true so cool our api got run let's go and check it out awesome that is really nice so you can imagine what's going to happen here you may have a database or message queue on your back end that's saying oh i've got some data it's changed and then you can basically go and tell your front end oh you need to go and regenerate this page right now on demand and so they've now offered this ability to us in 12.1 this is really really cool so static site generation was really good with next js and it got even better with this minor change to 12.1 so cool so when would i use static site generation well i would use static site generation for the home page or the product detail page in my ecommerce app basically anytime you have data that's not moving all that fast we expect massive volumes of requests or you just don't want to run a server which honestly is you know if you run a server you probably don't want to run the server so it's a really good thing to have this ability to statically generate your site all right well i hope you feel a lot more informed and comfortable with the modes of next js of course all of this code is available to you there's links to it in the description down below if you have any questions or comments be sure to put those in the comment section down below hit that like button if you like the video and hit the subscribe button if you really like the video
Info
Channel: Jack Herrington
Views: 15,903
Rating: undefined out of 5
Keywords: next js, jack herrington next js, blue collar coder, next js ssg, next js ssr, next js ssr ssg, next js 12.1, NextJS 12.1 SSR & SSG, NextJS SSR & SSG, Client-Side Rendering, Client-Side Rendering Explained, Client-Side Rendering Usecases, Server-Side Rendering, next js client side rendering, next js server side rendering, Static-Site Generation, next js static site generation, Server Side Rendering
Id: kdXKz1UWc3E
Channel Id: undefined
Length: 31min 17sec (1877 seconds)
Published: Mon Mar 07 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.