UNPKG

2.29 kBJavaScriptView Raw
1import { h, createContext, Fragment } from "preact";
2import { useRef } from "preact/hooks";
3import render from "preact-render-to-string";
4export const __DocContext = createContext({
5 head: { current: [] },
6 hydrate: { current: [] },
7});
8export const __hydratedComponents = [];
9const unique = (value, index, self) => self.indexOf(value) === index;
10export const Document = ({ hydrateExportManifest, page, styles = [], hasScripts = false, children, }) => {
11 const head = useRef([]);
12 const hydrate = useRef([]);
13 const subtree = render(h(__DocContext.Provider, { value: { head, hydrate } }, children), {}, { pretty: true });
14 const components = hydrate.current.map(({ name }) => name).filter(unique);
15 if (hydrate.current.length > 0)
16 __hydratedComponents.push({ page, components });
17 const componentStyles = components
18 .map((name) => {
19 const found = hydrateExportManifest.find((entry) => entry.exports.find(([_key, n]) => n === name));
20 if (found)
21 return found.styles;
22 return null;
23 })
24 .filter((v) => v)
25 .join("")
26 .trim();
27 return (h("html", null,
28 h("head", null,
29 h("meta", Object.assign({}, { charset: "utf-8" })),
30 h("meta", { name: "viewport", content: "width=device-width" }),
31 h(Fragment, null, head.current),
32 h("style", { dangerouslySetInnerHTML: {
33 __html: "[data-hydrate]{display:contents;}",
34 } }),
35 styles.map((style) => (h("style", { dangerouslySetInnerHTML: { __html: style.trim() } }))),
36 componentStyles && (h("style", { dangerouslySetInnerHTML: { __html: componentStyles } }))),
37 h("body", null,
38 h("div", { id: "__microsite", dangerouslySetInnerHTML: { __html: subtree } }),
39 hydrate.current.length > 0 && (h("script", { type: "module", defer: true, src: `/_hydrate/pages/${page}.js` })),
40 hasScripts ? (h(Fragment, null,
41 h("script", { type: "module", src: "/index.js" }),
42 h("script", Object.assign({}, { nomodule: "" }, { src: "https://unpkg.com/systemjs@2.0.0/dist/s.min.js" })),
43 h("script", Object.assign({}, { nomodule: "" }, { src: "/index.legacy.js" })))) : null)));
44};