scrapinghub / splash

Lightweight, scriptable browser as a service with an HTTP API
BSD 3-Clause "New" or "Revised" License
4.08k stars 514 forks source link

React pages are not rendered #1117

Open palle-k opened 3 years ago

palle-k commented 3 years ago

While attempting to use splash with multiple client side rendered react pages, I noticed that the page is not properly rendered.

One example is the following react page: http://germavinsmoke.me/bmi-calculator/, which I attempted to render with the following script with the scrapinghub/splash:master docker image:

function main(splash, args)
  assert(splash:go(args.url))
  assert(splash:wait(5))
  return {
    html = splash:html(),
    png = splash:png(),
    har = splash:har(),
  }
end

This results in the following HTML response:

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><link rel="shortcut icon" type="image/png" href="./icon.png"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="theme-color" content="#172b4d"><meta name="description" content="Web site created using create-react-app"><title>BMI Calculator</title><link href="/bmi-calculator/static/css/2.ae9e8b99.chunk.css" rel="stylesheet"><link href="/bmi-calculator/static/css/main.fce36487.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(i){function e(e){for(var r,t,n=e[0],o=e[1],u=e[2],l=0,a=[];l<n.length;l++)t=n[l],Object.prototype.hasOwnProperty.call(f,t)&&f[t]&&a.push(f[t][0]),f[t]=0;for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(i[r]=o[r]);for(s&&s(e);a.length;)a.shift()();return p.push.apply(p,u||[]),c()}function c(){for(var e,r=0;r<p.length;r++){for(var t=p[r],n=!0,o=1;o<t.length;o++){var u=t[o];0!==f[u]&&(n=!1)}n&&(p.splice(r--,1),e=l(l.s=t[0]))}return e}var t={},f={1:0},p=[];function l(e){if(t[e])return t[e].exports;var r=t[e]={i:e,l:!1,exports:{}};return i[e].call(r.exports,r,r.exports,l),r.l=!0,r.exports}l.m=i,l.c=t,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(r,e){if(1&e&&(r=l(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var n in r)l.d(t,n,function(e){return r[e]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/bmi-calculator/";var r=window.webpackJsonpbmical=window.webpackJsonpbmical||[],n=r.push.bind(r);r.push=e,r=r.slice();for(var o=0;o<r.length;o++)e(r[o]);var s=n;c()}([])</script><script src="/bmi-calculator/static/js/2.0e5f39ad.chunk.js"></script><script src="/bmi-calculator/static/js/main.450fb4b8.chunk.js"></script></body></html>

(notice that <div id="root"></div> is empty)

Predendering with prerender/prerender yields the correct result; <div id="root"></div> is not empty:

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><link rel="shortcut icon" type="image/png" href="./icon.png"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="theme-color" content="#172b4d"><meta name="description" content="Web site created using create-react-app"><title>BMI Calculator</title><link href="/bmi-calculator/static/css/2.ae9e8b99.chunk.css" rel="stylesheet"><link href="/bmi-calculator/static/css/main.fce36487.chunk.css" rel="stylesheet"><style type="text/css">/* Chart.js */
/*
 * DOM element rendering detection
 * https://davidwalsh.name/detect-node-insertion
 */
@keyframes chartjs-render-animation {
    from { opacity: 0.99; }
    to { opacity: 1; }
}

.chartjs-render-monitor {
    animation: chartjs-render-animation 0.001s;
}

/*
 * DOM element resizing detection
 * https://github.com/marcj/css-element-queries
 */
.chartjs-size-monitor,
.chartjs-size-monitor-expand,
.chartjs-size-monitor-shrink {
    position: absolute;
    direction: ltr;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    overflow: hidden;
    pointer-events: none;
    visibility: hidden;
    z-index: -1;
}

.chartjs-size-monitor-expand > div {
    position: absolute;
    width: 1000000px;
    height: 1000000px;
    left: 0;
    top: 0;
}

.chartjs-size-monitor-shrink > div {
    position: absolute;
    width: 200%;
    height: 200%;
    left: 0;
    top: 0;
}
</style></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"><div class="container"><div class="row center"><h1 class="white-text"> BMI Tracker </h1></div><div class="row"><div class="col m12 s12"><div class="chartjs-size-monitor"><div class="chartjs-size-monitor-expand"><div class=""></div></div><div class="chartjs-size-monitor-shrink"><div class=""></div></div></div><div class="row"><div class="col m6 s12"><label for="weight">Weight (in kg)</label><input id="weight" name="weight" type="number" min="1" max="999" placeholder="50" value=""></div><div class="col m6 s12"><label for="height">Height (in cm)</label><input id="height" name="height" type="number" min="1" max="999" placeholder="176" value=""></div></div><div class="center"><button id="bmi-btn" class="calculate-btn" type="button" disabled="">Calculate BMI</button></div><canvas height="493" width="986" class="chartjs-render-monitor" style="display: block; width: 986px; height: 493px;"></canvas><div><div class="row center"><h4 class="white-text">7 Day Data</h4></div><div class="data-container row"><div class="center white-text">No log found</div></div></div></div></div></div></div></body></html>

What options do I have to set for the page to render correctly?

alexandresgf commented 3 years ago

Same here. Any React page is not being rendered, only the ones which use React to render static content like Gatsby, Next, etc. Any solutions for that?

rythm-of-the-red-man commented 3 years ago

Same issue with Angular apps, unfortunetly none of documentation advices on website not being rendered correctly worked. E.g. with page of some Polish bookmacher which seems to be written purely in angular. image with pretty basic script:

function main(splash, args)
  assert(splash:go(args.url))
  assert(splash:wait(20))
  return {
    html = splash:html(),
    png = splash:png(),
    har = splash:har(),
  }
end
manu-shukla commented 3 years ago

Same issue unable to render leetcode.com