Check out a free preview of the full Intermediate React, v3 course:
The "Building a Node.js Server" Lesson is part of the full, Intermediate React, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Brian walks through how to build a Node.js server using Express.js to statically serve the application after the Parcel build step. Sending back status codes from React Router is also covered in this segment.

Get Unlimited Access Now

Transcript from the "Building a Node.js Server" Lesson

[00:00:00]
>> So if this is your first time writing node, hopefully it's a long and fruitful journey for you. I love nodeJS. It's probably my favorite thing to write day to day. And there's great NodeJS code or NodeJS courses on front of masters most specifically, I really like Scott Master's stuff.

[00:00:21] All right, so we're gonna make a folder called server. So we have our source, which is gonna be the front end code and our server which is gonna be the server and go ahead and make a file called index dot j s inside of your server directory. And here, you and I are just gonna code up a quick little note server together.

[00:00:43] If this is your first time running node, no big deal. We'll do it all together. If you just follow along, you'll you'll get exactly what you need. So we're using Express so make sure you've installed Express. So npm install, Express. So npm install Express at 4.17.1, that should get you a copy of Express that which is like the most common way of doing nodeJS servers.

[00:01:17] And then here when do import, Express from Express, import, render to string. And again, remember we're doing this with Babel running all of our node code. So we can use the ES modules with impunity, right? Because it's just not a big deal. It's gonna we're gonna go through Babel anyway.

[00:01:40] From ReactDOM slash server, import static router from React Router DOM import Fs from Fs and import app from dot dot slash source app. These are all of our imports render to string is basically instead of doing lrender to DOM or render hydrate all those decisions that give you back a string of the HTML.

[00:02:13] Static Router is a special component, it's a special router from React Router DOM that doesn't depend on the browser API is being there. This is file system, it's just a node built in and then this is our react app here that we coded together. Okay, let's grab the port which is gonna be either process.m.port, or 3000.

[00:02:38] I just do this because if you're gonna deploy this to something like Azure App Service or Heroku or something like that, they will give you the port via an environmental variable. And if you don't provide it, then I'll just set it to 3000. Okay, const html equals fs dot read file sync.

[00:02:57] This is going to read and then block until this is finished reading so don't do this in your note server but what during startup, it's okay. So we're gonna read dist slash index dot HTML. And we're gonna say to string, so this is going to go read our built that you can see here I already built it.

[00:03:21] It's gonna go read this file, but it's going to split here on not rendered. So this is all gonna be in part one, this is all gonna be in part two. So let's see what that looks like. So HTML right now it's just this entire document and then we're gonna split that into parts by doing html.split on not rendered.

[00:03:48] Which again if you look here, not rendered is gonna give me, the first part is gonna be this. So zero is gonna be that, and one is gonna be that. And then we can put our application here, right? Then we have complete HTML when we send that down to the client.

[00:04:09] Okay const app is gonna be a new Express app to start that up. app.us we have to serve dist. Slash dist is gonna be served statically. So, serve all of our HTML, CSS JavaScript, static Dist, so this directory here that's gonna be coming from dist. App.use, It's gonna be a handle that takes in req and res, request and response.

[00:04:44] Here we're gonna do first thing, const static context equals an empty object. And we'll use this in just a second. And then we're gonna say const react mark-up equals, And we're gonna put in here a static router. With URL equals rec dot URL, so the request URL that the user asked for, and then we're gonna say the context here is gonna be the static context object that we're gonna pass into it.

[00:05:21] Now why do we do this? Well, what happens if we ask for a route that doesn't exist? We need to get that to the user as a 404, right? Otherwise, everything's gonna be a 200 from this response, that's a problem, because we wanna be able to give appropriate status codes for users not finding the right thing.

[00:05:41] Okay, and then in here, we're just gonna render our app. Now we're gonna say res dot status. This is where you send a 400 or something like that, where they're gonna say static dot com static context dot status code. So this is gonna have a now that this has been through static router, we can even say that like this is gonna be a 400 or 404 or 500.

[00:06:06] Anything that the client is telling. This is what I wanted to send back to the user. Or this can be a 200 as like 200 okay. Now this is important just because if Google is crawling your site, and they try and crawl something that doesn't exist, if you give it a 200, Google's gonna say, great, here's this page that's on your website.

[00:06:27] But if you give it a 404, Google is gonna be, I'm not gonna index this, right? That's probably the most important reason why you wanna do that. Okay, res dot send them we're gonna do template string. We're gonna send the first part of it and so parts zero, that's the first part of the HTML.

[00:06:44] We're gonna send the markup, so render to string, react markup and then we're gonna do part one. And this is gonna be our total complete response. Here then we say, res dot end like that and say okay. I've wrapped everything up. I'm done, send the response to the user.

[00:07:11] Lastly here we're gonna say, console dot log Listening on http://local host. Con port. This is just so I can remember. It also gives me something I can just click on directly in my terminal, that will take me to the page. And then I'm gonna say app dot listen on port.

[00:07:41] All right, all of this should work now in theory. Cross your fingers. npm run, start, this is gonna build the client. It's gonna build the server, and then it's gonna start the server. So there it goes parcel builds the client, builds the server and now we're running on port 3000.

[00:08:02] And you can see now, this renders immediately. Very quickly do we get a response back but here's something interesting. If I view page source, notice that this is actually coming back with complete markup, right. It has the options here. This has the theme this or this is all the stuff that react was rendering for us before, right?

[00:08:29] This is all coming back as complete markup from the server response. What's even cool about this, is I can come in and say, where's my options here? This one, settings. There we go. If I really wanted to, you can actually disable JavaScript. So I'm going to temporarily disable JavaScript here.

[00:08:54] So disable JavaScript. Now we'll make the request, right? Because react will never bootstrap here. But notice I'm still getting a functional page at the end of this, right? Despite the fact that I disabled JavaScript, that's because it's complete markup when it comes to the user. So their time to first paint is gonna be extremely quickly.

[00:09:13] It's like happened very quickly, but we've delayed maybe a couple milliseconds, maybe a second at most, their time to interactive, right? Because we spent a bunch of time rendering on the server. Now that user is gonna have to wait just a tiny bit longer to get their JavaScript payload for them to bootstrap and hydrate the application.

[00:09:33] So that's your trade off here. You're moving up to time to first paint and you're moving back your time to interactive. Usually, it's probably worth it. I'll say. There's a lot of research that a user can't decide what to do in less than like a second and a half or something like that, right?

[00:09:47] Even if they're super familiar with your website, they're time to move the mouse and click on the thing. You can almost always beat them, right? In their time to comprehend and then click on something. But what I wanna say is measure it. You should know, right? You should do user studies, you should instrument your application, these are all things that you should be interested in finding out about your user.