Skip to content

Instantly share code, notes, and snippets.

@kettanaito
Last active April 21, 2023 22:16
Show Gist options
  • Save kettanaito/5eaf8a1931e38fc43cbb484b2f55cd86 to your computer and use it in GitHub Desktop.
Save kettanaito/5eaf8a1931e38fc43cbb484b2f55cd86 to your computer and use it in GitHub Desktop.
React - SSR (Server-side rendering)
// Root of the actual application.
// Feel free to branch from here, create routes and any other things
// rendered on both browser and server.
//
// Don't use modules relying on "window" here, as it would throw on the serfver.
// If using any such logic, move it to "client-index" instead, as its being rendered
// in the browser only.
import React from 'react'
const App = () => (
<h1>My first server-side rendered app!</h1>
)
export default App
// Root file for the application.
// This is the wrapper that provides client-side context (state, routing)
// and renders the actual application.
import React from 'react'
import { hydrate } from 'react-dom'
import { BrowserRouter } from 'react-router-dom'
import App from './App'
// Hydrate the server-side rendered markup.
// You may want to do this conditionally depending on your HMR setup to prevent
// nodes mismatch during hydration from hot reloaded chunks.
//
// const mount = module.hot ? ReactDOM.render : ReactDOM.hydrate
// mount(...)
hydrate(
// Note how we specify providers around the <App/>.
// These ones are client-specific, as server side must have its own routing or state providers.
// In other words, tree wrapping the <App/> is supposed to be declared separately on client and server.
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
)
// Simple express server example that renders our application.
import React from 'react'
import { renderToStaticMarkup, renderToString } from 'react-dom/server'
import express from 'express'
import { StaticRouter } from 'react-router'
import App from '../client-App'
const getHtml = (clientHtml) => {
const Page = (
<html>
<head>
{/* Hydrate head via "react-helmet", or manually */}
{/* Flush critical CSS from the React components tree */}
</head>
<body>
<div id="root" dangerouslySetInnerHTML={{ __html: clientHtml }} />
{/* Include JS file(s), or flushed chunks if using SSR+Code splitting */}
<script src="lib/index.js"></script>
</body>
</html>
)
return renderToStaticMarkup(Page)
}
const app = express()
// Basic middleware to server-side render the application
app.get('*', (req, res) => {
const ComponentsTree = (
// Basic example of server-side routing setup
<StaticRouter url={req.url}>
<App />
</StaticRouter>
)
const html = getHtml(renderToString(ComponentsTree))
res.send(`<!DOCTYPE>${html}`)
})
app.listen(8080)
@kettanaito
Copy link
Author

Basic example of server-side rendering using React on both client and server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment