Last active
April 21, 2023 22:16
-
-
Save kettanaito/5eaf8a1931e38fc43cbb484b2f55cd86 to your computer and use it in GitHub Desktop.
React - SSR (Server-side rendering)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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') | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Basic example of server-side rendering using React on both client and server.