In my “Server-Side Rendering in React” series, I have described so far, how to configure an application to be rendered on both server and client. I have also shown how to add Redux to the server-rendered app. Today we will enrich our example with routing. To do so, we will use the react-router library because it is the most popular routing solution in the React ecosystem.
As in my previous SSR article, I assume that you are already familiar with the react-router library. If not, please take a look at the documentation of this great library.
In today’s article, we will work on the code we already created in my two previous articles. Before we start amending our example, let’s install the
react-router-dom package. We can do it using the following command:
The above command, along with
react-router-dom, also installs the
react-router library, which will be useful in our example.
Component structure changes
Now that we have all the necessary packages installed, we can move on to make changes to our app. Our plan is to rename our
App.js component to
Home.js and use it in the
/ route. We will also add the
About.js component and use it in the
/about path. Then we will create the new
App.js component, which will be the root React element of our application and will be the place where the routing is configured. Later in the article, we will make changes to the code that renders our app on the server and on the client.
Home and About components
Let’s start from changing the name of the
App component to
Html — actually, all we have to do is to rename the component function and the file. Please see below how the amended code looks like:
Now, let’s create the
About.js component. It may be implemented like below:
As you can see, it is a straightforward component that renders only some static information. For the example purpose, I don’t need it to be more sophisticated nor connected to Redux.
App component and routing configuration
About.js components will be displayed respectively for
/about paths. We will configure it in the
App.js component we are about to add right now:
The above code is quite simple — it just renders the list of links to make navigation easier. It also uses the
Switch and the
Route components of the
react-router-dom package to configure our routing.
Changes to the server-side rendering code
Ok, all the necessary changes in the structure of the components are done. Now, let’s move on to the
server.js file where rendering on the server is performed.
What do we want to achieve here? When the user opens one of the paths of our application in the browser (or simply refreshes the page), our server should render the right components tree and send it to the browser.
Please see below what changes to the
server.js file has been done:
We haven’t made many changes here, actually. The first thing to consider in the above code is the import of the
StaticRouter component. Please notice that it is imported from the
Now, please take a look at how we have used this component — we’ve just wrapped components passed to the
renderToString method with the
StaticRouter component. To make it work, we had to assign two things to its arguments. Firstly, and most importantly, we have assigned the
req.url value to the
location attribute. Thanks to it, the react-router will be able to pair the route from the browser address bar with a suitable component assigned to this route in the
The second attribute required by the
StaticRouter component is
context. We have passed an empty object in it. This object will be added to the
props object of a component rendered for the matched route. This way, we can provide some additional information to this component while rendering.
Changes to the client-side rendering code
The last (but not least) thing to do is to change the way how the client code is rendered. Let’s amend the
client.js file a little bit:
As you can see, all the changes we had made here are pretty straightforward. We’ve just imported the
BrowserRouter component from the
react-router-dom package. Next, we have wrapped with it our existing components tree.
And that’s all — our routing works on both the server and the client!
You can test it by running this project:
yarn start; and visiting the http://localhost:3000 address.
react-router into the server-side rendered React project is, as you have already seen, quite an easy task. In the next article of my series, I will show you how to deal with the data fetched from the external API in this type of application. This way, we will cover all the essential aspects of the SSR topic and finish the whole series.
The example we have discussed today is available in my GitHub repository. I encourage you to clone it and play with it on your own.
P.S. This post is a part of a series of articles about Server-Side Rendering using React. Please see the list of all items of the series below:
- Server-Side Rendering in React — an Introduction
- Server-Side Rendering in React — Express.js
- Server-Side Rendering in React — Redux
- Server-Side Rendering in React — react-router
- Server-Side Rendering in React — Dealing with Real Data