Good News!
SSR works with the following:
- Meteor 2.14
- Using
Meteor.callAsync()
- Using
- React Router 6.21
- React 18.3.0-canary-c5b937576-20231219
- Suspense
- lazy
renderToNodeStream()use()- use – React (as mentioned by @radekmie above)
The example in the above branch has a component and data loaded using Suspense and nested lazy loaded components.

Caveats:
- Still using
renderToNodeStream(), which has been deprecated in React 18
use()hook is still in the canary channel (expected to arrive in 18.3) - can be used in production by pinning the canary version
The use() hook simplifies everything with Meteor.callAsync() and Suspense.
const { links } = use(Meteor.callAsync('getLinks'));
To Do:
Since renderToNodeStream() is deprecated, there is still a need to support renderToPipeableStream() moving forward. There are two important things to do to make this possible:
- Support a JSX boilerplate-generator template because hydration now happens on
documentinstead of an HTML element. This requires allowing a custom template to generate the HTML output. Either Meteor adds a custom template for React or allows the developer to add one. - Allow access to the
responseparameter accessible byrenderToPipeableStream()
Ideally, these features will be available through server-render package.
