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 9 months ago Initial commit 11 months ago
SSRComponent.js Faster and more correct variant which does not recreate full DOM tree on every run 11 months ago
renderToHtml.js Remove extra spaces in the style attribute to better match React 9 months ago
virtualRender.js Get key from item (not props), do not update state if there is no change 9 months 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)