-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Allow disabling boilerplate response and pass response to boilerplate callbacks #13855
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow disabling boilerplate response and pass response to boilerplate callbacks #13855
Conversation
These changes pass the express response to the boilerplate data callbacks and adds the ability to disable the default boilerplate server response. Motivation for this change stems from React's need to handle the entire html document when server rendering. Executing the newly added WebappInternals.disableBoilerplateResponse stops meteor from sending the default html shell, and allows frameworks that don't play well with Meteor's default boilerplate generation to take over handling generation of the html document and pipe it to the response object.
✅ Deploy Preview for v3-meteor-api-docs canceled.
|
✅ Deploy Preview for v3-migration-docs canceled.
|
|
Great to see these changes in a PR. Could you prepare a small React SSR app? We can then use a Meteor checkout from your branch so we can see it in action and debug it. Maybe include the other packages you mentioned that are common for SSR in the community. I’m not familiar with Meteor SSR full capabilities and usage beyond some basic usage. It'd be nice if we could have an example of Meteor SSR app that serve us to understand and grow features from it. |
|
@nachocodoner here you go. https://github.com/copleykj/meteor-with-react-ssr It's quite simple and there are some other things that would have to be taken into consideration in a full setup like static js assets and SRI, but this fully works when running from a checkout containing the changes from this PR |
|
@copleykj: I had time to review your PR after a long stretch working on the next Rspack integration for Meteor 3.4. I'm not very familiar with advanced SSR, but I got your example running. I had to silence client rendering to see only the SSR output you described in I’m for merging this into 3.4 so people can experiment with improved SSR for React. It also gives you a base to keep improving, including reloads. If you agree, please add docs for the new disableBoilerplateResponse option, marked experimental. The app you shared is a good example for me to test the Rspack integration and understand future SSR opportunities. Let me know what you think. We can iterate from this point. Update: Tested it with Rspack and it works too, including the server reload. As part of Meteor 3.4 and the Rspack integration, I adjusted the server reload behavior in development to force it, since it was also lost and didn't interacted well with Rspack. Surprisingly, that change when using Rspack fixed the issue in this PR and made the app reload correctly. 😄 |
|
@nachocodoner although I'm sure there is someone with a server only use case, my intent is still a hybrid app with SSR used mainly for SEO purposes and the client taking over after the first page load. I hadn't noticed the issue with failed reloads myself, but could have totally missed it. If Rspack fixes this issue though, that'd be fantastic. I'm happy to add docs for this if you can just point me in the direction of where you want them added. |
|
I believe it’s enough to add them within WebApp since it already depends on this package. Mark it as experimental and include a short explanation of the reasoning and the idea and use cases behind it. |
nachocodoner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m going to merge this after my testing. Please prepare the docs update in a separate PR. I’ll announce the experimental React SSR changes here in the next beta.
Summary
These changes pass the express response object to the boilerplate data callbacks and adds the ability to disable the default boilerplate server response.
Motivation for this change stems from React's need to handle the entire html document when server rendering. Executing the newly added WebAppInternals.disableBoilerplateResponse stops meteor from sending the default html shell, and allows frameworks that don't play well with Meteor's default boilerplate generation to take over handling generation of the html document and pipe it to the response object.
I have successfully used these changes to get a full working SSR integration using React's
renderToPipableStream.Caveats
I'm not fully sure that I like the way response is passed to the callbacks, as currently it is passed as the last argument. That being said, this is the only viable solution that I can think of without introducing breaking changes into the codebase.
How this facilitates SSR with React in practice
Apps desiring to server render would use
WebAppInternals.registerBoilerplateDataCallbackto register a callback. From thereWebAppInternals.disableBoilerplateResponseis called so that Meteor does not send it's default boilerplate to the client. Next the data argument passed to the callback contains the information needed to build the script and link tags for the document as well as the runtime config. This script and stylesheet information is used to construct the shell in the top level component using defer attributes on the script tags and the runtimeConfig is passed to the bootstrapContent option ofrenderToPipeableStream. In theonShellReadyor theonAllReadyoption ofrenderToPipeableStreamthe rendered output is piped to the response.Implementations
I'm currently working on using these changes in
communitypackages:fast-renderandcommunitypackages:react-router-ssrthat use this technique to implement server rendering React applications. It's fully working at this point and just some minor adjustments and code cleanup remain.