UNPKG

@nfq/react-ssr

Version:

An helper bundle for react with ssr setup

117 lines (92 loc) 2.8 kB
"use strict"; 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;