@nfq/react-ssr
Version:
An helper bundle for react with ssr setup
117 lines (92 loc) • 2.8 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.renderWithStyles = exports.readHtml = exports.getHelmetString = exports.createAppWithContext = void 0;
const fs = require('fs');
const path = require('path');
const {
promisify
} = require('util');
const React = require('react');
const {
renderToString
} = require('react-dom/server');
const {
StaticRouter
} = require('react-router-dom');
const {
ServerStyleSheet
} = require('styled-components'); // eslint-disable-next-line import/no-unresolved
const {
Helmet
} = require('./helmet'); // eslint-disable-next-line security/detect-non-literal-fs-filename
const readFile = promisify(fs.readFile);
/**
* Read the html file from given path.
*
* @param {String} htmlPath An absolute path to the html file.
*
* @returns {Promise} Returns an async loading function.
*/
const readHtml = htmlPath => async (req, res, next) => {
if (!Object.prototype.hasOwnProperty.call(req, 'ssrMiddleware')) {
req.ssrMiddleware = {};
}
req.ssrMiddleware.html = await readFile(path.join(process.cwd(), htmlPath), 'utf8');
next();
};
/**
* Gets the helmet object and generates an header string for the template.
*
* @param {Object} helmet The helmet instance used.
*
* @returns {String} The header metatag string.
*/
exports.readHtml = readHtml;
const getHelmetString = helmet => `
${helmet.title.toString()}
${helmet.meta.toString()}
${helmet.link.toString()}
${helmet.noscript.toString()}
${helmet.base.toString()}
`;
/**
* Creates the react app tree.
*
* @param {Object} req The server request object.
* @param {String} appPath The absolute path to the App entry file.
* @param {Object} context The context object that should get added to the router.
*
* @returns {Object} The React component tree.
*/
exports.getHelmetString = getHelmetString;
const createAppWithContext = (req, appPath, context) => {
// eslint-disable-next-line security/detect-non-literal-require
const AppComponent = require(appPath);
return React.createElement(StaticRouter, {
context,
location: req.url
}, React.createElement(AppComponent.default, null));
};
/**
* Renders the app to an string and gets all styles and headers used.
*
* @param {Object} App The react component tree.
*
* @returns {Object} An Object with {helmet, reactHtml, styleTags}.
*/
exports.createAppWithContext = createAppWithContext;
const renderWithStyles = App => {
const sheet = new ServerStyleSheet();
const reactHtml = renderToString(sheet.collectStyles(App));
const styleTags = sheet.getStyleTags();
const helmet = Helmet.renderStatic();
sheet.seal();
return {
helmet,
reactHtml,
styleTags
};
};
exports.renderWithStyles = renderWithStyles;
;