DEV Community

Cover image for React Server-Side Rendering without Next.js
OpenSource for Webcrumbs

Posted on • Edited on

React Server-Side Rendering without Next.js

GitHub Repo: https://github.com/webcrumbs-community/webcrumbs

We have been running a series of experiments for WebCrumbs where we explore Server-Side Rendering (SSR) of React Components.

Turns out it is not that hard.

All you'll need is a bit of express with ReactDOMServer.renderToString and ReactDOM.hydrate with Webpack, to keep it simple.

Here's an example. It can get more complicated, sure, but you'll get the idea.


Support us! 🙏⭐️

By the way, I'm part of the WebCrumbs team, and it would mean a lot if you could check out our no-code solution for Node.js that simplifies web development. Giving us a star would be fantastic.

We're putting in a ton of effort to help devs take their ideas to a live website as quickly and easily as possible (think: effortless plugin and theme integration), and every bit of support is truly appreciated!

⭐️ Give WebCrumbs a Star! ⭐️

Ok. Now, let's dive back into the practicalities of using React Server-Side rendering without Next.js.


🫵 Okay. Cut to the chase. How do I do it?

To create a simple React Server-Side Rendering (SSR) application with client-side hydration, you'll need to follow several steps.

This involves setting up a Node.js server with Express, creating a React component, rendering it server-side, and then hydrating it on the client-side.

Here's a step-by-step guide:

Step 1: Set Up Your Project

Create a New Directory: Create a new directory for your project and navigate into it.



mkdir react-ssr-demo
cd react-ssr-demo


Enter fullscreen mode Exit fullscreen mode

Initialize npm: Initialize a new npm project.



npm init -y


Enter fullscreen mode Exit fullscreen mode

Install Dependencies: Install Express and React-related packages.



npm install express react react-dom


Enter fullscreen mode Exit fullscreen mode

Step 2: Create the Server

Write the Server Code: Create a file server.js and write the following code:



const express = require('express');
const ReactDOMServer = require('react-dom/server');
const React = require('react');
const SampleComponent = require('./SampleComponent'); // Replace with your component

const app = express();

app.use(express.static('public'));

app.get('/', (req, res) => {
    const componentStr = ReactDOMServer.renderToString(React.createElement(SampleComponent));

    res.send(`
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>React SSR with Client-Side Hydration</title>
    </head>
    <body>
      <div id="root">${componentStr}</div>
      <script src="/bundled-client.js"></script>
    </body>
    </html>
  `);
});

const PORT = 3000;
app.listen(PORT, () => {
    console.log(`Server is running on http://localhost:${PORT}/`);
});


Enter fullscreen mode Exit fullscreen mode

Here's the explanation of the code above:

  • Loads Express, React, ReactDOMServer.
  • Defines a basic React component for rendering.
  • Initializes an Express server.
  • Creates a route to handle HTTP GET requests to the root ('/') URL.
  • Converts the React component into an HTML string using ReactDOMServer.
  • Includes a script in the HTML for hydrating the server-rendered component on the client side.
  • Listens for requests on port 3000 and logs a startup message.

Step 3: Configure Webpack for Client-Side Code

Create Webpack Configuration: Create a webpack.config.js file in your project root.



const path = require('path');

module.exports = {
  entry: './client.js',
  output: {
    path: path.resolve(__dirname, 'public'),
    filename: 'bundled-client.js'
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react']
          }
        }
      }
    ]
  }
};


Enter fullscreen mode Exit fullscreen mode

Create hydration logic: In your project, create a new file named client.js:



import React from 'react';
import ReactDOM from 'react-dom';
import SampleComponent from './SampleComponent'; // Replace with your component

ReactDOM.hydrate(
  <SampleComponent />,
  document.getElementById('root')
);


Enter fullscreen mode Exit fullscreen mode

Compile with Webpack: Create the bundled-client.js by running this command:



npx webpack --mode production


Enter fullscreen mode Exit fullscreen mode

Step 4: Running the Server

Start the Server: Run your server using Node.



node server.js


Enter fullscreen mode Exit fullscreen mode

Open Your Browser: Go to http://localhost:3000 to see your server-rendered React component.

🫵 Alright! Is that it?

This guide is for educational purposes and demonstrates the basic concepts of SSR with React and hydration. For complex applications, a more sophisticated setup is recommended.

We're using SSR in WebCrumbs!


Follow me for more!
I usually write about JavaScript, WebDev and Webcrumbs ❤️.

Top comments (6)

Collapse
 
brense profile image
Rense Bakker • Edited

To be clear, this solution does not support React server components, it only supports server side rendering, which is not the same. To support React server components (RSC), you have to do a lot more. Server components are quite different from server-side rendering, for example, SSR doesn't reduce the bundle size and requires client hydration. RSC do reduce bundle size and thus are static and not hydrated on the client. patterns.dev/react/react-server-co...

Collapse
 
opensourcee profile image
OpenSource

Yes, thanks for clarifying it!

Collapse
 
opensourcee profile image
OpenSource

I think it's beautiful!

Collapse
 
jsimple profile image
JSimple

Agree! Thanks for this

Collapse
 
lurco profile image
Andrzej Legutko

I've seen you post a lot of content (and about open source as well!) on here, so I don't want to be too antagonistic, but be honest here - this entire article was written by ChatGPT, wasn't it? Again, I've seen your other articles which seem like real, legit work and content. But copy pasting ChatGPT response to a basic prompt really shouldn't disguise itself as an article...

Collapse
 
sodd_store_1051 profile image
SODD STORE

Thank you

Some comments have been hidden by the post's author - find out more