Skip to content

Instantly share code, notes, and snippets.

@Arfey
Created December 22, 2016 22:51
Show Gist options
  • Save Arfey/034788170a8f408d6d84a1cec39b44f9 to your computer and use it in GitHub Desktop.
Save Arfey/034788170a8f408d6d84a1cec39b44f9 to your computer and use it in GitHub Desktop.
import 'babel-polyfill';
import path from 'path';
import express from 'express';
import cookieParser from 'cookie-parser';
import bodyParser from 'body-parser';
import React from 'react';
import ReactDOM from 'react-dom/server';
import { match, RouterContext } from 'react-router';
import { Provider } from 'react-redux';
import PrettyError from 'pretty-error';
import Helmet from 'react-helmet';
import { state } from './store/state';
//locals
import i18n from './utils/i18n';
import ru from './public/lang/ru.json';
import en from './public/lang/en.json';
import he from './public/lang/he.json';
var language = {
ru,
en,
he
};
const i18nToolsRegistry = {
ru : new i18n.Tools({ localeData: ru, locale: 'ru' }),
en : new i18n.Tools({ localeData: en, locale: 'en' }),
he : new i18n.Tools({ localeData: he, locale: 'he' }),
};
import { Html, ContextHolder, App } from './components';
import { Error as ErrorPageWithoutStyle } from './containers';
import errorPageStyle from './containers/Error/Error.scss';
import routes from './routes';
import fetchComponentsData from './utils/fetchComponentsData';
import assets from './assets';
import configureStore from './store/configureStore';
import { setRuntimeVariable } from './utils/modules/runtime';
const app = express();
global.navigator = global.navigator || {};
global.navigator.userAgent = global.navigator.userAgent || 'all';
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.get('*', async (req, res, next) => {
try {
const store = configureStore(state, {
cookie: req.headers.cookie,
});
store.dispatch(setRuntimeVariable({
name: 'initialNow',
value: Date.now(),
}));
const css = new Set();
const location = req.url;
const context = {
insertCss: (...styles) => {
styles.forEach(style => css.add(style._getCss()));
},
store,
};
match({ routes: routes(store), location }, (error, redirectLocation, renderProps) => {
if (error) {
return next(error);
} else if (redirectLocation) {
return res.redirect(redirectLocation.pathname + redirectLocation.search, '/');
} else if (renderProps) {
fetchComponentsData(
store.dispatch,
renderProps.components,
renderProps.location.query,
renderProps.params,
)
.then(() => {
const helmet = Helmet.rewind();
const i18nTools = i18nToolsRegistry[renderProps.params.prefix];
const headComponents = Object.values(helmet)
.reduce((acc, property) => [...acc, property.toComponent()], [])
.filter(array => array.length)
.reduce((acc, array) => [...acc, ...array]);
const content = ReactDOM.renderToString(
<Provider store={store}>
<ContextHolder context={context}>
<App>
<i18n.Provider i18n={i18nTools}>
<RouterContext {...renderProps} />
</i18n.Provider>
</App>
</ContextHolder>
</Provider>
);
const data = {
style: [...css].join(''),
script: assets.main.js,
state: context.store.getState(),
head: headComponents,
i18nTools: {
localeData: language[renderProps.params.prefix],
locale: renderProps.params.prefix,
},
};
const html = ReactDOM.renderToStaticMarkup(
<Html {...data}>
{ content }
</Html>
);
return html
})
.then(html => {
// res.cookie('locale', locale, { maxAge: 900000 });
res.status(200).send(`<!DOCTYPE html>\n${html}`);
})
.catch(err => {
console.log(err.stack);
res.end(err.message);
});
}
});
} catch (err) {
next(err);
}
});
const pe = new PrettyError();
pe.skipNodeFiles();
pe.skipPackage('express');
app.use((err, req, res, next) => {
console.log(pe.render(err));
const html = ReactDOM.renderToStaticMarkup(
<Html
title="Internal Server Error"
description={err.message}
style={errorPageStyle._getCss()}
>
{ReactDOM.renderToString(<ErrorPageWithoutStyle error={err} />)}
</Html>
);
res.status(err.status || 500);
res.send(`<!doctype html>${html}`);
});
app.listen(3000, () => {
console.log(`The server is running at http://localhost:${3000}/`);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment