How to Implement Server-Side Rendering (SSR) in a MERN Stack App
Server-Side Rendering (SSR) improves performance, SEO, and the initial load time of web applications by rendering pages on the server before sending them to the client. In a MERN (MongoDB, Express, React, Node.js) stack application, implementing SSR can significantly enhance user experience. In this guide, we’ll walk through the steps to set up SSR in a MERN app. 1. What is Server-Side Rendering (SSR)? SSR is the process of rendering React components on the server and sending the fully rendered HTML to the client. This differs from Client-Side Rendering (CSR), where JavaScript is executed in the browser to build the UI. Benefits of SSR: Improved SEO – Search engines can index pre-rendered pages. Faster initial load time – Users see content sooner. Better performance on low-end devices – The server does the heavy lifting. Improved social media sharing – Metadata and Open Graph tags are rendered correctly. 2. Setting Up the MERN Stack for SSR Step 1: Install Dependencies You'll need the following dependencies in your MERN app: npm install express react react-dom @babel/preset-env @babel/preset-react babel-register ignore-styles Step 2: Configure Babel for Server-Side Compilation Create a .babelrc file to enable JSX and modern JavaScript features on the server: { "presets": ["@babel/preset-env", "@babel/preset-react"] } 3. Setting Up Express for SSR Step 3: Create the Server (server.js) Set up an Express server to handle SSR. import express from 'express'; import fs from 'fs'; import path from 'path'; import React from 'react'; import { renderToString } from 'react-dom/server'; import App from './src/App'; import { StaticRouter } from 'react-router-dom/server'; const app = express(); const PORT = process.env.PORT || 3000; // Serve static files app.use(express.static(path.resolve(__dirname, 'public'))); app.get('*', (req, res) => { const context = {}; const reactMarkup = renderToString( ); fs.readFile(path.resolve(__dirname, 'index.html'), 'utf8', (err, data) => { if (err) { return res.status(500).send("An error occurred"); } return res.send( data.replace('', `${reactMarkup}`) ); }); }); app.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}`); }); 4. Modifying React App for SSR Step 4: Adjust index.html Template Create an index.html file as a template in your public folder: MERN SSR App Step 5: Modify React Entry Points Modify src/index.js to hydrate the server-rendered HTML. import React from 'react'; import { hydrate } from 'react-dom'; import { BrowserRouter } from 'react-router-dom'; import App from './App'; hydrate( , document.getElementById('root') ); 5. Bundling the Client-Side JavaScript Step 6: Configure Webpack for Client Bundling Create a webpack.config.js file to bundle React code. const path = require('path'); module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'public'), filename: 'bundle.js' }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: 'babel-loader' } ] }, resolve: { extensions: ['.js', '.jsx'] } }; Run Webpack to generate the client-side bundle: npx webpack --mode=production 6. Deploying the MERN SSR App Step 7: Deploy to a Cloud Server Use Vercel or Netlify for frontend. Deploy Express backend on Render, DigitalOcean, or AWS. Conclusion Implementing SSR in a MERN stack app significantly improves performance, SEO, and user experience. By following these steps, you can ensure that your app loads faster and is indexed better by search engines. Start integrating SSR today and take your MERN applications to the next level!
Server-Side Rendering (SSR) improves performance, SEO, and the initial load time of web applications by rendering pages on the server before sending them to the client. In a MERN (MongoDB, Express, React, Node.js) stack application, implementing SSR can significantly enhance user experience. In this guide, we’ll walk through the steps to set up SSR in a MERN app.
1. What is Server-Side Rendering (SSR)?
SSR is the process of rendering React components on the server and sending the fully rendered HTML to the client. This differs from Client-Side Rendering (CSR), where JavaScript is executed in the browser to build the UI.
Benefits of SSR:
- Improved SEO – Search engines can index pre-rendered pages.
- Faster initial load time – Users see content sooner.
- Better performance on low-end devices – The server does the heavy lifting.
- Improved social media sharing – Metadata and Open Graph tags are rendered correctly.
2. Setting Up the MERN Stack for SSR
Step 1: Install Dependencies
You'll need the following dependencies in your MERN app:
npm install express react react-dom @babel/preset-env @babel/preset-react babel-register ignore-styles
Step 2: Configure Babel for Server-Side Compilation
Create a .babelrc
file to enable JSX and modern JavaScript features on the server:
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
3. Setting Up Express for SSR
Step 3: Create the Server (server.js)
Set up an Express server to handle SSR.
import express from 'express';
import fs from 'fs';
import path from 'path';
import React from 'react';
import { renderToString } from 'react-dom/server';
import App from './src/App';
import { StaticRouter } from 'react-router-dom/server';
const app = express();
const PORT = process.env.PORT || 3000;
// Serve static files
app.use(express.static(path.resolve(__dirname, 'public')));
app.get('*', (req, res) => {
const context = {};
const reactMarkup = renderToString(
<StaticRouter location={req.url} context={context}>
<App />
</StaticRouter>
);
fs.readFile(path.resolve(__dirname, 'index.html'), 'utf8', (err, data) => {
if (err) {
return res.status(500).send("An error occurred");
}
return res.send(
data.replace('', `${reactMarkup}`)
);
});
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
4. Modifying React App for SSR
Step 4: Adjust index.html
Template
Create an index.html
file as a template in your public
folder:
lang="en">
charset="UTF-8">
name="viewport" content="width=device-width, initial-scale=1.0">
MERN SSR App
id="root">
Step 5: Modify React Entry Points
Modify src/index.js
to hydrate the server-rendered HTML.
import React from 'react';
import { hydrate } from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
hydrate(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
5. Bundling the Client-Side JavaScript
Step 6: Configure Webpack for Client Bundling
Create a webpack.config.js
file to bundle React code.
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'public'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: 'babel-loader'
}
]
},
resolve: {
extensions: ['.js', '.jsx']
}
};
Run Webpack to generate the client-side bundle:
npx webpack --mode=production
6. Deploying the MERN SSR App
Step 7: Deploy to a Cloud Server
- Use Vercel or Netlify for frontend.
- Deploy Express backend on Render, DigitalOcean, or AWS.
Conclusion
Implementing SSR in a MERN stack app significantly improves performance, SEO, and user experience. By following these steps, you can ensure that your app loads faster and is indexed better by search engines.
Start integrating SSR today and take your MERN applications to the next level!