Created
August 18, 2017 12:39
-
-
Save selbekk/d9b5807bb4b967813f963039ae9fcde0 to your computer and use it in GitHub Desktop.
Super simple server side rendering with React and styled-components
This file contains hidden or 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
const express = require('express'); | |
require('babel-register')({ | |
ignore: /\/(build|node_modules|.svg)\//, | |
presets: ['env', 'react-app'] | |
}); | |
const universal = require('./universal'); | |
const app = express(); | |
app.set('port', process.env.PORT || 8080); | |
// TODO: Add middlewares for logging, gzip compression etc here | |
// Handle index route as universal | |
app.get('/', universal); | |
app.get('/index.html', (req, res) => res.redirect('/')); | |
// Serve static files from the build/ folder | |
app.use(express.static('build')); | |
// Handle all other requests through React | |
app.get('*', universal); | |
// Start the application | |
app.listen(app.get('port'), () => console.log(`Server is running at port ${app.get('port')}`)); |
This file contains hidden or 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
const path = require('path'); | |
const fs = require('fs'); | |
const React = require('react'); | |
const { renderToString } = require('react-dom/server'); | |
const { StaticRouter } = require('react-router-dom'); | |
const { ServerStyleSheet } = require('styled-components'); | |
// This is your main App component, shared between front-end and back-end | |
const { default: App } = require('../src/containers/App'); | |
// Read the index html template on start. | |
const indexFile = fs.readFileSync(path.resolve(__dirname, '..', 'build', 'index.html'), 'utf8'); | |
// HACK: Need to set these to make sure they are set (yet undefined). | |
global.window = undefined; | |
global.document = undefined; | |
module.exports = function universalLoader(req, res) { | |
const css = new ServerStyleSheet(); | |
const context = {}; | |
// Create the markup from the React application | |
const markup = renderToString( | |
css.collectStyles( | |
<StaticRouter context={context} location={req.url}> | |
<App /> | |
</StaticRouter> | |
) | |
); | |
// If a redirect was rendered - redirect to the correct URL | |
if (context.url) { | |
return res.redirect(context.url); | |
} | |
// Hydrate the HTML template with both React DOM and styled-components styles | |
// The HTML file has placeholders for both the markup and the style tags | |
const html = indexFile | |
.replace('{{SSR}}', markup) | |
.replace('{{CSS}}', css.getStyleTags()); | |
// Send the response back to the user | |
res.send(html); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment