var express = require('express'); var path = require('path'); var compression = require('compression'); import React from 'react'; import { renderToString } from 'react-dom/server'; import { match, RouterContext } from 'react-router'; import routes from './modules/routes'; var app = express(); app.use(compression()); // serve our static stuff like index.css app.use(express.static(path.join(__dirname, 'public'))); // Send all requests to index.html so browserHistory in React Router works app.get('*', (req, res) => { match({ routes, location: req.url }, (err, redirect, props) => { console.log(`SSR for ${req.url}`); // in here we can make some decisions all at once if (err) { // there was an error somewhere during route matching res.status(500).send(err.message); } else if (redirect) { // we haven't talked about `onEnter` hooks on routes, but before a // route is entered, it can redirect. Here we handle on the server. res.redirect(redirect.pathname + redirect.search); } else if (props) { // if we got props then we matched a route and can render // `RouterContext is what the `Router` renders. `Router` keeps these `props` // in its state as it listens to `browserHistory`. But on the server, our // app is stateless, so we need to use `match` to get these props before // rendering. const appHtml = renderToString(); // Dump the HTML into a template, lots of ways to do this, but none are // really influenced by React Router, so we're just using a little function, // `renderPage`. res.send(renderPage(appHtml)); } else { // no errors, no redirect, we just didn't match anything res.status(404).send("Not found"); } }); }); function renderPage(appHtml) { return ` My first React Router App
${appHtml}
`; } var PORT = process.env.PORT || 8080; app.listen(PORT, function () { console.log('"Production" Express server running at localhost:' + PORT); });