Package Exports
- react-ssr
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (react-ssr) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
react-ssr
Overview
react-ssr is a minimalistic solution to achieve server-side rendering with a few lines of code and a simple ruleset. The simple ruleset is outlined with performance in mind, and must be followed to server side render React apps effectively. It supports React Router 4, which introduced challenges to server-side rendering by making you have to declare data calls at a route level. react-ssr allows you to make those calls where-ever you want.
Installation
$ npm install react-ssr --save
$ npm install babel-plugin-react-ssr --save-devAdd the babel plugin to your .babelrc. This is currently required.
{
"plugins": [
"react-ssr"
]
}Adding to your server
Firstly, you'll need to use the module on your Node server and have some static routes of your app setup. The below example uses express:
- Your Node JS express server
server.js
import express from 'express'
import ssr from 'react-ssr'
import routes from './routes'
const app = express()
const renderer = ssr({ routes })
app.get('*', renderer) // send all routes to ssr- Static routes of your React app
routes.js
import HomePage from './HomePage'
import NotFoundPage from './NotFoundPage'
const routes = [
{
path: '/',
exact: true,
component: HomePage
},
{
path: '/about',
redirect: '/'
},
{
path: '**',
component: NotFoundPage
}
]
export default routesFetching data
There's one important rule: If you want to make a data call, and you'd like it to be server side rendered correctly, you'll need to use a special method for this. It's a static method that sits in your React component called fetchData. react-ssr will execute this before it begins rendering your app on the server and inject the result of it into the components props.
Here's an example:
class Navigation extends React.Component {
static fetchData () {
const pageContent = new Promise((resolve, reject) => {
fetch('/api')
.then(res => res.json())
.then(resolve)
.catch(reject)
})
return {
content: pageContent // becomes available as this.props.content
}
}
render () {
console.log(this.props.content)
return <span />
}🏆 You should now have server-side rendering setup. There's still a few extra things to think about to make this work for more advanced applications. Continue reading to find out more.
Some caveats and notes
At the moment there are a few caveats you'll need to consider for server side rendering with these static methods. Some of them will have to remain, whereas others will slowly be improved in future releases.
- You can't access
thisinside your staticfetchData. This means you cannot accessthis.props, so no props-driven data call here. If you want to achieve this, you'll need to chain api calls together in a parent container, wrapped in one promise, then pass the result into the child component as standard props. - You can access
paramsinside your staticfetchData. The params of your React route are available as an argument to the method.static fetchData (params) {} - You must return an object with keys in your static
fetchData. This API won't be finalised until the first major release. - You must use static routes of your app currently. You might be able to define them how you want in future releases.
- The static
fetchDatamethods will only work on React components that are classes currently. Functional components are not yet supported. - You have to use Babel so the plugin can work some magic. This might not be required in the future. If it still is, we'll consider adding Typescript transformers and any other alternative requirements.
- Components not directly defined in the
rendermethod might not server side render yet. This is changing in an immediate minor release to follow - won't be long! - Components that are dynamically rendered with static
fetchDatawill not be server-side rendered. So, if you're programatically doing something like this, it won't server-side render, but instead show a loading spinner and client-side render:
const DynamicComponent = components['MyComponent']
return <DynamicComponent />The documentation for this solution is still actively under writing. Further info with accompanying diagrams to visualise the approach to server-side rendering will follow soon.
Not what you were expecting?
This package has recently changed from a previous solution by akiran. You can find his work here: https://github.com/akiran/react-ssr