Skip to content
This repository has been archived by the owner on Jan 1, 2024. It is now read-only.

Commit

Permalink
feat(ssr): render Helmet on server in <Root>
Browse files Browse the repository at this point in the history
  • Loading branch information
Metnew committed Feb 19, 2018
1 parent 3378ff6 commit 97808c5
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 26 deletions.
31 changes: 25 additions & 6 deletions src/common/components/Root/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import React, {Component} from 'react'
import {Provider} from 'react-redux'
import {IntlProvider, defineMessages, addLocaleData} from 'react-intl'
import Helmet from 'react-helmet'
import {APPLICATION_INIT} from 'actions/common'
import {ThemeProvider} from 'styled-components'
import theme from 'styles/theme'
Expand Down Expand Up @@ -48,21 +49,39 @@ class Root extends Component<Props> {
return null
}
const {SSR, store, history, i18n} = this.props
const routerProps = process.env.BROWSER
? {history}
: {location: SSR.location, context: SSR.context}
const routerProps = process.env.BROWSER ? {history} : {location: SSR.location, context: SSR.context}

return (
<IntlProvider
locale={i18n.locale}
messages={defineMessages(i18n.messages)}>
<IntlProvider locale={i18n.locale} messages={defineMessages(i18n.messages)}>
{/* key={Math.random()} = hack for HMR
From https://github.com/webpack/webpack-dev-server/issues/395
*/}
<Provider store={store} key={Date.now()}>
<ThemeProvider theme={theme}>
<Router {...routerProps}>
<App>
<Helmet>
<html lang={i18n.lang} />
<meta charSet="utf-8" />
<title>Suicrux</title>
<meta httpEquiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta
name="description"
content="Universal React starter with SSR/lazy-loading/i18n"
/>
<meta name="theme-color" content="#1b1e2f" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />

<meta name="msapplication-tap-highlight" content="no" />
<link rel="manifest" href="manifest.json" />
<noscript
dangerouslySetInnerHTML={{
__html: `You are using outdated browser. You can install modern browser here:
<a href="http://outdatedbrowser.com/">http://outdatedbrowser.com</a>.`
}}
/>
</Helmet>
<RoutingWrapper />
</App>
</Router>
Expand Down
38 changes: 18 additions & 20 deletions src/server/ssr/HTMLComponent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,29 @@
import serealize from 'serialize-javascript'
import _ from 'lodash'
type args = {
// rendered to string application
app: string,
// Styled components' styles
css: string,
// react-async-component state
asyncState: Object,
// react-helmet
helmet: Object,
// redux preloaded state
initialState: Object,
// client assets manifest
assets: Object,
// prop for react-intl
i18n: Object
}

const HTMLComponent = ({css, asyncState, initialState, assets, i18n, app}: args) => {
const HTMLComponent = ({css, asyncState, initialState, assets, i18n, app, helmet}: args) => {
const stringifiedAsyncState: string = serealize(asyncState)
const stringifiedState: string = serealize(initialState)
const stringifiedI18N: string = serealize(i18n)
const wrapFuncs = {
css: ({path}) => `<link rel="stylesheet" href="${path}" />`,
js: ({path}) =>
`<script src="${path}" type="text/javascript"></script>`
js: ({path}) => `<script src="${path}" type="text/javascript"></script>`
}
const assetsOrdered = ['manifest', 'polyfills', 'vendor', 'client']
const getTags = assets => funcs => ext => {
Expand All @@ -36,31 +43,22 @@ const HTMLComponent = ({css, asyncState, initialState, assets, i18n, app}: args)
const cssTags = getTagsFromAssets('css')
const jsTags = getTagsFromAssets('js')

return `<html lang="${i18n.lang}">
return `<html ${helmet.htmlAttributes.toString()}>
<head>
<meta charset="utf-8" />
<title>Suicrux</title>
<meta httpEquiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta
name="description"
content="Universal React starter based on Razzle. SSR/lazy-loading/i18n"
/>
<meta name="theme-color" content="#1b1e2f"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<meta name="msapplication-tap-highlight" content="no" />
<link rel="manifest" href="manifest.json" />
${helmet.title.toString()}
${helmet.meta.toString()}
${helmet.base.toString()}
${helmet.link.toString()}
${helmet.noscript.toString()}
${css}
${cssTags}
<head>
<body>
<script>window.__ASYNC_STATE__ = ${stringifiedAsyncState}</script>
<script>window.__INITIAL_STATE__ = ${stringifiedState}</script>
<script>window.__I18N__ = ${stringifiedI18N}</script>
<noscript>
You are using outdated browser. You can install modern browser here:
<a href="http://outdatedbrowser.com/">http://outdatedbrowser.com</a>.
</noscript>
<div id="app">${app}</div>
${jsTags}
</body>
Expand Down

0 comments on commit 97808c5

Please sign in to comment.