DEV Community

Cover image for What's Why's and How's of Server Side Rendering using ReactJS
server side digest
server side digest

Posted on • Updated on

What's Why's and How's of Server Side Rendering using ReactJS

🚀 When we talk about SSR (Server side rendering) rendering static content and showing them to the user sitting on the client side seems to be possible. But now a days our Websites are not static anymore. Now, we can send messages, update the status, change the ui etc etc.

😅 So, SSR in this case seems impossible.

SSR server side rendering

📍 What is SSR and How does it work

SSR or server side rendering is the method to display the information to the user that is being rendered by the server or in other words Server converts the files like HTML into the information suitable for the browser.

👉 Didn't understand? Don't worry we will dive a bit deeper.

Whenever we make a request to a server its response depends on the several factors like:

  • Speed of your internet
  • Location of the server
  • Website optimisation

😎 Once we open the website, it will request the server to fetch the HTML page and when you'll switch to another page, It will again make a request to fetch the rendered page if it has not been cached.

😎 Advantage:- The main advantage of SSR is that the content will be pre-available that we want to see and Search engines are able to index the content present in the website for SEO. So, for better SEO, SSR is a big Plus.

🥵 Disadvantage:- The main point to focus here is, It doesn't matter if the new page that we are requesting is different than the old by few items only. Let say new page is showing "Order placed Successfully" and rest is our old page, even then it will request for the entire page. This is one of the reasons why Wordpress website is slower in most of the cases.

📍 Client Side Rendering

In modern websites where most of the times content keep on changing or being an interactive website only few components changing, there use of Javascript is a big plus. Like rendering only the content whose state has been changed. Many libraries/frameworks are out there like React, Vue etc.

⭐️ Here server is responsible only for heavy tasks like getting data and storing into the DBs, sending notifications etc.

📍 SSR or Server side rendering using ReactJS

Follow these steps to enable SSR in ReactJS:-

  • Run in cli
cd react-example
npm start
nano src/Home.js
Enter fullscreen mode Exit fullscreen mode
// Home.js
function Home(props) {
  return <h1>Hello {props.name}!</h1>;
};

export default Home;
Enter fullscreen mode Exit fullscreen mode
  • Next, let's create an App component:-
  • Run in cli
nano src/App.js
Enter fullscreen mode Exit fullscreen mode
// App.js component
import Home from './Home';

function App() {
  return <Home name="Sammy"/>;
}

export default App;
Enter fullscreen mode Exit fullscreen mode
  • Run in cli
nano src/index.js
Enter fullscreen mode Exit fullscreen mode
import React from 'react';
import ReactDOM from 'react-dom';

import App from './App';
// using hydrate method instead of render to indicate the DOM that you intend to rehydrate the app after a Server side render
ReactDOM.hydrate(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode

📍 Now setting up the server side

  • Run in cli
mkdir server
nano server/index.js
Enter fullscreen mode Exit fullscreen mode
// index.js file
import path from 'path';
import fs from 'fs';

import React from 'react';
import ReactDOMServer from 'react-dom/server';
import express from 'express';

import App from '../src/App';

const PORT = process.env.PORT || 3006;
const app = express();
// ...

app.get('/', (req, res) => {
  const app = ReactDOMServer.renderToString(<App />);
  const indexFile = path.resolve('./build/index.html');

  fs.readFile(indexFile, 'utf8', (err, data) => {
    if (err) {
      console.error('Something went wrong:', err);
      return res.status(500).send('Oops, better luck next time!');
    }

    return res.send(
      data.replace('<div id="root"></div>', `<div id="root">${app}</div>`)
    );
  });
});

app.use(express.static('./build'));

app.listen(PORT, () => {
  console.log(`Server is listening on port ${PORT}`);
});
Enter fullscreen mode Exit fullscreen mode

Here,

  • express is used to serve contents from the build directory as static files
  • renderToString is used to render the app to a static HTML string
  • index.html being read from the client side and content is injected into the root tag

    🔥 Now, to achieve SSR, we need to use webpack(to bundle the folders and files), babel(to provide the extra functionality to the webpack bundling) and npm scripts.

    • Run in cli
    nano .babelrc.json
    
    • Inside babelrc.json
    {
      "presets": [
        "@babel/preset-env",
        "@babel/preset-react"
      ]
    }
    
    • Run in cli
    nano webpack.server.js
    
    // webpack.server.js file
    const path = require('path');
    const nodeExternals = require('webpack-node-externals');
    
    module.exports = {
      entry: './server/index.js',
      target: 'node',
      externals: [nodeExternals()],
      output: {
        path: path.resolve('server-build'),
        filename: 'index.js'
      },
      module: {
        rules: [
          {
            test: /\.js$/,
            use: 'babel-loader'
          }
        ]
      }
    };
    
    • Run in cli
    • package.json file
    nano package.json
    
    "scripts": {
      "dev:build-server": "NODE_ENV=development webpack --config webpack.server.js --mode=development -w",
      "dev:start": "nodemon ./server-build/index.js",
      "dev": "npm-run-all --parallel build dev:*",
      // ...
    },
    
    • Run in cli
    npm install nodemon@2.0.15 --save-dev
    npm install npm-run-all@4.1.5 --save-dev
    npm run dev
    

    🎉 Now, open http://localhost:3006/ to see the SSR app.

    👉 Kindly go through the Webpack configs and the code you'll get to know what are we trying to do.

    📌 Follow for more such compiled blog versions.

Top comments (0)