Author avatar

Vivek Kumar

Rendering React Components Which Require Styles on Server

Vivek Kumar

  • Jun 11, 2019
  • 12 Min read
  • 64 Views
  • Jun 11, 2019
  • 12 Min read
  • 64 Views
Web Development
React

Introduction

The application of the styled-components in the server-rendered React application helps you attain a seamless, yet dynamic, framework. The magnitude of impact that the styled components can have on your finished products is beyond imagination. That is the reason why it is essential to understand how to render React components requiring styles on the server right from the grass root level.

Here, you'll get a straightforward guide on rendering the React components requiring styles on server styles with easy language and proper examples to make it understandable at first glance. The prime objective of this guide is to help you understand the core principles that will edify the beauty of the style components and blend them into your application right away. Nevertheless, we will also help you understand how easy it is to integrate the style components into already existing applications which are currently depending on other techniques for styling. With the easy and seamless approach of this guide, it is still important to note that we will not bring up other libraries like React Router, Redux or, other concepts like code splitting.

Let us get on with the basics.

Setting Up the React App

Firstly, let us have a glance at how our application can be designed for study in this guide. It is essential to confine all sorts of dependencies, as well as the scripts, within the package.json. The building step will be administered via webpack.config.js. After the completion of the building step, you will be happy to know that all the routing and serving of the React application can be accomplished via a single serve.js file. It is critical to note that it is the client/ folder which comprises of the real application in App.js, index.js, and Html.js.

In order to initiate, you are required to form an empty package.json in a newly created empty folder of your choice. The command required to be entered is simple, as shown:

1
npm init --yes or yarn init --yes

The application structure that would be created in the end would look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
src/
|---client/
|	|
|	|---App.js
|	|
|	|---Html.js
|	|
|	|---index.js
|
|---server.js

package.json
webpack.config.js

Once you acquire the application structure, you can easily paste the following dependencies and scripts into the code to make things more effective. The dependencies for this specific type of application comprises of React, Express, Babel, styled-components, and Webpack.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
"scripts": {
  "start": "node ./dist/server",
  "build": "webpack"
},
"devDependencies": {
  "babel-core": "^6.10.4",
  "babel-loader": "^7.1.2",
  "babel-preset-env": "^1.6.1",
  "babel-preset-react": "^6.11.1",
  "webpack": "^3.8.1",
  "webpack-node-externals": "^1.2.0"
},
"dependencies": {
  "express": "^4.14.0",
  "react": "^16.2.0",
  "react-dom": "^16.2.0",
  "styled-components": "^2.2.4"
}

As all the dependencies are taken into consideration, it is now feasible for us to set up the scripts in order to initiate and create our project. After the completion of this step, the setup of our React application will be done.

.src/client/App.js

1
2
3
4
5
import React from 'react';

const App = () => <div >💅</ div>;

export default App;
javascript

App.js actually returns a div which wraps the 💅 emoji. It is quite evident by the image displaying the commands. Here, we all are well aware of the fact that it is a basic type of React component that the user will be rendering for the browser.

src/client/index.js

1
2
3
4
5
import React from 'react';
import { render } from 'react-dom';
import App from './App';

render(<App />, document.getElementById('app'));
javascript

index.js is specifically the standard approach for mounting a React application to the concerned Document Object Model (DOM). In this particular step, our objective will be to take out the App.js component and thereafter render the same.

src/client/Html.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
 * Html
 * This Html.js file acts as a template that we insert all our generated
 * application code into before sending it to the client as regular HTML.
 * Note we're returning a template string from this function.
 */
const Html = ({ body, title }) => `
  <!DOCTYPE html>
  <html >
    <head >
      <title > ${ title } </ title>
    </ head>
    <body style = "margin:0" >
      <div id = "app" > ${ body } </ div>
    </ body>
  </ html>
`;

export default Html;
javascript

Now, what we have here at the moment is the package.json which comprises of all sorts of scripts and dependencies belonging to the user, along with the rudimentary React app in the specific src/client/ folder. Here, the rendering of this particular React app will be in the form of HTML via the Html.js file which returns a form of template string.

Building Up the Server

In order to render the app over the server, it is necessary for us to set up the express to handle the request and then revert back our concerned HTML. Here, with the express already built, the building of a server right away will not be a daunting task at all.

src/server.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import express from 'express';
import React from 'react';
import { renderToString } from 'react-dom/server';
import App from './client/App';
import Html from './client/Html';

const port = 3000;
const server = express();

server.get('/', (req, res) => {
  /**
   * renderToString() will take our React app and turn it into a string
   * to be inserted into our Html template function.
   */
  const body = renderToString(<App />);
  const title = 'Server side Rendering with Styled Components';

  res.send(
    Html({
      body,
      title
    })
  );
});

server.listen(port);
console.log(`Serving at http://localhost:${port}`);
javascript

The Configuration of the Webpack

As the objective of this guide is to enrich the basic knowledge, we will keep the configuration of the Webpack simple and straightforward. Here, we are putting up the application of Webpack in order to create our own React app in the production mode along with the application of Babel. Do note that there will be a single access point located at src/server.js along with output at dist/.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
const path = require('path');

module.exports = {
  entry: './src/server.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'server.js',
    publicPath: '/'
  },
  target: 'node',
  externals: nodeExternals(),
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: `'production'`
      }
    })
  ],
  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: 'babel-loader'
      }
    ]
  }
};
javascript

As the results are rendered, it is quite easy to assess that we have enough to create and serve a solely server-side type rendered React application. Now, you can render two forms of commands and be prepared to avail the best results. The primary run will be:

1
yarn build or npm build

Thereafter, in order to commence the application run:

1
yarn start or npm start

If it gets started then it is well and good; otherwise, the user is required to include a .babelrc file at the root of the project created.

Finally, you can visit the URL http://localhost:3000 after a successful yarn build and subsequent yarn start.

The Addition of Styled Components

The results procured up until now are far better than the anticipation. The successful creation of the React application rendered on the server enables us to run the things a lot easier. There is no involvement of any third-party libraries such as Redux, React Router, and the Webpack will be upfront without beating around the bush.

Now, we have reached the point where we can commence styling the app through the style components.

src/client/App.js It is time to build the first styled component. In order to build a specific styled component, you are required to import styled and then define the component.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import React from 'react';
import styled from 'styled-components';

// Our single Styled Component definition
const AppContainer = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  width: 100%;
  height: 100%;
  font-size: 40px;
  background: linear-gradient(20deg, rgb(219, 112, 147), #daa357);
`;

const App = () => <AppContainer >💅</ AppContainer>;

export default App;
javascript

src/server.js This is the step where some of the largest and key changes will take place. The styled-components will highlight ServerStyleSheet which will permit the user to form a stylesheet by all the available styled components existing in your <App />. After that, this stylesheet gets access to the HTML template.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import express from 'express';
import React from 'react';
import { renderToString } from 'react-dom/server';
import App from './client/App';
import Html from './client/Html';
import { ServerStyleSheet } from 'styled-components'; // <-- importing ServerStyleSheet

const port = 3000;
const server = express();

// Creating a single index route to server our React application from.
server.get('/', (req, res) => {
  const sheet = new ServerStyleSheet(); // <-- creating out stylesheet

  const body = renderToString(sheet.collectStyles(<App />)); // <-- collecting styles
  const styles = sheet.getStyleTags(); // <-- getting all the tags from the sheet
  const title = 'Server side Rendering with Styled Components';

  res.send(
    Html({
      body,
      styles, // <-- passing the styles to our Html template
      title
    })
  );
});

server.listen(port);
console.log(`Serving at http://localhost:${port}`);
javascript

src/client/Html.js In this step of adding the style component, we are including them as our HTML function and then inserting ${styles} argument for the created template string.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
 * Html
 * This Html.js file acts as a template that we insert all our generated
 * application strings into before sending it to the client.
 */
const Html = ({ body, styles, title }) => `
  <!DOCTYPE html>
  <html >
    <head >
      <title > ${title} </ title>
      ${styles}
    </ head>
    <body style = "margin:0" >
      <div id="app" > ${body} </ div>
    </ body>
  </ html>
`;

export default Html;
javascript

Next, run the following command:

1
yarn build or npm build

And with that, you can simply create and render the React components requiring styles from the Server.

To initiate the running of the application, do:

1
yarn start or npm start

Conclusion

With this step-by-step guide, it should be easy to understand how server-side rendering of a styled components based React application is done. The guide is based on simple core concepts and doesn’t intend to try anything fancy.

As a developer, one can apply these core principles to the existing apps or, rather, develop a more complex app on the grounds of the same. In the upcoming guides, we will emphasize the next level indicating performance improvements, routing, state management, etc.

Reference

While writing this guide, the following resources have been referred to:

1