React server side rendering as a react based template engine

isomorphic javascript is a technology used to speedup rendering on browser, it can be used a pure version that is server-side-rendering (ssr) to generate template from a react app

Motivation: Create a presentation template to be converted to pdf and configurable with data: produce formatted documents.

Here:
https://www.freecodecamp.org/news/server-side-rendering-your-react-app-in-three-simple-steps-7a82b95db82e/

This is the way the piece of server generated code and client app can work together, using renderToString from:

import { renderToString } from ‘react-dom/server’;

the rendered html contains references to the window.STATE, hydrate is used to “undry” the app (sort of bring it to life).

But by using renderToStaticMarkup from:

import { renderToStaticMarkup } from ‘react-dom/server’;

it is possible to render directly to html markup, without any additional information: pure html.

note

The trick is on the use of:

require("@babel/register");

for transpilling the jsx to javascript transparently.

Here is a src/template.js code:

require("@babel/register");
let fs = require('fs');

const decoratedStyle = (content) => {
    return '<style type="text/css">\n' + content + '\n</style>\n';
}

const nodulespath = __dirname.replace(/\/[a-zA-Z]+$/,'')+"/node_modules/";

const importCss = (moduleref) => {
    const solvedPath = moduleref.replace("~",nodulespath).replace("\./",__dirname+'/');
    //console.log('solvedpath', moduleref, solvedPath);
    let styledef = fs.readFileSync(solvedPath);
    return decoratedStyle(styledef);
}

let render = require('./server');

const template = (state) => {
    let s = {...state};
    delete s.title;
    let content = render(s);
    let page = `<!DOCTYPE html>
              <html lang="en">
              <head>
                <meta charset="utf-8">
                <title> ${state.title} </title>
                ${importCss('~bootstrap/dist/css/bootstrap.min.css')}
                ${importCss('~font-awesome/css/font-awesome.min.css')}
                ${importCss('./template.css')}
              </head>
              <body>
              <div id="root">
                ${content}
                </div>
              </body>
              `;

  return page;
}

module.exports = template;

and here a rendering script that is called by a nodejs service that generate static documents:

const fs = require('fs');
const inlineCss = require('inline-css');

let template = require('./template');
let getState = require('./state/get-state');

let data = process.argv[2];
//console.log('commna',data);
let currentselection = {
    tariff_id: 5,
    selected_opt: {"3101":66,"3102":79,"3108":166,"3109":34,"3112":155,"3114":85,"3115":157,"3208":161,"4005":180,"4102":151,"4105":170,"4107":67,"4202":159,"4207":105}
};

let state = getState(JSON.parse(data));
let html = template(state);

const output_fn_inlined = __dirname + '/../dist/output.inlined.html';

inlineCss(html, {url: 'http://ssl.starsellersworld.com/'})
.then(html => {
    //fs.writeFileSync(output_fn_inlined, html);
    let buf = Buffer.from(html);
    //console.log(buf.toString('base64'))
    let res = {"html":buf.toString('base64')};
    //console.log(JSON.stringify(res))
    process.send(JSON.stringify(res));
    //process.send(data);
    process.exit(0);
}).catch(err=> {
    console.log('error', err);
    process.exit(0);
});

If you want to know more, you can consider working with us, drop me an email: dc @ xwave . de ( r e m o v e s p a c e s ! )


Posted

in

by

Tags: