Now this was a pretty frustrating problem that cost me at least 3 days of debugging, investigation and trial/error testing. But basically, this was due to none of the routes matching on the server. Funny thing is that the route did match when running in the browser and it rendered just fine. And just for the record, I’m using Babel 6, React-Router, Redux, and Redux-Simple-Router which is probably why you’re reading this. So I spent a lot of time debugging this code which I got from the examples:
import { renderToString } from 'react-dom/server'
import { match, RouterContext } from 'react-router'
import routes from './routes'
serve((req, res) => {
// Note that req.url here should be the full URL path from
// the original request, including the query string.
match({ routes, location: req.url }, (error, redirectLocation, renderProps) => {
if (error) {
res.status(500).send(error.message)
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search)
} else if (renderProps) {
// You can also check renderProps.components or renderProps.routes for
// your "not found" component or route respectively, and send a 404 as
// below, if you're using a catch-all route.
res.status(200).send(renderToString(<RouterContext {...renderProps} />))
} else {
res.status(404).send('Not found')
}
})
})
Stepping through the code above, renderProps was always undefined. Running other samples, I saw that renderProps should contain the route that will be rendered. So for whatever reason, the URL wasn’t wasn’t matching any of the routes specified. So the reason the routes weren’t matching on the server is because my routes were being included like this:
var routes = "./routes"
And here is how I defined the routes:
module.exports = () => {
var routes = (
<Route path={ baseUri } component={ Container }>
<IndexRoute component={ Home } />
<Route path='*' component={ NotFound } />
</Route>
)
return routes
}
And again, this setup works perfectly fine when running in the browser. After some trial and error, I decided to try copying the syntax from the example and changed my routes definition to:
export default (
<Route path="/" component={ Container }>
<IndexRoute component={ Home } />
<Route path="*" component={ NotFound } />
</Route>
)
And guess what, it worked. I’m not sure if I know why it worked, but for whatever reason, this was the missing piece of the puzzle that got server-side rendering to work. My renderProps was no longer undefined and everything was rendering correctly.
And that’s all folks, hope this helps someone.