Skip to content

Instantly share code, notes, and snippets.

@tkh44
Forked from btholt/ClientApp.jsx
Created March 6, 2016 23:26
Show Gist options
  • Save tkh44/96059cfadfe7eac20e96 to your computer and use it in GitHub Desktop.
Save tkh44/96059cfadfe7eac20e96 to your computer and use it in GitHub Desktop.
react-router server-side rendering
require("babel-register")
var express = require('express')
var React = require('react')
var ReactDOMServer = require('react-dom/server')
var ReactRouter = require('react-router')
var match = ReactRouter.match
var RouterContext = ReactRouter.RouterContext
var _ = require('lodash')
var fs = require('fs')
var port = 5050
var baseTemplate = fs.readFileSync('./index.html')
var ClientApp = require('./js/ClientApp.jsx')
var routes = ClientApp.Routes
var app = express()
app.use('/public', express.static('./public'))
app.use((req, res) => {
// Note that req.url here should be the full URL path from
// the original request, including the query string.
match({ routes: ReactRouter.createRoutes(routes), location: req.url }, (error, redirectLocation, renderProps) => {
console.log(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(ReactDOMServer.renderToString(React.createElement(RouterContext,renderProps)))
} else {
res.status(404).send('Not found')
}
})
});
console.log('listening on ' + port)
app.listen(port)
const React = require('react')
const Landing = require('./Landing')
const Search = require('./Search')
const Layout = require('./Layout')
const Details = require('./Details')
const ReactRouter = require('react-router')
const data = require('../public/data')
const { Router, Route, hashHistory, IndexRoute } = ReactRouter
const Store = require('./Store')
const { store } = Store
const reactRedux = require('react-redux')
const { Provider } = reactRedux
const shows = data.shows || []
const MyRoutes = (props) => (
<Route path='/' component={Layout}>
<IndexRoute component={Landing} />
<Route path='/search' component={Search} shows={shows} />
<Route path='/details/:id' component={Details} onEnter={props.assignShow} />
</Route>
)
class App extends React.Component {
constructor (props) {
super(props)
this.assignShow = this.assignShow.bind(this)
}
assignShow (nextState, replace) {
const show = data.shows[nextState.params.id]
if (!show) {
return replace('/')
}
Object.assign(nextState.params, show)
return nextState
}
render () {
return (
<Provider store={store}>
<Router history={hashHistory}>
<MyRoutes assignShow={this.assignShow} />
</Router>
</Provider>
)
}
}
App.Routes = MyRoutes
module.exports = App
{
"name": "complete-intro-to-react",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack",
"watch": "webpack --watch",
"test": "mocha --require test/helpers/setup.js",
"lint": "eslint --ignore-path .gitignore --cache ./",
"cover": "nyc --reporter=lcov --reporter=text --reporter=html --require babel-register --extension .jsx npm test"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "4.13.4",
"lodash": "4.6.1",
"react": "^0.14.7",
"react-dom": "^0.14.7",
"react-redux": "^4.4.0",
"react-router": "^2.0.0",
"redux": "^3.3.1"
},
"devDependencies": {
"babel-core": "^6.5.2",
"babel-loader": "^6.2.2",
"babel-preset-es2015": "^6.5.0",
"babel-preset-react": "^6.5.0",
"babel-register": "^6.5.2",
"chai": "^3.5.0",
"enzyme": "^2.0.0",
"eslint": "^2.2.0",
"eslint-config-standard": "^5.1.0",
"eslint-config-standard-jsx": "^1.1.1",
"eslint-config-standard-react": "^2.3.0",
"eslint-loader": "^1.3.0",
"eslint-plugin-promise": "^1.0.8",
"eslint-plugin-react": "^4.1.0",
"eslint-plugin-standard": "^1.3.2",
"jsdom": "^8.0.4",
"json-loader": "^0.5.4",
"mocha": "^2.4.5",
"nyc": "^6.0.0",
"react-addons-test-utils": "^0.14.7",
"sinon": "^1.17.3",
"webpack": "^1.12.13"
}
}
require("babel-register")
var express = require('express')
var React = require('react')
var ReactDOMServer = require('react-dom/server')
var ReactRouter = require('react-router')
var match = ReactRouter.match
var RouterContext = ReactRouter.RouterContext
var ReactRedux = require('react-redux')
var Provider = ReactRedux.Provider
var Layout = require('./js/Layout.jsx')
var Store = require('./js/Store.jsx')
var store = Store.store
var _ = require('lodash')
var fs = require('fs')
var port = 5050
var baseTemplate = fs.readFileSync('./index.html')
var template = _.template(baseTemplate)
var ClientApp = require('./js/ClientApp.jsx')
var routes = ClientApp.Routes
var app = express()
app.use('/public', express.static('./public'))
app.use((req, res) => {
// Note that req.url here should be the full URL path from
// the original request, including the query string.
match({ routes: routes, location: req.url }, (error, redirectLocation, renderProps) => {
console.log(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.
var body = ReactDOMServer.renderToString(
React.createElement(Provider,{store},
React.createElement(Layout, {},
React.createElement(RouterContext,renderProps)
)
)
)
res.status(200).send(template({body}))
} else {
res.status(404).send('Not found')
}
})
});
console.log('listening on ' + port)
app.listen(port)
const React = require('react')
const Landing = require('./Landing')
const Search = require('./Search')
const Layout = require('./Layout')
const Details = require('./Details')
const ReactRouter = require('react-router')
const data = require('../public/data')
const { Router, Route, browserHistory, IndexRoute } = ReactRouter
const Store = require('./Store')
const { store } = Store
const reactRedux = require('react-redux')
const { Provider } = reactRedux
const shows = data.shows || []
const routes = [
<Route path='/' component={Landing} />,
<Route path='/search' component={Search} shows={shows} />,
<Route path='/details/:id' component={Details} />
]
class App extends React.Component {
constructor (props) {
super(props)
this.assignShow = this.assignShow.bind(this)
}
assignShow (nextState, replace) {
const show = data.shows[nextState.params.id]
if (!show) {
return replace('/')
}
Object.assign(nextState.params, show)
return nextState
}
render () {
return (
<Provider store={store}>
<Router history={browserHistory}>
<Route path='/' component={Layout}>
<IndexRoute component={Landing} />
<Route path='/search' component={Search} shows={shows} />
<Route path='/details/:id' component={Details} onEnter={this.assignShow} />
</Route>
</Router>
</Provider>
)
}
}
App.Routes = routes
module.exports = App
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment