Suppose I've got a web page, which contains nothing but a javascript reference. When a browser loads the page it runs the javascript, which does the actual rendering. The javascript is large, complex, and makes a lot of XHR
calls.
Now I need to make this page searchable, i.e. render the page on the server.
I tried to load the page in phantomJS
but the it was slow and sometimes did not complete the whole page. So I'm wondering if there is an alternative.
Ideally I need a node.js
script to
- load a web page by URL
- run the page javascript and then
- serialize the DOM created by the javascript to HTML.
P.S. I can assume that the javascript is based on React.js
I think that PhantomJS and good caching are your best hope by far, outside of doing a proper server-renderable architecture (which would be the actual right thing to do). Trying to emulate a browser in node is a fool's errand. You will never complete it and will constantly be finding "oops I forgot about that one other thing" endlessly.
Many of your peers in industry are faced with this same problem. Don't cobble together some bespoke solution. Either make node rendering first-class by explicit
ReactDOM.renderToString()
and factoring out the browser-side code (XHRs etc), or use a fully-capable headless browser like PhantomJS.If you are going to hack things, why don't you do this:
You can make a decision about when and how you serve the "frozen" versions of pages versus the dynamic ones.
Note that this makes your React pages static rather than dynamic - but they are searchable. Maybe you want a searchable archive alongside the dynamically rendered app-like pages. This would allow you to do this. It off-loads the rendering to clients.
There may be issues around logins and confidential information, if for example this were a GMail-type app.
But I didn't read anything in your question that suggests it.
Essentially you need to configure a node.js server that for every request can respond the react component rendering result as plain string. The key is React.renderToString. An example in combination with react-router:
React-router is helpful to load components based on url but it is not strictly necessary. Anyway if you are new to react ecosystem I suggest you to take a look at this starter kit for isomorphic react applications. As you should know what you are trying to do is called isomorphic Javascript.