Closed macrozone closed 5 years ago
here is the code i used in my app to do SSR with flow router:
https://gist.github.com/macrozone/637f66dbac7bf752b0814cdc0699b677
there are some pitfalls:
i also need to revisit/ remove the .current() api from the server side version, because the server side router has to be stateless, otherwise, this leads to ugly concurrency problems
I had also another concurrency problem with react.createContext, but i think i have solved it now... https://github.com/facebook/react/issues/13854
any feedback would be much appreciated so that this can be merged. I used it in production for some time now
Hello @macrozone ,
I'm very sorry for delayed response, end of the year.... 🤦♂️ Thank you for putting this up together. I've went through all other related issues at meteor and react, you've done gj there 💪🎉
I was about to merge this PR, doing maintenance routine before merge, like running tests, but end up looking at this issue — https://github.com/VeliovGroup/flow-router/issues/59 mb you have any idea around this?
@dr-dimitru I just tried checking out this PR and all 143 tests pass :+1:
Hello @coagmano ,
Thank you for the quick update. Wondering why this even raised here, let's continue at #59
Hi @macrozone, I have been trying to use the info on this PR and the gist you posted but haven't been able to get SSR working. Do you have a repo I can checkout to check how to get working SSR with FlowRouter?
Thanks.
Just got it working. Unfortunately, I use grapher-react and still don't have SSR support. I'll try to get SSR working with it and create a tutorial for doing it.
Hello @pmogollons 👋
Sorry I can't help you with SSR as I have no experience with it. If you're looking for implementing SEO properly, I recommend to take a look on prerendering.com
@dr-dimitru Thanks, I think we will try ostrio to get SEO faster.
(see https://github.com/VeliovGroup/flow-router/issues/10#issuecomment-429559609)
To do SSR with FlowRouter, only a few pieces are missing and I try to add them here.
Basically with meteor, SSR works like this (react example)
The
sink
parameter will contain all request params (path, queryParams, etc.). Withreact-router
you usually control the rendered component inside of<App />
depending on the location passed.However with
FlowRouter
our routes usually look like this:Notice:
mount(Component, props)
from above basically does:<Component {...props} />
and injects that on the body on the client.Ok, so if we could somehow call the right action definition inside of a
onPageLoad(sink => { ..})
callback and just callrenderToString
from the action, we were done!So the idea would be:
I implemented Piece 1 in this PR:
matchPath
will look through all routes defined and return{route, params}
if found, or null otherwise.route
is the flow router route definition and params are the path params. E.g. in our example above: if the route has this definition/users/:userId'
and/users/1234
is requested, params will be{userId: "1234"}
with this we can call our action:
Notice: data is an optional feature from flow-router, and can be ignored in this example.
ok, now how to get action to call
sink.renderIntoElementById
on the server?One idea would be to pass sink to the action in a 4th argument:
route.action(params, query, data, { sink });
but then you need to adjust all your actions, which is not really elegant.... :-/
Ok what other api would be possible? Let's have a look how you usually render content with blaze:
Attaching the render function to
this
is a good idea. Let's use such an api. Luckily, we can easily replace the render function with our own:this makes the router work on the client again using react-mounter. In our routes definition we can use this api like this:
Now on the server, we need to directly replace
.render
on a route usingsink
like this:Voilà.
Some notes:
kadira:flow-router-ssr
and as both projects are abandoned, its probably better to fully replace react-mounter (even on the client)sink
could also be included in FlowRouter, but i maybe do that in another PR