-
Notifications
You must be signed in to change notification settings - Fork 5
/
ssr-render.js
53 lines (46 loc) · 1.87 KB
/
ssr-render.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import { h } from "preact"; // eslint-disable-line no-unused-vars
import render from "preact-render-to-string";
import App from "../build/ssr-build/ssr-bundle";
import Assets from "../build/ssr-build/client-assets";
const pollyfillBundleName = Object.keys(Assets).filter(
key => key.includes("polyfills") && key.includes("js")
)[0];
const mainBundleName = Object.keys(Assets).filter(
key => key.includes("bundle") && key.includes("js")
)[0];
// can't seem to escape the <\/script> in window.fetch||document.write('<script src="${pollyfillBundleName}"><\/script>')
function renderFullPage(html, preloadedState) {
return `
<body>
${html}
<script>
window.__PRELOADED_STATE__ = ${JSON.stringify(
preloadedState
).replace(/</g, "\\u003c")}
</script>
<script defer src="${mainBundleName}"></script>
<script>
if(!window.fetch){
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', '${pollyfillBundleName}');
document.body.appendChild(script);
}
</script>
</body>
</html>
`;
}
export default async (pathname, writer, encoder) => {
// mock a network request, this is where we could load any needed async data to populate the
// server side redux store
const serverGatheredState = await (() =>
Promise.resolve({ name: "State rehydrated from the server" }))();
const html = render(
<App url={pathname} reduxStateFromServer={serverGatheredState} />
);
// stream the body of the page with our SSR results
writer.write(encoder.encode(renderFullPage(html, serverGatheredState)));
// await the close of the streaming response
await write.close();
};