React Server Side Rendering Done Right with Next.js

April 05, 2018 0 Comments

 

Over time, React.js has proven to be an excellent choice for building high-quality web applications. However, it becomes more complex as you need to learn about client-side routing, page layout, and so on. If you'd like to perform server-side rendering for faster page loads, things can become even more difficult.

Next.js is a universal JavaScript framework that runs in the browser and the server. It offers developers an easy way to get started, and as it uses React.js for templating, it is also a straightforward way for developers with React experience to get productive fast. One of its strong points is that it handles server-side rendering excellently, and it integrates with Express just well. Yes, your Express, our lovely Express.

What exactly is server-side rendering

Server-side rendering was the conventional method for getting your HTML up onto a screen. This refers to using a server environment to get your HTML up to the browser.

So why the fuzz over it if it’s a conventional method used back in the days? Oh well, remember the introduction of MVC (model, view, controller) concept which brought about a separation of concern? This brought about separating views totally from the business logic and brought about the rise of JavaScript frameworks for rendering views. You may ask, so what has this got to do with it? Soon enough, a problem emerged, which was: the JavaScript frameworks only displayed a bunch of divs in the browser, using DOM manipulation to do its work around the browser. This means that the user has to wait longer to see anything. It can also impact SEO if crawlers can’t see the content of the page quickly.

Oh well, that became a problem that needed to be solved. One solution was to render the JavaScript files from the server before returning its output to the server.

Getting started with Next

Getting started is simple. All we need to do is make a new directory, start a new node project, install Next, React and React-dom.

https://gist.github.com/587ced999a4536e164ae10a28826a472

Next, open up your package.json and replace your script section with this:

"scripts": { "dev": "next", "build": "next build", "start": "next start"
}

Run the npm run dev command, you should get an error like :

next
> Couldn't find a `pages` directory. Please create one under the project root

This is because Next uses the pages directory and the files in them to map its routes. This means if we have a file called index.js in our pages folder, Next would try to use the component in it as our entry point. Let’s create the pages folder and the index.js file.

https://gist.github.com/c5f0304db7b623b292f09a78ce251fd1

Next, let’s add some code to the pages/index.js file:

https://gist.github.com/a238f8bd14a73a0250d648e177c580e2

Save the file above and run the command npm run dev in your terminal. If you visit your browser, see the text “Hello Next.js, this is your friend Brian from logrocket” printed out on your browser.

Notice how easy this is? No need to mount React to a div, no need to import React, no need to set up routes. In our usual React app, we would need to do other configs to allow for code-splitting and server-side rendering. But hey, view your page source, you would be amazed. It’s all done out of the box.

Notice in the image above, there is a specific reference to [/_next/-/page/index.js](http://localhost:3000/_next/-/page/index.js)? That’s code splitting done right. Also, notice that the div which has your text was fully rendered? That’s server-side rendering taking place.

Next and Express

I bet you thought that was all the magic Next had in store. Next went a step further by allowing better server-side rendering using Express for the tougher cases. First of all, add Express into your app:

npm install --save express

Then create a file called ssr-server.js in your app and add following content:

https://gist.github.com/c198c1554519b9169d08e766fee56bec

What happens in the code above? We require both Express and Next libraries. We create an instance of the Next library passing in a Boolean based on the environment which detects whether to launch Next.js in dev mode or not.

We move ahead to call the getRequestHandler() function, then finally we prepare the app. The prepare function returns a promise, so we can do a .then pipe to it. In the .then call, we initiate Express, and we use a wildcard route to catch all routes and return it to the handler function.

Now update your npm dev script to:

{ "scripts": { "dev": "node ssr-server.js" }
}

If you run npm run dev, your page would spin up looking the same as it was. So how is this helpful if I end up getting the same result as I got earlier? Hold on fella, let me show you.

While what we have done above does not seem to add much difference, it makes sense when we add more routes as it helps to achieve clean URLs, which by default if implemented in Next would return 404 pages (when not navigated by a Next link i.e if I manually put in the URL in a browser or I was directed from another site).

Look at this route below, This helps us to achieve clean URLs as discussed in the paragraph above:

https://gist.github.com/df7da1c7c09d3f78b2cbca5d6ffdda2e

By default, it’s easy to use query strings in Next, but as usual, you want to keep your URLs clean, so you opt for something like: /p/2 rather than /p?id=2. In the code above, we use the popular express routing to define such routes, then we pass the page that should be loaded and the id as a query param to the main Next app. Here the call /p?id=2 happens under the hood where no one can see what is going on. To the regular user, he sees the URL as /p/2/.

Serving and exporting your app

So when done building the Next app, how do I serve it in production? Easy. First, we have to build the app, then we can serve it. Luckily, Next provides an easy way out. Remember the script section we had in the package.json, we had it all set up there. All we need do is:

https://gist.github.com/11f1cf1bc59577c8eae9a5d2fa4b2e2b

Wow, that’s cool, what if I want to export the app as a static HTML file? Great question. First, create a file called next.config.js in the root of your app and add the following content:

https://gist.github.com/1a90d57b1d47282f07aecbf1292a6e70

Note: In the setup above, only the index page would be exported as it is the only route we have specified in the PathMap.

What if I want to add more pages? Amigos, that’s a good question. You can add a new key and value in the return object of the PathMap like '/about': { page: '/about' }.

Then add the following to the scripts section of your package.json:

"export": "next export"

Finally, build and export your app.

https://gist.github.com/4dc864a5280686ffe559f4b72845c712

Conclusion

In this tutorial, we have been able to see how relatively easy it is to build a server-rendered app with Next.js. It is an excellent way of doing things using React. If you have gone through the procedure to achieve the same result in React, you would agree with me on this one.

Do you have any comments or observations? Let’s talk in the comment section.


Tag cloud