Check out a free preview of the full Complete Introduction to React (feat. Redux and React Router) course:
The "Using Express Part 2" Lesson is part of the full, Complete Introduction to React (feat. Redux and React Router) course featured in this preview video. Here's what you'd learn in this lesson:

Brian continues creating the Express application to enable the universal rendering. He adds all the conditions for the various HTTP status codes. Once the universal rendering is working, Brian shows the browser source code to illustrate why universal rendering is so beneficial both for performance and for users without JavaScript enabled.

Get Unlimited Access Now

Transcript from the "Using Express Part 2" Lesson

[00:00:00]
>> [MUSIC]

[00:00:03]
>> Brian Holt: So we're actually just gonna write things and error for that. So if error res .status(500) .send(error.message). So if I have an error, give me a status of 500. Which if you're not familiar with your http status codes. One I don't want to talk about them because they're boring.

[00:00:29] Actually they're kind of fun, depends on who you're talking to. My fellows they just adopted 451 as a standard error code, which means censored. I appreciated the the literary reference there to the Fahrenheit 451, right. So Reddit actually does it takedown requests, right. And so if it sends you back a 451, it means that the government asked them to censor it.

[00:00:57] I thought it was pretty cool. So anyway, a 500 means holy crap, the server blew up, right.
>> Students: [LAUGH].
>> Brian Holt: So else if (redirectLocation) then you're gonna do a res.redirect(302) which just means I don't remember, is 302 temporary or permanent?
>> Speaker 3: Temporary.
>> Brian Holt: Temporary? Yeah, so this is gonna be a temporary location.

[00:01:28] This is gonna be a redirectLocation.pathname + redirectLocation.search which is basically gonna say it's going to maintain all the parameters all the way through, that's what the search part is.
>> Brian Holt: That one matches to that, okay.
>> Brian Holt: Where is this parenthesis coming from?
>> Students: Should be on line 29 after redirectLocation.

[00:02:04]
>> Brian Holt: Yep, thank you.
>> Brian Holt: Okay, else if (renderProps). So if I found something, this is like the happy path, this is actually the fun part of the server. We wrote all this crap just so we could write this tiny little body down here. const body = ReactDOMServer.renderToString. And we're going to give ourselves some breathing room in on this.

[00:02:44] React.createElement(provider, {store}, ), and remember this is just store store right but we're just going to do it this way because we can. React.createElement
>> Brian Holt: (RouterContext, renderProps).
>> Brian Holt: And that's it.
>> Brian Holt: So body here, so what's happening here? So, Provider right that looks familiar that's coming from our React store or from a redux store, right, and then RouterContext.

[00:03:36] If we go in here and look at our, if it's still working. [INAUDIBLE] connecting in react. Notice that there's a RouterContext here underneath router, right. We're actually using this directly, because we can't use the router directly. We have to use the primitive underneath it. And this is actually going to be passing in all of our renderProps directly to this, and then the RouterContext knows how to render your app correctly.

[00:04:06] We're basically manipulating RouterContext directly. And we're using router, router is just a little wrapper on top of RouterContext. That makes some sense? So router is made really nice use for like, client side stuff. And then if you want to do the advanced rendering on the server stuff you have to manipulate RouterContext.

[00:04:26] That's why they're are different. Just, so you know, okay.
>> Brian Holt: So now we have a nice little body here. This should be a string of whatever our React app looks like. Then we’re do a res.status(200) which means yeah, I found whatever I'm looking for. .send(template(body), right. Remember up here, template is our baseTemplate, right?

[00:05:02] Our index [INAUDIBLE] this is going to have the head and the HTML and all that stuff that we don't really care about in terms of React. And then this [INAUDIBLE] you're gonna insert body straight into that template tag that we threw on there. Right, and then we need one more else which is 404, holy crap I didn't find what you're looking for, res.status(404).send( 'not found') or whatever snide remark you'd like to make to your user.

[00:05:39] Or you could send your 404 page here as well. Okay, two more lines [LAUGH] console.log
>> Brian Holt: Listening on port, port. And then app.listen(port). Okay, so
>> Brian Holt: Give you just a couple seconds here to catch up.
>> Speaker 5: Can you do the string interpolation in Node, for port?
>> Brian Holt: Maybe.

[00:06:27]
>> Speaker 5: I haven't done it.
>> Brian Holt: You have to check. I don't remember off the top of my head.
>> Brian Holt: All right, let's take a wild look and see if this works. So end your HTTP server. Where am I? So what I'm gonna say is node app.js and hopefully not go down in a blaze of glory.

[00:06:58] All right, so we're on 5050 now. So instead of being an 8080 and I'm change this to 5050. Body is not defined, okay. So that's that low dash so let's go find what we did wrong with index.html. That should be there. Did I do this wrong?
>> Speaker 6: Somebody in chat said, shouldn't we provide an object literal to the template.

[00:07:32]
>> Brian Holt: Right, that's exactly right. Okay, go to app. It's not actually just body. Where is it? Right here. So it's not just the string, you actually have to put in as an object. So it'd be body body, right. But you could actually just do body like that. That's totally fine.

[00:07:57]
>> Brian Holt: Oops, let's try that again.
>> Brian Holt: Okay listening again, refresh the page. Okay, so now we see our app again.
>> Brian Holt: But let's look at the interesting thing here. So open like, to do view source, View Page Source. Look at all the stuff that's getting sent down now.

[00:08:24] It's not just an empty thing and it's maybe a little bit more impressive to look at Search. So it you look at Searches page, look at how much markup is getting sent down, as opposed to before it was just the little tiny bare bones index.html. Now we're actually doing real universal rendering.

[00:08:45] So, to go back to my compelling example, if we go back to Network and say throttling to Regular 2G. Refresh the page. Notice I got it a lot faster. And don't get me wrong, it's actually still just as slow because that bundle file is still ginormous. So actually this is.

[00:09:09]
>> Brian Holt: This actually now will work totally without JavaScript, almost. The search won't work anymore without JavaScript, so if we refresh again. And I type orange right now, the search isn't gonna work yet.
>> Brian Holt: I actually don't know what it's gonna do it. I might just blow it away once React actually renders.

[00:09:40] It's still loading. [LAUGH]. Yeah, there's a ton of it. That's never gonna load [LAUGH]. Okay, anyway, something else you might have noticed though. Let's take this throttling off cuz that's going to absolutely drive me crazy. So if you go in to orange, right. I broke a lot of the images, that's gonna be true.

[00:10:05] Why didn't these break? That's why. So if you want to fix your images real quick, come into Details and put a slash on public. Because it's trying to look for your images that details slash public if you don't have the slash on here. But now we want to go actually to just public.

[00:10:25] So put /public on there. Okay,
>> Brian Holt: So now, if you go back into Daredevil, it should work.
>> Brian Holt: Magic, pretty cool, did people get it as well, or did we break along the way too?
>> Speaker 7: I guess I have a quick question is, what is it about universal rendering that's actually offering you a speed up.

[00:10:58] Cuz you're, on the server side, generating the DOM, right, but where you're throttling is the the network. It seems like you'd be getting more delivered by rendering the whole DOM, as opposed to just getting the JavaScript, am I missing, what am I missing?
>> Brian Holt: What you're missing is, first of all, your service can be way faster than anyone's laptop, right?

[00:11:20] So if someone's on some crappy flip phone, right, they don't have to worry about React rendering it. It's actually pre-rendered for them.
>> Speaker 8: Gotcha.
>> Brian Holt: And the other thing is, think about how big this is. Well, actually I can, we can demonstratively look at how big this is.

[00:11:38] So, we look at our bundle, how big is our bundle now? Our bundle is almost a meg, right, somewhere close to that. But if we look at Network here, I mean look at all, refresh. Our search page is only about 20 KB. So in order to see their very first view, they only have to download 20 KB, right, instead of a meg of JavaScript.

[00:12:03] So that's really the speed up right there. If they perceive seeing this immediately.
>> Speaker 8: Interesting.
>> Brian Holt: So I mean, front end development is a psychology game, right. The idea is to show them something as fast as possible, and then the idea after that, once you have universally rendered this, you wanna hurry as fast you can and make it interactive.

[00:12:20] Cuz once they see it, they assume it's already interactive. And if your network is just fast enough, by the time they click on it, it's gonna be interactive, right. Because there's a delay from me seeing it, to me understanding, to me deciding what I want to do, right.

[00:12:34] And usually, in that hopefully 400 to 500 milliseconds, you can get the rest of your JavaScript out there and then make it interactive. So this is playing the psychology game for sure.
>> Speaker 9: What about if you're not running Node in the back end?
>> Brian Holt: Then you're out of luck.

[00:12:52]
>> Speaker 9: That's what I thought.
>> Brian Holt: So yeah, you need you need some sort of node. So there's a couple strategies to that. My absolutely hair-brained scheme that worked okay at Reddit, before they let me use Node, is I just started using Node. So basically, I had a service out on the side that I would shoot all my data to.

[00:13:14] The Node server would hurry and render it, and then send it down to the client. Or it could send it back to the server on the server and send it back. And if you're just in the same data center that's a really fast hop, so that's okay. You can also do some fancy things like caching that on the side, like if it's the non-member home page, right.

[00:13:30] All that's totally cacheable, you can just send it into a cache and instantly serve it from the cache. So you can have a Node service on the side just populating a cache. So here's a couple things you can do. But if you actually want to do it in this style, where you're actually rendering it on everything, like for example, when you do on Netflix.

[00:13:47] That's what we're doing even for the member side but we can do that because we're using Node. So, Node has to be in there somewhere, suffice to say. I've heard of people with mixed results doing it with Rhino, which is what you run with Java. I've also heard that Rhino is like a hot pile of garbage, so take that for whatever you will.

[00:14:09] I have no personal experience, I'm just parroting what people have told me.