ssr
ssr copied to clipboard
Apollo support
At a minimum we need to:
-
Check for a function called
fetchData()(exported by thegraphqlHOC) in each component as we walk the tree, and treat it likessr.prepareStore. -
The user needs to wrap their app in a
ApolloProvider
Do we need support from ssr, or can the client do everything they on the server from their own app?
We should include a demo of this.
Link to @xavcz's repo: https://github.com/xavcz/meteor-apollo-codetour
Hello, is there currently any workaround to get ssr with apollo and ssrwpo? Is there sth like the preRender prop like on react-router-ssr? Then we could simply use a promise to fetch getDataFromTree before sending the html down to the client.
Regards, Lukas
Not for the moment but contribution in this field would be appreciate.
Hello, If you decide to contribute, it's probably this file that needs to be updated: https://github.com/ssrwpo/ssr/blob/develop/src/server/steps/processSSRRequirements.jsx
okay, thanks guys i'll try to take a stab, but i never did anything related to ssr besides using plugins so the solution will probably be pretty messy :)
@iRayzer on which branch should i start? seems like this file is missing on master, but on develop nothing renders any more and i get React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. errors
edit: figured out that api changed and it's now createRouter(MainApp, instead of createRouter({MainApp,
Still i'm not quite sure if i'm on the correct branch - seems like develop is broken due to changes at styled Components since -20 deta which is used inside demo. Fixed it with:
const sheet = new ServerStyleSheet();
css = sheet.getStyleTags();
for now.
I came up with a pretty hacky solution which "works for now" as we have some more pressing things right now:
walkTree(rootElement, rootContext, (element, instance, context) => {
(...)
// assume it's the apollo provider fetch the data and set the initialstate
if (element.props.client) {
getDataFromTree(rootElement).then(() => {
const initialState = {[context.client.queryManager.reduxRootSelector]: context.client.getInitialState()};
element.props.initialState = initialState;
});
}
(...)
With this "solution" we'll probably face some race condition problems as we don't wait for the promise to be resolved. The immediate issue i can see right now is that we have a render flash which is probably caused by not passing down the apollo store to the client. So we first render the html, then rerender it without data and rerender it once again as the client fetches the data.
I did it in a cleaner will push to develop asap
Just pushed Apollo SSR support and Styled-components V2 to develop branch.
I think we should delete some things from the store though. They say I should only send data and not other stuff because it's useless.
But to do that we need to do some more logic before store serializing. Will dig into that later. It works as-is already, so you can make some tests if you want.
Don't forget to install & import "isomorphic-fetch". I didn't make it a peer dependency since we don't need it if not using Apollo. But we should probably add it to the readme. Pull request for a cleaner readme would be welcomed! (Saying we are Apollo compatible and how to use it properly).
Thanks for your help
@iRayzer i gave it a quick test run and the "ssr" part of this is working as the correct dom is sent down, but there seems to be problem with rehydration of the apollo store
- server sends down correct hydrated markup
- [flash] client renders empty/loading states (client error because server != client)
- [flash] client renders with fetched content
I'll give it a closer look tomorrow evening. Thanks for your efforts! Regards, Lukas
I think it is because I do not do the proper transformations on the store... They say you should put the initial Apollo state in a special key but I don't do that..
Or maybe you tried to use Apollo SSR in a space reserved to logged-in user ? In this case the conflict would come from the cache.
@iRayzer sry, didn't have a chance to look at this in detail yet - will do it today :) I think it has nothing to do with logged-in users. For everything with login i use this asymetricSsr
When running:
createRouter({
// Your MainApp as the top component that will get rendered in <div id='react' />
MainApp
}).then(() => {
logger.info('ssr started')
window.getStore = getStore
console.log(getStore().getState())
})
on the client getState() should contain the apollo data or? For me it seems to not contain anything related to apollo queries so i'd assume sth goes wrong at store serialization?
Can you make a repository containing your issue please
I guess the problem is that you don't pass the ApolloProvider an instance of the store. (Get it via context ;) )
@iRayzer that's entirely possible :/ - I still don't really get it how to do this... On the server i have sth like:
const MainApp = (props, {store}) => {
return (
<ApolloProvider store={store} client={apollo.client}>
<RootRouter />
</ApolloProvider>
)
}
createRouter(MainApp)
which is probably wrong as store.getState() is basically empty here.
Here's an example repo https://github.com/sakulstra/ssrwpo-apollo-example reproducing the issue
Here you go. I made a pull request with fixed SSR :)
just a quick heads-up here :) @iRayzer helped me and it seems like apollo ssr is finally working! Thanks a lot guys!