Created
July 21, 2015 06:16
-
-
Save grabbou/d4b2340fd4953e22f0d1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import DocumentTitle from 'react-document-title'; | |
import Html from './html.react'; | |
import Promise from 'bluebird'; | |
import React from 'react'; | |
import Router from 'react-router'; | |
import config from '../config'; | |
import immutable from 'immutable'; | |
import initialState from '../initialstate'; | |
import routes from '../../client/routes'; | |
import stateMerger from '../lib/merger'; | |
export default function render(req, res, ...customStates) { | |
const appState = immutable.fromJS(initialState).mergeWith(stateMerger, ...customStates).toJS(); | |
return renderPage(req, res, appState); | |
} | |
function renderPage(req, res, appState) { | |
return new Promise((resolve, reject) => { | |
const router = Router.create({ | |
routes, | |
location: req.originalUrl, | |
onError: reject, | |
onAbort: (abortReason) => { | |
// Some requireAuth higher order component requested redirect. | |
if (abortReason.constructor.name === 'Redirect') { | |
const {to, params, query} = abortReason; | |
const path = router.makePath(to, params, query); | |
res.redirect(path); | |
resolve(); | |
return; | |
} | |
reject(abortReason); | |
} | |
}); | |
router.run((Handler, routerState) => { | |
const html = getPageHtml(Handler, appState, {hostname: req.hostname}); //options parameter | |
const notFound = routerState.routes.some(route => route.name === 'not-found'); | |
const status = notFound ? 404 : 200; | |
res.status(status).send(html); | |
resolve(); | |
}); | |
}); | |
} | |
function getPageHtml(Handler, appState, {hostname}) { | |
const appHtml = `<div id="app">${ | |
React.renderToString(<Handler initialState={appState} />) | |
}</div>`; | |
const appScriptSrc = config.isProduction | |
? '/build/app.js?v=' + config.version | |
: `//${hostname}/build/app.js`; // render hostname here | |
let scriptHtml = ` | |
<script> | |
(function() { | |
window._appState = ${JSON.stringify(appState)}; | |
var app = document.createElement('script'); app.type = 'text/javascript'; app.async = true; | |
var src = '${appScriptSrc}'; | |
// IE<11 and Safari need Intl polyfill. | |
if (!window.Intl) src = src.replace('.js', 'intl.js'); | |
app.src = src; | |
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(app, s); | |
})(); | |
</script>`; | |
if (config.isProduction && config.googleAnalyticsId !== 'UA-XXXXXXX-X') | |
scriptHtml += ` | |
<script> | |
(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]= | |
function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date; | |
e=o.createElement(i);r=o.getElementsByTagName(i)[0]; | |
e.src='//www.google-analytics.com/analytics.js'; | |
r.parentNode.insertBefore(e,r)}(window,document,'script','ga')); | |
ga('create','${config.googleAnalyticsId}');ga('send','pageview'); | |
</script>`; | |
const title = DocumentTitle.rewind(); | |
return '<!DOCTYPE html>' + React.renderToStaticMarkup( | |
<Html | |
bodyHtml={appHtml + scriptHtml} | |
isProduction={config.isProduction} | |
title={title} | |
version={config.version} | |
/> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment