React SSR

Server-Side Rendering (SSR) in React involves rendering React components on the server and sending the HTML to the client. Instead of the browser handling the rendering, the server generates the final HTML markup and sends it to the client. This approach offers several benefits, including faster initial load times, improved SEO, and a better user experience, especially on slower connections.

Set up a server

We are going to start this tutorial by setting up a web server.

const app = express()
app.get('/', (req, res) => {
res.setHeader('content-type', 'text/html')
res.send('

This will be an SSR React component soon...

'
)
})
app.listen(3000, () => {
console.log('Running on http://localhost:3000')
})

This is a guide to creating a React framework with server-side rendering.

|- server
| |- tsconfig.json
| |- package.json
|- client
| |- tsconfig.json
| |- package.json

Dependencies

Tried to minimize dependencies to the point where the solution is still easy to follow, but isn't too far abstracted away.

Step 1: Compile TSX files

We've decided to use React, so let's start with a function that transpiles a target TSX file to an output directory.

Now we can write an App.tsx file and transpile it manually.

Calling compileComponent from the script earlier.

Loading TypeScript...

This will transpile to the following ES module.

Loading JavaScript...

Execute a JSX function

Executing the function should give us a React element. This would be simple if we're in the same directory as client, but our general-purpose framework needs to work on client applications in any arbitrary user directory.

Let's create some functions to execute an arbitrary JS file and maintain module resolution (i.e. the calls to require), while passing the same reference to React as the server library.

It's very important to use the same React reference.

Create a server

Create express server and check that it works

Output React from server

Update app.get to use renderString from react-dom

Pause - already many applications in mind

  • anything that needs to spit out HTML, e.g. email templates
  • static site renderer

Include a component

In App.tsx include the Counter.tsx file

Using require with vm

Update require to a sythenticRequire function

Webpack for client bundle

Use Webpack to generate client bundle

Update server

Update server to serve webpack build directory, and update HTML to include script

Call hydrateRoot

Add a listener to hydrate the root when the content has loaded

Recursively compile component directory

Let's implement a function which compiles all TSX files in a directory, including nested paths.

Was this page helpful?