Skip to content
This repository was archived by the owner on Oct 26, 2018. It is now read-only.

Commit 87402ea

Browse files
committed
Add a SSR example.
1 parent 67aefaa commit 87402ea

File tree

8 files changed

+253
-0
lines changed

8 files changed

+253
-0
lines changed

examples/server/.babelrc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"presets": ["es2015", "react", "stage-1"],
3+
"plugins": [
4+
["babel-plugin-module-alias", [
5+
{ "src": "../../src", "expose": "react-router-redux" }
6+
]]
7+
]
8+
}

examples/server/client.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import 'babel-polyfill'
2+
3+
import React from 'react'
4+
import { render } from 'react-dom'
5+
6+
import { Provider } from 'react-redux'
7+
import { Router, browserHistory } from 'react-router'
8+
import { syncHistoryWithStore } from 'react-router-redux'
9+
10+
import { configureStore, DevTools } from './store'
11+
import routes from './routes'
12+
13+
const store = configureStore(browserHistory, window.__initialState__)
14+
const history = syncHistoryWithStore(browserHistory, store)
15+
16+
render(
17+
<Provider store={store}>
18+
<Router history={history} routes={routes} />
19+
</Provider>,
20+
document.getElementById('root')
21+
)
22+
23+
render(
24+
<Provider store={store}>
25+
<DevTools/>
26+
</Provider>,
27+
document.getElementById('devtools')
28+
)

examples/server/index.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>react-router-redux server rendering example</title>
5+
<meta charset="utf8"/>
6+
</head>
7+
<body>
8+
<div id="root"></div>
9+
<script src="/bundle.js"></script>
10+
</body>
11+
</html>

examples/server/package.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "rrr-server-example",
3+
"version": "0.0.0",
4+
"repository": "reactjs/react-router-redux",
5+
"license": "MIT",
6+
"dependencies": {
7+
"react": "^0.14.7",
8+
"react-dom": "^0.14.7",
9+
"react-redux": "^4.3.0",
10+
"react-router": "^2.0.0",
11+
"react-router-redux": "^3.0.0",
12+
"redux": "^3.2.1",
13+
"serialize-javascript": "^1.1.2"
14+
},
15+
"devDependencies": {
16+
"babel-cli": "^6.5.1",
17+
"babel-core": "^6.4.5",
18+
"babel-eslint": "^5.0.0-beta9",
19+
"babel-loader": "^6.2.2",
20+
"babel-plugin-module-alias": "^1.2.0",
21+
"babel-preset-es2015": "^6.3.13",
22+
"babel-preset-react": "^6.3.13",
23+
"babel-preset-stage-1": "^6.3.13",
24+
"babel-register": "^6.5.2",
25+
"eslint": "^1.10.3",
26+
"eslint-config-rackt": "^1.1.1",
27+
"eslint-plugin-react": "^3.16.1",
28+
"express": "^4.13.4",
29+
"redux-devtools": "^3.1.1",
30+
"redux-devtools-dock-monitor": "^1.0.1",
31+
"redux-devtools-log-monitor": "^1.0.4",
32+
"webpack": "^1.12.13",
33+
"webpack-dev-middleware": "^1.5.1"
34+
},
35+
"scripts": {
36+
"start": "babel-node server.js"
37+
}
38+
}

examples/server/routes.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import React from 'react'
2+
import { Route, IndexRoute, Link } from 'react-router'
3+
4+
const App = ({ children }) => (
5+
<div>
6+
<header>
7+
Links:
8+
{' '}
9+
<Link to="/">Home</Link>
10+
{' '}
11+
<Link to="/foo">Foo</Link>
12+
{' '}
13+
<Link to="/bar">Bar</Link>
14+
</header>
15+
{children}
16+
</div>
17+
)
18+
19+
const Home = () => (<div>Home!</div>)
20+
const Foo = () => (<div>Foo!</div>)
21+
const Bar = () => (<div>Bar!</div>)
22+
23+
const routes = (
24+
<Route path="/" component={App}>
25+
<IndexRoute component={Home}/>
26+
<Route path="foo" component={Foo}/>
27+
<Route path="bar" component={Bar}/>
28+
</Route>
29+
)
30+
31+
export default routes

examples/server/server.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*eslint-disable no-console */
2+
import express from 'express'
3+
import serialize from 'serialize-javascript'
4+
5+
import webpack from 'webpack'
6+
import webpackDevMiddleware from 'webpack-dev-middleware'
7+
import webpackConfig from './webpack.config'
8+
9+
import React from 'react'
10+
import { renderToString } from 'react-dom/server'
11+
import { Provider } from 'react-redux'
12+
import { createMemoryHistory, match, RouterContext } from 'react-router'
13+
import { syncHistoryWithStore } from '../../src'
14+
15+
import { configureStore } from './store'
16+
import routes from './routes'
17+
18+
const app = express()
19+
20+
app.use(webpackDevMiddleware(webpack(webpackConfig), {
21+
publicPath: '/__build__/',
22+
stats: {
23+
colors: true
24+
}
25+
}))
26+
27+
const HTML = ({ content, store }) => (
28+
<html>
29+
<body>
30+
<div id="root" dangerouslySetInnerHTML={{ __html: content }}/>
31+
<div id="devtools"/>
32+
<script dangerouslySetInnerHTML={{ __html: `window.__initialState__=${serialize(store.getState())};` }}/>
33+
<script src="/__build__/bundle.js"/>
34+
</body>
35+
</html>
36+
)
37+
38+
app.use(function (req, res) {
39+
const memoryHistory = createMemoryHistory(req.path)
40+
const store = configureStore(memoryHistory)
41+
const history = syncHistoryWithStore(memoryHistory, store)
42+
43+
match({ history, routes, location: req.url }, (error, redirectLocation, renderProps) => {
44+
if (error) {
45+
res.status(500).send(error.message)
46+
} else if (redirectLocation) {
47+
res.redirect(302, redirectLocation.pathname + redirectLocation.search)
48+
} else if (renderProps) {
49+
const content = renderToString(
50+
<Provider store={store}>
51+
<RouterContext {...renderProps}/>
52+
</Provider>
53+
)
54+
55+
res.send('<!doctype html>\n' + renderToString(<HTML content={content} store={store}/>))
56+
}
57+
})
58+
})
59+
60+
app.listen(8080, function () {
61+
console.log('Server listening on http://localhost:8080, Ctrl+C to stop')
62+
})

examples/server/store.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React from 'react'
2+
3+
import { createStore, combineReducers, compose, applyMiddleware } from 'redux'
4+
import { createDevTools } from 'redux-devtools'
5+
import LogMonitor from 'redux-devtools-log-monitor'
6+
import DockMonitor from 'redux-devtools-dock-monitor'
7+
8+
import { routerReducer, routerMiddleware } from 'react-router-redux'
9+
10+
export const DevTools = createDevTools(
11+
<DockMonitor toggleVisibilityKey="ctrl-h" changePositionKey="ctrl-q">
12+
<LogMonitor theme="tomorrow" preserveScrollTop={false} />
13+
</DockMonitor>
14+
)
15+
16+
export function configureStore(history, initialState) {
17+
const reducer = combineReducers({
18+
routing: routerReducer
19+
})
20+
21+
let devTools = []
22+
if (typeof document !== 'undefined') {
23+
devTools = [ DevTools.instrument() ]
24+
}
25+
26+
const store = createStore(
27+
reducer,
28+
initialState,
29+
compose(
30+
applyMiddleware(
31+
routerMiddleware(history)
32+
),
33+
...devTools
34+
)
35+
)
36+
37+
return store
38+
}

examples/server/webpack.config.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/* eslint-disable */
2+
const path = require('path')
3+
const webpack = require('webpack')
4+
5+
module.exports = {
6+
devtool: 'inline-source-map',
7+
entry: './client.js',
8+
output: {
9+
path: path.join(__dirname, 'dist'),
10+
filename: 'bundle.js',
11+
publicPath: '/__build__/'
12+
},
13+
module: {
14+
loaders: [{
15+
test: /\.js$/,
16+
loader: 'babel',
17+
exclude: /node_modules/,
18+
query: { plugins: [] }
19+
}]
20+
}
21+
}
22+
23+
24+
// This will make the redux-simpler-router module resolve to the
25+
// latest src instead of using it from npm. Remove this if running
26+
// outside of the source.
27+
var src = path.join(__dirname, '../../src')
28+
var fs = require('fs')
29+
if (fs.existsSync(src)) {
30+
// Use the latest src
31+
module.exports.resolve = { alias: { 'react-router-redux': src } }
32+
module.exports.module.loaders.push({
33+
test: /\.js$/,
34+
loaders: ['babel'],
35+
include: src
36+
});
37+
}

0 commit comments

Comments
 (0)