@shopify/react-html
Version:
A component to render your React app with no static HTML
146 lines (138 loc) • 5.4 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var server = require('react-dom/server');
var reactHydrate = require('@shopify/react-hydrate');
var context = require('../../context.js');
var utilities = require('../../utilities.js');
var Script = require('./Script.js');
var Serialize = require('./Serialize.js');
var Stylesheet = require('./Stylesheet.js');
var InlineStyle = require('./InlineStyle.js');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
function Html({
manager,
hydrationManager,
children = '',
locale = 'en',
blockingScripts = [],
scripts = [],
styles = [],
inlineStyles = [],
preloadAssets = [],
headMarkup = null,
bodyMarkup = null
}) {
const markup = typeof children === 'string' ? children : render(children, {
htmlManager: manager,
hydrationManager
});
const extracted = manager && manager.extract();
const serializationMarkup = extracted ? extracted.serializations.map(({
id,
data
}) => /*#__PURE__*/React__default["default"].createElement(Serialize["default"], {
key: id,
id: id,
data: data
})) : null;
const managedProps = {
[utilities.MANAGED_ATTRIBUTE]: true
};
const titleMarkup = extracted && extracted.title ? /*#__PURE__*/React__default["default"].createElement("title", managedProps, extracted.title) : null;
const metaMarkup = extracted ? utilities.removeDuplicate(extracted.metas).map((metaProps, index) =>
/*#__PURE__*/
// This is never re-rendered, since it is the initial HTML document,
// so index keys are acceptable.
// eslint-disable-next-line react/no-array-index-key
React__default["default"].createElement("meta", Object.assign({
key: index
}, managedProps, metaProps))) : null;
const linkMarkup = extracted ? extracted.links.map((linkProps, index) =>
/*#__PURE__*/
// This is never re-rendered, since it is the initial HTML document,
// so index keys are acceptable.
// eslint-disable-next-line react/no-array-index-key
React__default["default"].createElement("link", Object.assign({
key: index
}, managedProps, linkProps))) : null;
const stylesheetMarkup = styles.map(style => {
return /*#__PURE__*/React__default["default"].createElement(Stylesheet.Stylesheet, {
key: style.path,
href: style.path,
integrity: style.integrity,
crossOrigin: "anonymous"
});
});
const inlineStylesMarkup = inlineStyles.map(inlineStyle => {
return /*#__PURE__*/React__default["default"].createElement(InlineStyle.InlineStyle, {
key: inlineStyle.content
}, inlineStyle.content);
});
const blockingScriptsMarkup = blockingScripts.map(script => {
return /*#__PURE__*/React__default["default"].createElement(Script.Script, {
key: script.path,
src: script.path,
integrity: script.integrity,
type: script.type,
crossOrigin: "anonymous"
});
});
const deferredScriptsMarkup = scripts.map(script => {
return /*#__PURE__*/React__default["default"].createElement(Script.Script, {
key: script.path,
src: script.path,
integrity: script.integrity,
type: script.type,
crossOrigin: "anonymous",
defer: true
});
});
const preloadAssetsMarkup = preloadAssets.map(asset => /*#__PURE__*/React__default["default"].createElement("link", {
key: asset.path,
rel: "prefetch",
href: asset.path
}));
const htmlAttributes = extracted ? extracted.htmlAttributes : {};
const bodyAttributes = extracted ? extracted.bodyAttributes : {};
// eslint-disable-next-line no-process-env
if (process.env.NODE_ENV === 'development') {
if (bodyAttributes.style == null) {
bodyAttributes.style = {
visibility: 'hidden'
};
} else {
bodyAttributes.style.visibility = 'hidden';
}
}
return /*#__PURE__*/React__default["default"].createElement("html", Object.assign({
lang: locale
}, htmlAttributes), /*#__PURE__*/React__default["default"].createElement("head", null, titleMarkup, /*#__PURE__*/React__default["default"].createElement("meta", {
charSet: "utf-8"
}), /*#__PURE__*/React__default["default"].createElement("meta", {
httpEquiv: "X-UA-Compatible",
content: "IE=edge"
}), /*#__PURE__*/React__default["default"].createElement("meta", {
name: "referrer",
content: "never"
}), metaMarkup, linkMarkup, stylesheetMarkup, inlineStylesMarkup, headMarkup, blockingScriptsMarkup, deferredScriptsMarkup, preloadAssetsMarkup), /*#__PURE__*/React__default["default"].createElement("body", bodyAttributes, /*#__PURE__*/React__default["default"].createElement("div", {
id: "app",
dangerouslySetInnerHTML: {
__html: markup
}
}), bodyMarkup, serializationMarkup));
}
function render(app, {
htmlManager,
hydrationManager
}) {
const hydrationWrapped = hydrationManager ? /*#__PURE__*/React__default["default"].createElement(reactHydrate.HydrationContext.Provider, {
value: hydrationManager
}, app) : app;
const content = htmlManager == null ? app : /*#__PURE__*/React__default["default"].createElement(context.HtmlContext.Provider, {
value: htmlManager
}, hydrationWrapped);
return server.renderToString(content);
}
exports["default"] = Html;