Intermediate Next.js

Suspense & Errors

Scott Moss

Scott Moss

Superfilter AI
Intermediate Next.js

Check out a free preview of the full Intermediate Next.js course

The "Suspense & Errors" Lesson is part of the full, Intermediate Next.js course featured in this preview video. Here's what you'd learn in this lesson:

Scott creates loading spinners and handles page-specific errors. A loading spinner or any other UI element can be displayed by adding a loading.tsx file to the route. The same pattern can be used to handle errors with a errors.tsx file. The current code can be found on the "step/3" branch.


Transcript from the "Suspense & Errors" Lesson

>> Scott Moss: This one's pretty cool. So, suspense loading states, if you don't know what suspense is, it's basically, it allows your component to wait until some data comes back before you render something. It's the best way I can describe it. And then you can show like a fallback while it's waiting.

So perfect place for loading indicator, that's suspense. What's actually happening is that components being streamed down, chunk by chunk. So, that way you're not blocking a whole page while something is loading. So, that's suspense, we're gonna get that for free by doing one thing. The other thing is going to be the error handling, so, react introduces this thing called an error boundary, which is like a try catch for a component tree.

So if you can wrap a component tree inside of error boundary, it'll try catch that and show a certain page when the error bubbles up to it. Okay, we get that for free too, by just making a file, so we'll be doing both of those and we'll be able to see in more detail how the caching works as well.

So, what we're gonna do is we're just gonna make some loading files. So all you really have to do is everywhere you have a page if you add a loading file next to it, that will show while that page is waiting for its data to resolve. You can also put an error file next to that page and that will show If an error was thrown while that page was trying to fetch data.

So let's do that, the only caveat here is that the error file must be a client component because the error gets caught during runtime and the error boundaries happen at runtime. And also you can do things like on click and you can reset them back to a previous state and things like that.

The server, the, I'm sorry, the loading component can be server or client doesn't really matter. But the error one has to be client, you'll get an error if you don't. So let's do that, so I'm gonna go right down the route of dashboard, and I'm gonna make a loading.tsx for the homepage which the bottom right on the grid, so loading.tsx I'm gonna say home loader.

>> Scott Moss: And for now I'm just gonna pass in
>> Scott Moss: Something like that. Actually the component library that we have has some really good loaders. You know what? Let's just leverage one of those, why am I being lazy? They have a spinner, this is not even the best one.

The best one is the skeleton, but I don't feel like making that. So, all this spinner, I think, because this is a server component, you have to import directly from the component like that. So, I have to import directly from spinner and not the slash react, which will import some client side stuff, which might throw an error in the server side component.

So I'll do a spinner here, I'm gonna copy this.
>> Scott Moss: I'm gonna go into our RSVPs folder, make a loading.tsx. Do the same thing, just change the name from home to RSVPs.
>> Scott Moss: Going to my events, do the same thing, loading.tsx, paste that, change this from home to events.

Now we got some loaders.
>> Scott Moss: So if I go back
>> Scott Moss: And I refresh, now you can see the caching, so I'm just doing a regular refresh. Look how quick those things come in, you barely see the loaders, okay? Barely see the loaders, I'll do a hard refresh and you can see this is what it looks like without caching.

So, without caching, with caching.
>> Scott Moss: All right, and also just notice how, because these are all their own pages, they come in at their own time. And because we're using the loading file, which is suspense, they're being streamed. So the rest of the UI is good to go, these things are being loaded in.

Whenever they feel they're ready, they all have random delays, so they pop in at random times. And you can control their independent states without having to figure out like the whole route, the whole page or the whole layout. They're all independent.
>> Scott Moss: So I think this is something, a lot of frameworks, I think something like this is what Astro does.

Or you might have built something like this, cuz this is not new. Like, for sure it's not new, but you would have, it wasn't on the framework level. It was like, cool, react suspense. Now, how do we actually take advantage of that? You had to build a bunch of stuff to enable this, so really only the most elite companies probably did it.

Now it's just, you add a file called loading and you're done, which to me is kinda crazy
>> Scott Moss: Cuz really when you add the loading file, what it's doing is it's taking, it's going into the layout, I believe, and it's wrapping a suspense around this. It's saying suspense, it's like doing this, and then suspense takes a fallback.

And that's the loader that you wanna show, so it takes whatever you put in that file and puts it in his file back here. That's what it's done. So you can even do that too, and in fact, you would if you wanted to suspend some client components, you would have to right suspend.

>> Scott Moss: Okay, let's do the Erawan, so, I'll make a error file on the root of dashboard. Error.tsx, and then we'll throw an error so you can see it. So error.tsx has to be client, use client, and I think I have some code here. I hit Save so it broke.

Let me go back to the notes, let's get, yeah, I'm just gonna take this one right here.
>> Scott Moss: Do that, it's gonna rename this to home error like that. This thing is not syntactically correct, is it? There we go.
>> Scott Moss: So we have that, let's go back to our page here.

So, everything still should work, it's cash, everything's great. So now I'm gonna go down here to the home one, which is this one, I'm gonna throw an error, right? So I'm gonna go here, and I can throw an error anywhere in here, but I'm gonna throw an error right in the function itself.

So I'm gonna go in here, I'm gonna say, throw new error, oops. So I'll do that. What do you know? Only that I'm gonna errors out, but the rest of them load in just fine independently. They don't even care, they don't even know.
>> Scott Moss: And to me this is powerful because, I would say most apps aren't like this.

Most apps, this whole page is gonna die. [LAUGH] Like you're gonna see like a, yeah, you're not gonna see anything, the whole page is gonna die. But now it's just that little thing over there. You can easily put a reset button right there that says, click that button to load this one again which is exactly what I put.

That's what this button is, this button is supposed to load it again but it's just gonna keep throwing an error cuz I hard coded it so
>> Scott Moss: Every, error file, every error boundary file comes with a, where is it at? Here we go, it comes with a reset as a fun, as a prop.

When you call this again, it will try to re-render the page in which it is a boundary for. It's just a re-render, it's like re-render this again, try this again, try this again. So yeah, you can just build a really cool UI and it's like, something happened, let me do that again.

You also should have access to the error message, I believe, let's see.
>> Scott Moss: Yeah, oops, there you go. So it's like whatever error you threw, you could put there too.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now