Let's Learn Next.js!
with Scott Moss
Next.js makes building ReactJS apps fast and flexible. In this episode, Scott Moss will teach us what Next can do and what we can build with it!
Resources & Links
Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.
JASON LENGSTORF: Hello, everyone. And, welcome to another episode of Learn With Jason. Today, on the show, we have Scott Moss. Scott, thank you so much for joining us today.
SCOTT MOSS: Yeah. Thank you for having me, Jason. Superglad you reached out. Superpumped to be a part of this. Let's do it.
JASON LENGSTORF: I feel the same way to have you on the show. It's an absolute honor. You are one of the best teachers out there. You have so much material on Frontend Masters. Having the opportunity to learn from a professor educator is always wonderful so I'm superpumped to learn today.
For those of us not familiar with your work, want to give us a little bit of background?
SCOTT MOSS: I do a lot of teaching on Frontend Masters. I'm the CEO of a company called Tipe. It's basically, you know, a CMS that you can use on any app you develop. You still can make your own app, however you want, whether it's a web app, a mobile app, or a server. You can use the CMS through an API for contents. So, that's kind of what we do.
JASON LENGSTORF: Yeah. Yeah. I think that's that's, like, what drives me, too, is I'm always like, "I was going to poke at this anyways, so I might as well show other people what's going on while I'm tinkering."
SCOTT MOSS: Exactly. Something I tell a lot of people is that teaching is a higherlevel, you know, way of learning, right. Teaching, in itself, is such a great way to learn. If you're going to learn something, why not teach it? People are going to benefit, but you're going to benefit greatly by coming up with words to explain it.
JASON LENGSTORF: Absolutely. Yeah. Well, yeah, so, this is going to be a good one, too, because this is something that that I think you've taught a lot about, which is Next. Next.js is all the rage right now. What is Next?
SCOTT MOSS: You know, I'm so proud of Next.js and the folks behind it because, like, I've been using Next.js for awhile. I remember finding it a couple years ago. I'm just like, this framework is so ridiculous. It's so OP. No one knows about it. People, at the time, were still you know, they were not looking for anything beyond React. It was like, React and that's good enough. At the time, like, that was a feature. React's like a Vue reader. That was the feature. But then, like, as React starting developing, people were like, ah, I'm so sick of setting up all this stuff and figuring out if I want a React router. There was framework on top of framework and if you come from the Angular community, it's kind of always like that so you're kind of used to it.
When I saw Next.js, I was like, oh, wow, this is pretty legit, kind of like Gatsby. I thought it was pretty amazing. You can think of Next.js as a bunch of opinions, baked on top of React, right. So, if you ever use Rails before or a CLI tool, like Angular CLI, they were developed by smart people to develop React applications by leveraging conventions inside of a framework. Some are filebased routing or, you know, different things like that. Versus the way you did that before was mainly set that up with creating a router declaratively. This framework, Next.js, alleviates a lot of that for you. Everyone knows there's a million ways to style things in React.
Next.js is that, at its core. It adds tons of other stuff on top of it, right. Like being able to automatically what type of rendering mode you want, for free. I would imagine a lot of people have never tried to set up a serverside rendering with React Vanilla. If you have done that, good for you. But most people haven't. And ReactJS gives you that for free.
JASON LENGSTORF: I remember when I was back at IBM, that was one of the things we were talking about. We kept trying and the experiment would break and we were like, well, let's push that off and we'll deal with it later and we just never got around to it because there were so many caveats and weird, little things that could go wrong and so having that sort of thing handed to you is really, really nice.
SCOTT MOSS: I agree, yeah. I'm trying to figure out how to turn my notifications off on [Indiscernible]. I just updated it last night.
JASON LENGSTORF: Does it let you do the I have to do the alt click on the notification icon, on the topright, and that usually shuts them up. I have yet to really get the hang of notifications in Mac.
SCOTT MOSS: It turned into Siri. (Laughter).
JASON LENGSTORF: I've betrayed you.
What's up! I saw Dom. It's good to see everybody.
Next is a meta framework on top of React. So, we're going to look at kind of what that means. Let's switch over to the pair programming view so we can see my screen here. Make sure you go and follow Scott on Twitter. This is going to be a great feed, a great source of information. We already posted this type link, but I'm going to post it again. Make sure you go check it out. And if you're interested in learning from Scott, there is so much great information here, on Frontend Masters, that you can learn. And these are, like, indepth workshops. That is a subscription that you won't regret. It's great information.
SCOTT MOSS: I go back and look at my own courses sometimes and learn new things. (Laughter).
JASON LENGSTORF: My favorite part of teaching is that I get to have notes that I can find.
I have so many private notes that I'll never seen again. At least on my blob, I'm like, "I know I published this."
We have live captioning, that is being provided by White Coat Captioning. Thank you so much. And that is so that the show can be more accessible to more people. It is available on the home page of learnwithjason.net. We have Netlify, Fauna, Auth0.
And, today, we're talking about Next.js, which is here. Here's the website for it. And, Scott, if I want to get started, what should my first step be with the Next site?
SCOTT MOSS: Most people tell you, "go read the docs." Open up your terminal.
JASON LENGSTORF: I like that.
SCOTT MOSS: Yeah. I just hop right in. I like to hop right in and I let the docs save me. Really, Next.js comes with a really awesome tool called "create Next app." It allows you to create a Next app. You can use NPX and say "NPX create Next app." We can do that. And should be go to go. I think you might have to have, like, at least Node 8, I believe, to actually get this running. Don't quote me on that. You want a later version of Node. You don't want Node 0.12.
JASON LENGSTORF: 0.12. (Laughter).
SCOTT MOSS: You should fix that first, you'll probably have other problems.
JASON LENGSTORF: If you've never used it before, NVM. You can see, I'm on Node, Version 14. If I want to use 12, I can use that to switch. I'm going to keep it on the latest and greatest. Let's do "use 14."
SCOTT MOSS: Nice. You'll have to send me your script for that path there. I really like that path.
JASON LENGSTORF: This is Starship.rs, which is a Rustbased terminal prompt. I love this thing.
SCOTT MOSS: Okay. Yeah, that looks amazing.
JASON LENGSTORF: In my dot files let's see...somewhere in here.
SCOTT MOSS: I thought it was my that stored my dot files
JASON LENGSTORF: You get enough questions about this and then you you're like, well, I should just share this. So, I have my Starship config in here somewhere, in "config," "starship." You can use that, there.
All right. So, I've got a new folder and let me open this up in VS Code so we can see it.
SCOTT MOSS: Boom! Okay. So, when you open this up, you're going to see a couple things here
JASON LENGSTORF: Give me one second. It's being "get ignored." Side effect of my files.
SCOTT MOSS: There we go. All right. So, got a couple things going on here. So, basically the Create Next app is going to have a Hello JS app. We're looking at the package.json here. We have the scripts objects. We have the dev command that does "Next dev." That starts it up in dev mode. It's a fast reload or a fast refresh. So, they have that. That's going to start that up. "Build" is actually going to build and deliver some type of exported version of your app. You'll almost never use that locally unless you want to test the build. Your CI will likely do that for you. The same thing goes for "start," unless you want to test locally. Your CI or whatever hosting provider you're using are going to run those two commands and will be running "dev" for everything.
JASON LENGSTORF: We've only got three dependencies here. React and React DOM, are every React project. Next, so, I'm kind of used to, when I set up a React project, I've got Webpack and Babel. Next is taking all that over for us?
SCOTT MOSS: Everything from the build system, all the way up to actually giving you components you can use inside of your own components. We'll have access to router, link components and all types of things, from this Next package. All of it's handled. After you run this scaffold, you can go straight into writing application code. There is literally nothing else you have to do.
JASON LENGSTORF: So I start this, "yarn dev." And then this is going to open up 3,000. So, let me get over here and we'll start this. So, here we are, at Local Host 3000 and we've got a basic page.
SCOTT MOSS: You got a basic page and there's further learning. We can inspect the page that actually has this stuff. We're inside the "pages" directory. Here's where the conventions kick in. This is special with Next.js. What Next.js does is when it sees the "pages" folder, it's going to take every single file in there, that doesn't have an underscore in it, and it's going to pick a route. The index page of our app, that we're seeing on the left, that's going to be whatever the index.js page is rendering. It looks like regular React. There's really nothing fancy in here, right. It's just regular JSX. It looks like it's using a styles object, which is probably a CSS module. You can change and hit "save" and it'll update.
JASON LENGSTORF: And this is supercool, right? The fact I'm over here let's try something and see what it looks like and as soon as I hit "save," it's live.
SCOTT MOSS: Next.js is a fullstack framework. It actually comes with a server. Even when you deploy it, there's actually a server there, as well. People are having, like, a panic attack back from when did we start doing this? 2014? We built singlepage applications and we served them ourselves. We threw some reverse proxy in front of it and then we wised up and we were like, "well, what if we put this on a CDN?" That's how Netlify came to be. That's not actually what's happening here. Yes, we do have a server, but we as you'll find out, we'll be able to tell Next.js how we want to treat certain pages, what mode we want to render them in and what types of interactions we want.
JASON LENGSTORF: Yeah. Yeah. Cool. So, looking at this, this all is familiar, right. This is React code. And if you're new to React, we just did an episode on this, actually. Let me pull this up. Let's learn React oh, wait! My slug creation doesn't work. It adds extra. So, here's a link to that. This was on Tuesday. Alley was here and taught us how to do the basics of React. If that's new to you, go check out that episode, after this, and all will be revealed.
We have mostly boxstandard HTML here. So, then as I'm looking through here, I see...wow. It looks so approachable, right. There's no magic here.
SCOTT MOSS: There's no magic here. The only thing that looks different is you've got that head tag there. Again, this is where I said the Next package delivers a build system, all the way up to components. This head tag is pretty much like any other tag you could find on NPM. Things like the meta tags, SEL stuff, title, description, you can manipulate on a page basis. You get things like this in Gatsby, as well.
JASON LENGSTORF: What's interesting here, is so Next is actually giving us Next head. If we're using another framework, you know, Gatsby, for example, we're importing React helmet, which is a different dependency. So, this is kind of nice, because now I don't have to go learn that the way that you add a title tag to my React site is that I have to go find a dependency that can do head management. It's all kind of baked in. That, I think, is a really nice touch.
SCOTT MOSS: It's the small things. Next.js is trying to create the complete framework. As you build out an app, you're realize your dependencies are nonexistent. I've been to production with that app. You'd be surprised how far you can go without having to install something when Next.js gives you everything you need, out of the box.
JASON LENGSTORF: Nikki, in the chat, is asking this is serverrendered?
SCOTT MOSS: Yes, so it's perfect for SCL. Right now, what's actually happening, this index page is being rendered on the server, in development mode.
SCOTT MOSS: Next.js is going to do that for every single page, but you do have the option to change that and we'll kind of get into that. That's where I think Next.js kind of shines. You can't go back to anything else, in my opinion.
JASON LENGSTORF: That is really nice. It just takes a lot of guesswork out. One of the things that's always stressful about working on any project is when you're not sure whether or not something's going to do what you expect it to do and you never know which thread you're going to tug at that's going to open a worm hole. You thought you were adding an SEO tab and now you're in the guts of the React rendering?
SCOTT MOSS: Messing with fibers. (Laughter).
JASON LENGSTORF: Um, so that is kind of nice. It's good that, you know, this happy path is handled. This is something everything's going to want to do. If you're building a production app, you have to set a title. You have to provide the social tags. That's how the internet works. This is good thing to see.
So, you mentioned before, if I want to create another page, I just create a new page?
SCOTT MOSS: Name a new file and default export a component there. Put "hello world" and we should be able to route to it, without having to stop the server and start it again.
JASON LENGSTORF: Ooohhh. Interesting.
SCOTT MOSS: Hot reload is awesome. If you ever have to set up a development environment manually, keeping track of State can be stuff when it's reloading modules in the caches. Next.js does it very well.
JASON LENGSTORF: Look at that! I just created this page and here we are. Also, this is something that I think is really interesting. Note that I didn't have to import anything. Now that we're on React 17, we don't have to import React anymore. This is a breath of fresh air.
SCOTT MOSS: It's pretty nasty. (Laughter). Like I don't know. I love Next.js so much. I'm a big advocate of building from, you know, an experience, right. I like to think about a developer's experience, a user's experience and I build backwards from there without trying to sacrifice the experience. Open source tools, they discover awesome technology and they build that out and stamp a really nice experience on top of it and it doesn't really work out that way because you have to make sacrifices. If you start with the experience first which is what I think the Next.js team did it just leads to a greater product.
JASON LENGSTORF: Yeah. Um, so, I noticed something here, which is that this is still getting styles from somewhere, even though I'm not including anything. So, how does that work?
SCOTT MOSS: You can make a page inside the "pages directory" and it'll render it unless it has an underscore in front of it. You can see at the top, it's importing global CSS. Let's talk about this underscore app.js. This is the index of your app. If you're building a React app, it might say "React DOM render." This is the root of your app. Every page is going to be rendered here. If you look at "component," that's actually a page. That's going to be the index page or the "about" page.
JASON LENGSTORF: I can do something like let's say I want to wrap this whole thing and under each one, we'll just say... "powered by boops." Now every page is going to have that. We are on our "About" page here. That's a pretty powerful model that we can now here's our global styles. And then because it's a React app, you could also do something I would guess where I would figure out which page I'm on and conditionally show things, too?
SCOTT MOSS: Absolutely. Depending on what component I'm on, I want to show this layout versus that layout. What a lot of people have done Next.js have a really good example of this in their docs. You'll attach a property, maybe called "layout." And you'll wrap your page to whatever "component.layout" is.
JASON LENGSTORF: That's cool. That's very cool. And so, what do we get in page props?
SCOTT MOSS: Let's talk about the props. This is where I think this is where Next.js really starts to get like, okay, y'all not playing around here. This is nice.
JASON LENGSTORF: So my "about" page is empty.
SCOTT MOSS: Uhhuh.
JASON LENGSTORF: My index page is empty.
SCOTT MOSS: Yep. You pick a page, "index," "about."
JASON LENGSTORF: This one's our proofofconcept.
SCOTT MOSS: We're exporting a component, but we can export functions and this is where it kind of gets magical. One of the functions we want to export is going to be called "get static props." It's going to allow us to get some props that are going to be rendered statically for this page. So, like, what does that actually mean? Well, remember when Jason looked and showed you the view source, that's the static version of this page. We want some props to be available when that page is being staticallygenerated so therefore, we could conditionally show different UI elements.
So that's what "get static props" does. The sweet thing about this function is that it doesn't get bundled in with the browser, it gets eliminated. You could do Node things in there. Things you couldn't do in the browser, you could actually do in the function, for instance, reading the file system.
JASON LENGSTORF: Wait. If I was like, we'll get "FS" and then I'll require" FS." What can we read here? Maybe the package JSON. And we'll read, um, where are we? Have to go up...one more? Package JSON? Yeah. Right. And then I could I could consolelog my package JSON and you're saying that's going to get, like, spit out here?
SCOTT MOSS: Yeah. You'll see you'll probably get an error because it's not returning any props because it doesn't like
JASON LENGSTORF: I have my directories wrong, too.
SCOTT MOSS: It executed the code.
JASON LENGSTORF: That, in and of itself, is really interesting oh, maybe we can make an identity and have it grab itself. Is that going to work? Nah. It doesn't like that. (Laughter).
SCOTT MOSS: It's executing the code. The error message is from the file system. And it's pretty impressive. You would think you would have to encapsulate all of the code inside of this function, you can import the file module at the top and it's still going to work.
JASON LENGSTORF: So, let's do something that won't break. I'll import "path" from "path." Down here, let's consolelog we'll do "path.join" of "test directory file.js." And then this should there it is!
SCOTT MOSS: There it is! Boom!
JASON LENGSTORF: Wow! I could return this. It's telling us we didn't return an object. Let's assume I was going to I don't know. Let's say this was somehow useful. We'll call it "file path." And then I'm going to store that path.
SCOTT MOSS: Right. So, the next thing we want to do it's complaining because we need to return an object with the "props" property on it. Whatever that "props" property is, is an object and that is passed into this page.
JASON LENGSTORF: Up here, I'm going to have access to that?
SCOTT MOSS: You can destructure.
JASON LENGSTORF: Here's our "page" props. Now I can do this and we'll get we'll just make it a div, so we can put whatever inside it. And I'm going to do let's do a "P" and we'll drop a file path. Boom! There it is. That's pretty slick. That's really cool, because being able to do Node stuff, that means that I could do something like I could send off a query to my database. Because this gets compiled away, it won't make that when the page loads, it will have already been done on the server.
SCOTT MOSS: You completely bypass the API layer and talk directly to the database. So, you can imagine importing your ORM, where you're interacting with the database directly without having to go outside to the internet, come back around to your own API and get a result. You just go straight to the database.
JASON LENGSTORF: And so, this also will work, um so, Next has an export mode, right? Like you mentioned we can deploy to Netlify or CDN targets. Does this work with that?
SCOTT MOSS: Yeah. This definitely works with that. In the case here, where we have "getstatic.props," this is all static. Yes, this totally works with it because the way that [no audio].
JASON LENGSTORF: Uhoh. Scott has frozen. Um...can you all see me oh, wait, Scott, you're back.
SCOTT MOSS: Sorry about that.
JASON LENGSTORF: You said "if we were doing an export" and then we lost you.
SCOTT MOSS: The way Next.js handles exports, it'll go through all the pages. It'll look for all the functions and execute that function at build time. In the case of "getstaticprops," it doesn't matter what mode, it's always going to run at that time that it's building.
JASON LENGSTORF: Very, very cool. And so, now, I saw a question earlier, from, I think, Bendi, about this app file. So, if I wanted to have different layouts, can I create, like, an underscore layout, too, or something? Or you have to do that logic in app.js.
SCOTT MOSS: It would most likely make a route called "underscore layout." I make another folder, sibling to pages, called "layouts." And the pages, themselves, know what layout they need to be wrapped around, either by explicitly wrapping that layer out. You can use the props inside of "apps.js."
JASON LENGSTORF: Another thing to point out, too, to everyone who's watching, this layout, all it does other than the stuff I've added for proofofconcept, these styles would be your globals, but you could do something, if you have a layout like Scott just said where we'd get "about layout" from "layouts."
SCOTT MOSS: Exactly. Yeah.
JASON LENGSTORF: And down here, we'd just wrap it. Now you have full control over your layouts. You're not like, "where the heck did that extra stuff some from?"
SCOTT MOSS: They're pretty explicit. When you're building a site if you're building a Next.js app that is rendering it's responsible for your entire stack, your marketing site, documentation and responsible for the signinexpensive, having that app is really great because those are, like, three different scenarios that might have three different build modes and three different designs.
JASON LENGSTORF: People get excited about abstractions and they want to put everything in the abstraction. This app.js is an abstraction. If we cram everything into it, it becomes a source of confusion. I do like that idea of kind of being more more deliberate about it. If this is a page and we want a page layout, just import the page layout and wrap it. That's going to be more understandable.
SCOTT MOSS: I keep the app.js light. CSS resets, different things like that. I normally try to keep it as light as possible. If you have providers, if you're using components to have providers, that's a good place to do it, as well. Then again, maybe you don't want all pages to have access to that provider. So, it really depends.
JASON LENGSTORF: Depending on how big your app is, right? The advice you always hear is put everything as low in the tree as you can. You don't want everything to be global, that's a recipe for sadness. If you've got a blog, sure, put it in the app or whatever. Yeah, okay. So, I like this. I think this is a really nice workflow. We've got this "getstaticprops" flow. This one, I just wrote something and it showed up here. So, if we wanted to determine something about our pages, just by, um, by setting them up here, then we could do something like the page props, here, that's that's available. So, we could do "pageprops.layout" and make a choice.
SCOTT MOSS: Yep. 100%. And I've done that before. That's a pretty good way.
So the next thing I want to dive into right now, we've been talking about staticallynamed route. We have a name called "about," "index." We can have parameters. Let's make a new folder and call it "blog" or "docs." And then inside of here, if you think about a blog, there's usually an index page for the blog where all the blogs are listed and then there's a page for an individual blog. So, if we wanted to make an index page for the blog, we would put "index.js" and the route will be "/blog."
JASON LENGSTORF: We'll start with nothing. We'll make it as simple as possible. We'll call it "blog." And dump all of our information out. It's just a regular, old function.
SCOTT MOSS: Regular blog. Best blog out there.
JASON LENGSTORF: If I want to write a blog post, it's not really practical for me to reprogram my layout for each blog.
SCOTT MOSS: Right.
JASON LENGSTORF: I want to write the content, I don't necessarily want to have to put the title in an H1.
SCOTT MOSS: Yeah, you don't want to do that. We can make another page here and we can say you basically use the array brackets, you can put any name. You might put "title," "slug." And then the file extension. So, you know, "slug.js." And that's going to give you a dynamic route and basically this route is, hey, we don't really know the value of slug because it's dynamic, therefore, Next.js is going to require you to tell it, um, what those parameters are. This is where we get into more advanced pagebuilding. If you've ever done any type of static generation, even Gatsby, there's ways to think about generating pages ahead of time. If you can grab it, you should know all the slugs. You should be able to tell the framework, here are all the slugs I want you to generate ahead of time. If someone navigates to one that's not, here's a 404.
We know about "getstaticprops." There's another one, and that's going to be I'm drawing a blank right now.
JASON LENGSTORF: Is it paths?
SCOTT MOSS: "Getstaticpaths." Thanks, Jason. So, "getstaticpaths," doesn't return props, it returns paths. It is an object with paths that's going to be an array of object and each object, in there, is going to have a property on it called "params." It might be singular, but we'll find out. And that's in this case, it's going to be the value of the parameters we want to render. We have a parameter called "slug." We put "slug." And then we put a value here. It could be anything. If we had tons of objects in here, we're telling Next.js, if we have three objects in the paths array, we want to render three pages and each one of them have this slug...
JASON LENGSTORF: Like this?
SCOTT MOSS: Yes. Exactly.
JASON LENGSTORF: So, we've got our first three blog posts and then what how does this like, this is going to create three pages?
SCOTT MOSS: So halfway there. So, what this is going to do, this is going to register to Next.js that these are valid routes. Please do not 404 when you see these slugs come in. These are valid. But now we actually still need to probably actually supply some content for this page, based off the slug. So, this is where "getstaticprops" comes back in. We'll make it on this page, as well. And the difference now, with "getstaticprops," there's going to be an argument with a context object. On the params, we're going to get the slug property, which is the value of whatever the person just routed to.
JASON LENGSTORF: Okay. Theoretically, I can do something like this. If I return my props object, for now, I guess we could just say
SCOTT MOSS: Yes.
JASON LENGSTORF: Let's say we're H1, viewing...or, we don't need a I know how React works. Okay. (Laughter). So, reviewing a slug. And that means we would destructure that out of our props here. And so to track this, to make sure I'm understanding it, what we're doing is when we start Next, it is going to run "getstaticpaths." It is going to provide this this array of objects with a slug and then Next is going to say "these are the pages that are going to be rendered." So, "blog/my blog." Then it will run and get this slug we passed in, but the one individually for it. So, like the first time it runs, it'll run and get my first blog and then runs again with the next one and again, with the next one. At which point, we pass in this prop and render a page which will display that prop.
SCOTT MOSS: Absolutely. If you try to navigate to a slug that isn't there, it'll break. You have to supply a property inside of "getstaticpaths" called "fallback." Underneath, where you have "paths," you have to add a property called "fallback." It's a false for now. You're telling Next.js, um, hey, if someone tries to navigate to a slug that I didn't tell you about, fallback false means 404. They're going to handle 404. We don't want them to see anything. There's two other values. One is "fallback true," which is really awesome. If someone navigates to a slug I didn't tell you about, that's okay. Don't 404. Go to "getstaticprops" and pass that in anyway. And the reason why that's amazing is because if you deployed on a compatible platform, like Netlify, what's going to happen is when someone navigates to a page that you did not previously render ahead of time, that person is going to render it and it's going to be cache for everyone else. It like an ondemand prerendering. Let's say you had, I don't know, 100,000 blog posts and it was on a CMS somewhere that had the slowest server in the world and build time was over three hours. Instead of prerendering 100,000 blog posts, you could prerender one blog post. When they click that link, Next.js is going to yeah, Next.js is going to render it when they click it and then it's cached.
JASON LENGSTORF: That's superslick. And it's interesting, too, because this starts to hint to a way of how to crack that problem of having our cake and eating it, too. We want to prerender because it's more stable. We're going avoid all these issues with setting up our custom caches.
SCOTT MOSS: Exactly.
JASON LENGSTORF: This lets us have the
SCOTT MOSS: Go ahead?
JASON LENGSTORF: This lets us have it.
SCOTT MOSS: It's I've been trying to describe it. I try to describe it as everything is eventually static, right? It doesn't matter how you build your app with Next.js, it's eventually static. When it gets to the browser, it's going to be static. It doesn't matter what you do with it, it's going to be static. Whereas before, it's either static or it's not static. Pick which one you want. Now it's like, everything's static. It depends on what you want to do after it loads up and that's the different mode there. Everything is pretty much going to be static here.
JASON LENGSTORF: Yeah. Yeah. Oh, man, this is so cool!
SCOTT MOSS: Having "fallback true," inside of your page our example's pretty trivial. We're returning something and "getstaticprops."
JASON LENGSTORF: I have an idea. Let's use the Rick and Morty API.
SCOTT MOSS: I had someone convert me to the character so I'm all about it.
JASON LENGSTORF: You can look up characters by number. Right. And so if I look up Character 1, we will get back Rick Sanchez. Let's do this, I'm going to change my slugs to numbers.
SCOTT MOSS: Nice. I see what you're doing.
JASON LENGSTORF: This will let us actually do something. When I go to Static Props can I make this in sync?
SCOTT MOSS: Yes. I believe Next.js loads for your globally, I think you can call "fetch."
JASON LENGSTORF: I'm going to do a call to the API and then we will get the response your helpfulness isn't helping right now, VS Code. I love it when it's being helpful and then sometimes it's like, really, I want you to read this and I'm like, dude, chill! Give me a little breathing room here. (Laughter). Then if I put in "data," I should be able to say, let's say, "name" in here. We'll get the name and the image and then down here, I'm just going to do we'll do a source of image and an alt of name.
SCOTT MOSS: It'll be data. Either you got to spread them out
JASON LENGSTORF: Oh, you're right. You're right. I'm going to spread data in here and that will give us all of these, at the top. If I come where's my did I, like, lose my page here? Local host.
SCOTT MOSS: It's gone.
JASON LENGSTORF: 3000. Blog 1. Broke it. Required parameter was not provided in a string at "getstaticpath" for slug.
SCOTT MOSS: Parameter slug was not provided.
JASON LENGSTORF: It's got to be a string.
SCOTT MOSS: Very specific. Very specific.
JASON LENGSTORF: I'm not mad at it. I prefer specificity. Now, we've got Rick. If I go to let me make this a little bit bigger, so we can see. I'm going to go to 2. Okay. That makes sense. Let's go to 3. Let's try one we didn't register. Let me try, I don't know, 10. Okay.
SCOTT MOSS: You saw that loading? That popin there? That's due it worked out well for your example because we're not really doing anything that would actually cause an error inside of our page. We're not doing any nested property lookups. So everything's good there. But if you were doing, like, let me get this character.origin.name, it would break because at the time of the page rendering, the data wasn't there and that's because of how "fallback" works. It renders the page, first, with no props and renders it again when the props come.
JASON LENGSTORF: I'm going to assume there aren't 99,000 characters on Rick and Morty, so now it's broken. We don't have a character.
SCOTT MOSS: The way you get around that is, you can actually import the "use router hook" from Next Router and there is an "is fallback boolean on there?" On your page I think it's "next/router." And then inside of here, you can say, "const router equals use router." On the router object there's a "router.isfallback." That's just a boolean. If fallback is true, it means it's loading. Maybe you want to show a loading spinner. Maybe you want to show something else and then it's going to render it again.
JASON LENGSTORF: If we're in the fallback, it's going to say "loading." It shows it's loading and says it's broken. Let's see what 30 is...loading. And then it shows that was not the right character. (Laughter). Good. Good. Randomness strikes again. (Laughter).
SCOTT MOSS: That's my son's favorite character. (Laughter).
JASON LENGSTORF: Moment of silence for that one.
SCOTT MOSS: Yeah. Oh, man. But, uh, yeah, so that's how fallback works. But, you know, some people don't want that loading they don't want you know
JASON LENGSTORF: So, that's exciting. (Laughter).
SCOTT MOSS: So, um, what they'll do is they'll change fallback from true to being a string and they'll put "blocking." And that's actually something new to Next.js. This means, hey, block the initial rendering until "getstaticprops" renders.
JASON LENGSTORF: Let's going to six then. It doesn't show anything until okay. All right. Very cool.
SCOTT MOSS: That's another way to do that. I think it really depends on how fast your APIs are. If you can get fast enough. You don't want them looking at a white screen. It really just depends on how you want to do it. But they give you that option, which is really cool.
JASON LENGSTORF: Between the options we have, we can say "don't do anything until it's time." That's the recommendations from perf experts. It's 500 milliseconds, it feels slower. If your API's that fast, just block and show it immediately. You can use fallback to show your skeleton component or loading spinner and in cases where you know, like an interesting kind of approach I can see, here, is if you know what your top pages are, like, if you use your Google Analytics data and you know these are the 15 posts that get the most traffic on your blog, render those first. You get a supperfast build and a superfast performance to improve both the developer experience and the user experience. I really love that.
SCOTT MOSS: That's a really good idea. I helped a big company do the exact same thing, inside of their pages. They were trying to figure out a strategy on what pages to render. I was like, well, what's the hottest pages on your Analytics? We made a call to the Analytics to get the top pages and we rendered those. It was a beautiful strategy. Very good idea.
JASON LENGSTORF: Okay. All right. I'm pretty excited here. I feel like we've got a lot of potential. We've covered, so far, the filebased routing, so, just creating a page. We've got dynamic routing, where we're able to create a parameterized page that can do the "getstaticpaths." We haven't looked at this folder, though. What's up with the API?
SCOTT MOSS: It works pretty similar to how the "pages" would work. In the "pages directory." The API directory is exactly what it sounds like. It's going to create an API for you at the route or whatever the name of the file is. We're at "API.hello.js." That is going to be "/API/hello." So that means you can do a "get request, a "hello." And it's going to run this. It's a serverless function.
JASON LENGSTORF: Nice. So, if I just visit this I'll just go to what was it? "API/hello." I'm using Firefox. This is what's actually coming back. And, so I just switched to Firefox because Chrome was getting so it would beachball because it was using so much memory and I'm noticing all these nice, little things that Firefox does, like formatting data
SCOTT MOSS: Without a Chrome extension, yeah.
JASON LENGSTORF: That is really, really cool.
SCOTT MOSS: Yeah. It's pretty powerful. It really just depends on your experience with serverless. Because me, personally, I wouldn't say serverless is I wouldn't say it's like a oneforone replacement for, like, having an actual, traditional API. For me, it really comes down to, what are you trying to do? If you are doing anything, like, a task that's it's going to be it has to be extended, anything that's polling, serverless is not built for that. It even really depends on your database. Some live on a longlived connection. Serverless is the opposite. It spins up and it shuts down. It doesn't want to keep track of anything. You have to make good technology changes. Most popular database and frameworks have some type of serverless counterpart or a tutorial to help you get there.
Instead of me having to tell my team, like, oh, if you want to use this data, you have to copy this util to your endpoint. I'm suddenly a backend engineer because I built an API for my team, but really, I only had to write some logic.
SCOTT MOSS: I think it's funny that, like, we've all worked on different projects, in our own ecosystems, but everyone has a utils folder. (Laughter). It's always the same name, "utils." That's funny.
JASON LENGSTORF: There's a question, from Brandon, about the API routes. I think this one might be for me because it's about hosting on Netlify. So, Netlify just to do a quick shoutout and, you know, full disclosure, I work for Netlify, so this is me doing my job. (Laughter). We have a plugin for Next. It is designed to make everything work. This is ran by Lindsay. You can deploy to Netlify and the API routes and getstaticpaths, it'll work. It's a really nice experience and Lindsay's done a ton of work on that, so props to her.
SCOTT MOSS: I actually tried it out. I went through Netlify and [Indiscernible] to do comparison to see if anything was missing. It actually is pretty good. Netlify hooked me up, a couple weeks ago, with an account. I was blown away because it works pretty well. I was I was shocked. I honestly didn't think Netlify was going to be able to pull it off with their infrastructure, but they did and it was pretty amazing.
JASON LENGSTORF: It's been an interesting changing. Why does Netlify exist? Because we want to remove the complexity and the eventual pitfalls. Depending on how you host Next, we were like, okay, how can we bridge this gap? How can we make sure we don't lose that functionality, but that we also don't create those pitfalls and those potential downsides of standing up a server again. It's been a really interesting exercise. I think we'll there's a ton of content about it. Cassidy writes about it, all the time, on the Netlify blog and on Dev 2. If you are interested in learning more, that's a whole conversation for another time.
For now, let's get back to Next, itself, and talk about what should we talk about next? What else have we not looked at, or what other features you want to dig into? Chat, what do you want to see?
SCOTT MOSS: Yes. One thing I want to throw in, real quick, was we didn't we've been talking about pages, but what about regular components? There are no conventions in Next.js. Typically what I see is you make a "components" folder and Next.js won't do anything magical or special to them. You can import to other components. The only difference between the components is that if you need to load up some like, for instance, if one of your components is using another NPM component and it has CSS, in previous versions of Next.js, you were not able to import that NPM's modules CSS, here, you had to do it globally. If you have a dropdown that was only rendered on one page, you'd have to render it globally and that was not fun.
So, now you can actually import CSS for other NPM packages, inside of "components" and "pages" and things like that. It makes things a lot better. You can do CSS modules for the styling of your CSS, as well, inside of Components.
JASON LENGSTORF: CSS modules, I feel like I'm starting to think I should talk to somebody, specifically, about CSS in JS. There are hundreds of ways to do it and they all have tradeoffs. Every time we talk about it, it's like, we're going to lose the entire episode.
SCOTT MOSS: My opinion of CSS and JS, it works and feels like [Indiscernible]. Being able to basically add styles that tap into a theming system that you have built somewhere else and you can add them a la Carte. They're just there. They're typechecked. They just work. That's literally been the best experience for me. And you don't have to worry about them colliding because they're scoped. That's kind of what I've been doing.
JASON LENGSTORF: Nice.
SCOTT MOSS: So, we talked about the components. Do we have anything in chat? Let's see, TypeScript.
JASON LENGSTORF: TypeScript and Image are the ones that got asked.
SCOTT MOSS: The good news about TypeScript is, Next.js does it for you for free. You don't have to do anything. In fact, I'm trying to think, what's the most minimum thing you have to do to have it recognize? I think the most minimum you have to do ask make a TS config and restart the build.
JASON LENGSTORF: Dang. That's slick. Okay. So, this is going to be fun because I so, I create a TS config. Does this need to be a.js?
SCOTT MOSS: Yes. I think it's tsconfig.js. Restart the build.
JASON LENGSTORF: All right. I'm stopping. Restarting...okay. It says it's compiled.
SCOTT MOSS: Oh, okay. Maybe that wasn't it. Hold on. I might have
JASON LENGSTORF: Do I have to make something into a.ts file?
SCOTT MOSS: I don't want to give the magic away. Oh, I'm sorry. It's "tsconfig.json.
JASON LENGSTORF: Now install TypeScript.
SCOTT MOSS: We'll set it up for you.
JASON LENGSTORF: All right. Here we go. Doing it.
SCOTT MOSS: It's pretty magical and once you have this, I mean, all you really got to do, from there, is just, you know, change your extensions to whatever you want. Running the build, again, should hook us up.
JASON LENGSTORF: All right. I'm running it...
SCOTT MOSS: Nice! So, right there. Detected that you have a "ts config." It populated it for you because it's a conventionbased framework so it knows what everything. You're ready to start making TSX files, if you want to.
JASON LENGSTORF: If I come in here not this one, maybe the component, instead, because it's much, much smaller. If I rename this one to ".TSX," do you have to prefix like this?
SCOTT MOSS: I think renaming a file might inherit a rebuild. Switching from JS to JSX might confuse it.
JASON LENGSTORF: Let's go to the home page. It is smart enough to figure that out and it's got my footer in that. That, actually, kind of blows me away that we were able to rename files and nothing exploded. And so then, in here, I have access to my types, which are honestly so, what to I do? I do, like, a component?
SCOTT MOSS: For the functional ones, it would be "FC" from React.
JASON LENGSTORF: Is this right?
SCOTT MOSS: Wrap it in a bracket. Wrap "FC" in a bracket.
JASON LENGSTORF: Element is not assignable to type "FC."
SCOTT MOSS: FC takes a generic, so you have to pass in, like, those lessthan/greaterthan brackets you can put an empty object because you don't have any props. Yeah. So, what is it saying now?
JASON LENGSTORF: I think it wants me to call it an element. Element provides no match for the signature props.
SCOTT MOSS: In TypeScript, what we're doing, we're declaring the return value by putting the FC there. I don't do the functional declaration. I'll do an arrow function.
JASON LENGSTORF: Oh, I got you. I got you.
SCOTT MOSS: "Const footer equals." I think you have to do it with Next.js anyway. Very much like this, for I want to say optimizing their fast reload. I think you'll have bugs if you don't do it this way.
JASON LENGSTORF: Okay.
SCOTT MOSS: Sometimes it'll throw a warning saying, "hey, you need to name your component." You'll do FC right here and the "less than/greater than." And set that equal to the component below. Take that function, right there...oh, just take the entire function, the value everything after "default." Set that equal to on the right side of Line 3. So, get rid of that semicolon and say "equals," that function. And then export.
JASON LENGSTORF: Oh, I got it. I got it. I understand. Actually, this might be the first React TypeScript I've ever written. This is cool, though. Now, if I were to, let's say, we want to add a date, then that would be we can call it we'll call it a string, for easy math, and then we'll do, like, one of these and say, you know, "copyright." Whoops. "Copyright" and then we'll do "date."
SCOTT MOSS: You assigned a date to the type and then you got to import it. There you go.
JASON LENGSTORF: Okay. And then if I go back to my app, is it going to tell me that I'm wrong?
SCOTT MOSS: This file's not TypeScript, so it's not going to show you.
JASON LENGSTORF: But I can do what is it? It's TS Check? Oh, okay. So, it's yelling at me about that. Okay. Whatever. Then, it says "property date is missing inside." There we go!
SCOTT MOSS: Gotta love TypeScript.
JASON LENGSTORF: Now that it's been renamed, it's not liking it so we can restart and it'll fix it. That's what we expected to happen. Yeah. Here we go! That's pretty slick. I'm I'm kind of blown away, here, at how straightforward this actually is. That's pleasant.
SCOTT MOSS: It's pretty nice. I think the other question was, we talked about images. So, Next.js just released a package called "Next Image," is a component that optimizes image. It pretty much has the same API as the image tag. What's unique about it, it tries to you can configure it to map to certain wellknown image providers, like ImageX or Cloudinary. It'll map to the parameters of that CDN and allow you to resize and recrop. A lot of stuff, you can kind of do on your own. It's just their story for images. There's not much to show about it. There's nothing visual to see about it.
JASON LENGSTORF: Can we convert this one over and look at the difference here? Let's go to Blog 1 and then let's inspect source. I can once it loads...what have I done?
SCOTT MOSS: I think we might have killed it somehow.
JASON LENGSTORF: Here it goes. I think I might have just hit this API at a weak moment. Here, we've got the image. It's got a source and it's got an alt. That's exactly what we wrote. If we convert this over Next Image, what do we do?
Scott Moss: Import from Next Image.
JASON LENGSTORF: Right. That needs to be quoted.
SCOTT MOSS: Wherever the image tag is being used, we're going to replace it with "image. "By default, I think that might work.
JASON LENGSTORF: Let's see what happens. Must use width and height or layout fill.
SCOTT MOSS: We can put "layout fill."
JASON LENGSTORF: Okay. It's not configured under images in your next config. Oh, do I need to make it local or something?
SCOTT MOSS: Right. When you pull it down from a CDN, this is where you get into Next.js's plugin system and the way you do it is on your root, you make a "nextconfig.js." So, what you do inside of here, in the Next.js Config, you basically want to export an object. You can say "module.exports." This is going to run natively in Node. So, "module.exports." Then you have "domains." And add the actual the domains of the things that you're going to be serving.
JASON LENGSTORF: Like that?
SCOTT MOSS: Yep. That will approve any images, from this domain, to be rendered
JASON LENGSTORF: Do I have to stop and restart?
SCOTT MOSS: Yeah. It tells you right there, hey, you changed your config, you have to stop and start.
JASON LENGSTORF: Read the error message. (Laughter). Okay. So, this fill is not what we want, so let's make up a width and height on it to get what we want. I'm going to do a width of 300 and a height of 300...and now it's pretty much back to where we are. And so under the hood, then, what changed?
SCOTT MOSS: Under the hood, I don't think too much is going to change, other than the fact that it's going to try to optimize how it's rendered. It's doing an async loading. Then it does a bunch of CSS to actually position it, based on the width that you gave it.
JASON LENGSTORF: Oh, and you know, here's something that's kind of interesting to look at. Let me slow down the browser a little bit and I'll throttle this to, let's say, good 3G. When I load...oh, 3G.
SCOTT MOSS: How did we ever use 3G. It was too fast. (Laughter).
JASON LENGSTORF: Watch the content down here...when it pops in, eventually. Did you see how that for that split second, when the image wasn't there, this was still where it was supposed to be? That's a big deal.
SCOTT MOSS: It doesn't jump.
JASON LENGSTORF: Yes. And that's actually something that'll happen when you go into into, like, your performance testing, if you're looking at your Lighthouse scores. The content shift I think it's called "cumulative layout shift." Your performance score is going to suffer every time it jumps. The worst experience in the world is when you go to one of those websites covered in ads and whenever you scroll, the content jumps around the page. Google is using that as part of its scoring, which presumably means it's using it as part of its ranking algorithm.
SCOTT MOSS: By changing elements, you're causing a reflow. If putting an image on a page causes everything beneath it to shift and what you have WebGL, animations, a big table, that has to shift and it's really expensive on the browser.
JASON LENGSTORF: Brittany is asking if this is happening because of the width and height. It's happening because of the width and height, but because it's actually creating, like this is a transparent SVG. It is creating a placeholder image and it puts this image in the same position as it. And that's what this, um, this position absolute and everything is doing. So, effectively, what you're doing when you use Next Image, it's creating two images. One is, I'm going to occupy this space, even if the image isn't there. I don't know what layout fill does. Let's turn it back on and look at the source.
SCOTT MOSS: It looks like it's trying its best to try to fill the entire space of the container.
JASON LENGSTORF: Yeah. So, we get a display block. Goes to position absolute. This is kind of chaos, isn't it?
(Laughter). Um, I don't know why it does that, actually.
SCOTT MOSS: I can read it here. So...let's see...I think it comes down to so, there's an extra option you can pass in the Next Config JS and Layout Fill makes sure your image is filling the layout of the device size, which is perfect for things like, I don't go, full background images, header images. And you want it to match the size of the the view port that you specified in the config.
JASON LENGSTORF: Got it. Okay. What I had expected was going to happen is that this was going to do the responsive, it figures out the aspect ratio and moves to full width. This is different than that. This is it's occupying the view port, which is why we're getting this squish.
Also, it's overlaying the content. I think if you're going to use Layout Fill, there's extra work to make that contained because we'd have to do something like I don't know. Inline style. Position Relative and
SCOTT MOSS: There's also a "Layout Responsive."
JASON LENGSTORF: Let's do that before I start handcoding things. Let's see what "Responsive" does.
SCOTT MOSS: I think you still have to add the width and height.
JASON LENGSTORF: And that's how we get the aspect ratio. I get it. Height is 300. So, this is what I expected to happen. So, let's go back to the network. I have it disabled. I've disabled the cache. That was a good suggestion, chat. Let me start reloading. And...here it comes. 3G. And I didn't see this content bounce. It was it would have been up here, but it didn't bounce, so that is actually exactly what we were hoping to see.
So, with responsive and a width and a height, it's going to cover the full view port, which I was hoping to happen, so this was the property I was looking for. And under the hood, what happens? It is doing let's see, it's got an alt. It's got sizes and it's got a source set. Oh, yeah. So, this is what we're interested in. So, check this out. It's not just doing, like, um, an image tag. Now it's doing a bunch of work. It's setting sizes and source set. This is the part that's interesting. It's sending this to some kind of a processor, like a serverless. It's actually doing work.
This is this is powerful stuff. So, now it's got different resolutions.
SCOTT MOSS: This couldn't happen if it wasn't a fullstack framework.
JASON LENGSTORF: This is slick. This is really slick.
SCOTT MOSS: When you add different domains, you can configure how the next image components interact. You can map them to the parameters on this URL.
JASON LENGSTORF: That's superslick. All right. So, this is amazing. Um, and with that, I think we're just about at time. If you've got any lastsecond questions, chat, get them in now.
Scott, where should someone go if they want to keep going down this path?
SCOTT MOSS: There's so many resources. The documentation is pretty nice. They gamified their documentation where you can go through it and earn points and they quiz you on it so it's a pretty good resource.
If you're looking for something more guided, handson, I do have an Intro to JS course on Masters and I followup with a Next.js in Production course and it builds on to a bunch of amazing things, like how to use previews and revalidation and other things we didn't talk about today, like serverside props. You can check that one. I think they're still editing it and it should be published pretty soon, if it isn't there already.
There's also honestly, if you watch the Next.js conferences and look at some of the talks, there's some really good material there. I learned a lot of stuff there, like what's coming next, no pun intended. The creators, how they're thinking about their framework. Those are pretty much the resources that I follow.
JASON LENGSTORF: I think there's a playlist that has all of those videos on it. Is this it? No.
SCOTT MOSS: That was something else. (Laughter).
JASON LENGSTORF: Um, that's a different conference.
Okay. If somebody finds this and has a link I see, Cassidy. If you know the list, that these videos are on, um, I know that you were just looking at this a little bit ago. I can put those in the resources for this for this episode.
And, with that, let's also remember, go follow Scott on Twitter for more information. And, you know, I'm not saying this because we're pandering, I'm saying this because we're true. Go watch these Frontend Masters courses. They're outstanding. The content is very good, all around so we're going to get a lot of great information there.
I think, from there, let's do one more shoutout to the sponsors. Remember, we've had live captioning going all episode, that is through White Coat Captioning, thank you very much for that. The captioning is made possible by Netlify, Auth0, Fauna.
Scott, I am I had so much fun today. I learned so much today. Thank you so much for being here. Any parting words for the chat?
SCOTT MOSS: I saw a couple minutes ago someone asked me what switches I was using for my keyboard. I'm a keyboard enthusiast. I build keyboards, so I actually built this one from scratch. The switches I have from this one is from Zeal PC. They're linear. They're very smooth. I didn't have to actually lube them or anything. They work very well out of the box. So, check them out.
Only thing I have to say, uh, if you're going to use Next.js, if you're going to use Gatsby, I highlyrecommend using some type of content management system. It really doesn't matter which one you use. There's tons of them out there. They all cater to your different needs. But if you look at the features that these frameworks have, they're enabling you to actually use a CMS. We looked at getstaticprops. That's perfect to be able to fetch content from CMS. So, you I'm really trying to get to the point where the community no longer hardcodes content, ever again. Just like, you would never hardcode users' data. You couldn't recreate Twitter. You have to make an API call. Content should be the same way. Content is users' data, the users and the people on your team. Don't hardcode it.
JASON LENGSTORF: Yeah. And if you're looking for a suggestion, remember, Scott runs Tipe.
SCOTT MOSS: Yeah. Check out Tipe. We're going to be releasing, out of private beta, in the next week or so.
JASON LENGSTORF: Ooohhhhh, okay. Maybe we got to come back and do another episode on that. (Laughter).
SCOTT MOSS: We partnered closely with Next.js and [Indiscernible].
JASON LENGSTORF: Really, really looking forward to that. Chat, make sure you check out the schedule because we've got so much good stuff coming up. Next week, Ben is teaching us Vue's Composition API. Sarah is going to talk about how she's looking for people to hire and what stands out for her and what she's aiming for when she's putting job offers out there and what you can do to help yourself stand out in the field. This is more of a Q&A. It'll be useful in the replay, but you'll get the most out of it live.
We're going to get into building your own Babel plugin. We've got so much amazing stuff coming up.
If you click this button, it's going to show up on your Google Calendar. You can follow on Twitch.
I think that's it for us, this week.
Scott, thank you so much for taking the time to teach us Next today.
Chat, thank you so much for hanging out. Staytuned. We're going to find somebody else to raid.
Until next time...
SCOTT MOSS: Thanks, everybody.