Simple base class for truly SSR-capable React components
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Vitaliy Filippov 57cd762262 Get key from item (not props), do not update state if there is no change 1 year ago Initial commit 1 year ago
SSRComponent.js Faster and more correct variant which does not recreate full DOM tree on every run 1 year ago
renderToHtml.js Remove extra spaces in the style attribute to better match React 1 year ago
virtualRender.js Get key from item (not props), do not update state if there is no change 1 year ago

This is a simple base component class for true server-side rendering with emulation of server interaction.

It is intended for use with class components and without any external state management libraries like Redux. Basically it's intended for pure setState()-based code.


  • Write code in such a way that it still works if DOM is not available
  • Make your components inherit from SSRComponent:
    • Use doRender instead of render
    • Use init instead of constructor
    • Everything else stays the same
    • You can additionally override serializeState and unserializeState if your state isn't directly JSON-serializable
  • Implement SSR:
    • Declare store = {}
    • Render your component using react-test-renderer with store={store} in props
    • Make sure your code tracks all fetch() requests (server interactions) during render
    • And of course mock fetch() (or analogue) to use internal server-side calls
    • Wait until all fetch() requests complete
    • Re-render until the component stops issuing additional requests
    • Render HTML using renderToHtml(testRenderer.toJSON())
    • Serialize state using JSON.stringify(SSRComponent.serializeStore(store))
  • Hydrate the rendered HTML in your frontend code:
    • Call ReactDOM.hydrate() instead of ReactDOM.render()
    • Pass serialized state from the last step of SSR to your top-level SSRComponent


Simpler (but less compatible) alternative to react-test-renderer.


import virtualRender from 'virtualRender.js';

const options = {};
let html = virtualRender(<Component {...props}>, options);
while (options.shouldUpdate)
    html = virtualRender(<Component {...props}>, options);

Author and License

Author: Vitaliy Filippov, 2021+

License: Dual-license MPL 1.1+ or GNU LGPL 3.0+ (file-level copyleft)