UNPKG

3.2 kBJavaScriptView Raw
1import React from "react"
2import { renderToStaticMarkup } from "react-dom/server"
3import { merge } from "lodash"
4import apiRunner from "./api-runner-ssr"
5// import testRequireError from "./test-require-error"
6// For some extremely mysterious reason, webpack adds the above module *after*
7// this module so that when this code runs, testRequireError is undefined.
8// So in the meantime, we'll just inline it.
9const testRequireError = (moduleName, err) => {
10 const regex = new RegExp(`Error: Cannot find module\\s.${moduleName}`)
11 const firstLine = err.toString().split(`\n`)[0]
12 return regex.test(firstLine)
13}
14
15let Html
16try {
17 Html = require(`../src/html`)
18} catch (err) {
19 if (testRequireError(`../src/html`, err)) {
20 Html = require(`./default-html`)
21 } else {
22 console.log(`There was an error requiring "src/html.js"\n\n`, err, `\n\n`)
23 process.exit()
24 }
25}
26
27Html = Html && Html.__esModule ? Html.default : Html
28
29export default (pagePath, callback) => {
30 let headComponents = [
31 <meta key="environment" name="note" content="environment=development" />,
32 ]
33 let htmlAttributes = {}
34 let bodyAttributes = {}
35 let preBodyComponents = []
36 let postBodyComponents = []
37 let bodyProps = {}
38 let htmlStr
39
40 const setHeadComponents = components => {
41 headComponents = headComponents.concat(components)
42 }
43
44 const setHtmlAttributes = attributes => {
45 htmlAttributes = merge(htmlAttributes, attributes)
46 }
47
48 const setBodyAttributes = attributes => {
49 bodyAttributes = merge(bodyAttributes, attributes)
50 }
51
52 const setPreBodyComponents = components => {
53 preBodyComponents = preBodyComponents.concat(components)
54 }
55
56 const setPostBodyComponents = components => {
57 postBodyComponents = postBodyComponents.concat(components)
58 }
59
60 const setBodyProps = props => {
61 bodyProps = merge({}, bodyProps, props)
62 }
63
64 const getHeadComponents = () => headComponents
65
66 const replaceHeadComponents = components => {
67 headComponents = components
68 }
69
70 const getPreBodyComponents = () => preBodyComponents
71
72 const replacePreBodyComponents = components => {
73 preBodyComponents = components
74 }
75
76 const getPostBodyComponents = () => postBodyComponents
77
78 const replacePostBodyComponents = components => {
79 postBodyComponents = components
80 }
81
82 apiRunner(`onRenderBody`, {
83 setHeadComponents,
84 setHtmlAttributes,
85 setBodyAttributes,
86 setPreBodyComponents,
87 setPostBodyComponents,
88 setBodyProps,
89 pathname: pagePath,
90 })
91
92 apiRunner(`onPreRenderHTML`, {
93 getHeadComponents,
94 replaceHeadComponents,
95 getPreBodyComponents,
96 replacePreBodyComponents,
97 getPostBodyComponents,
98 replacePostBodyComponents,
99 pathname: pagePath,
100 })
101
102 const htmlElement = React.createElement(Html, {
103 ...bodyProps,
104 body: ``,
105 headComponents: headComponents.concat([
106 <script key={`io`} src="/socket.io/socket.io.js" />,
107 ]),
108 htmlAttributes,
109 bodyAttributes,
110 preBodyComponents,
111 postBodyComponents: postBodyComponents.concat([
112 <script key={`commons`} src="/commons.js" />,
113 ]),
114 })
115 htmlStr = renderToStaticMarkup(htmlElement)
116 htmlStr = `<!DOCTYPE html>${htmlStr}`
117
118 callback(null, htmlStr)
119}