SSR with user data example

I wanted to create a simple web app and I felt like the current state of Meteor should allow me to SSR the app without having to “hydrate” the state of the app. After some tweaking I got exactly what I wanted and decided to share the boilerplate:

  1. SSR “just works”. I write my app and it’s SSR’d correctly whether a component uses data or not.
  2. No need to put data/state on the initial HTML render.
  3. User data is SSR’d normally. Again, just write the app.
  4. Admin section (/admin) is lazily loaded (not part of the main bundle).

Check it out: https://github.com/ManuelDeLeon/meteor-ssr

Caveats:

  • I forked react accounts ui and basic because they had errors and it was a lot easier to fix those than doing it from scratch.
  • It’s technically possible for a user to pull the admin screen but they wouldn’t be able to view or modify admin data.
  • It’s using ReactDOM.hydrate but that’s just the new name for .render(). By “hydrate” people typically mean injecting the initial state on the HTML and using it to render the state. That isn’t needed here.
  • There’s some code duplication in the components. I felt that drying an example would make it less readable.

@antoninadert @wildhart , you may be interested in this.

9 Likes

Just wow! I need to try this ASAP

Hey Manuel, I hope you’re doing well. Didn’t have time to start using meteor-ssr yet, I just looked into the code.

It looks good to me feature-wise, but right now it is like a starter project (so it looks like proto-starter in this way, but with reacher features !)

What I think would be good to do, is to break down your repository into packages that could be used independently.

I think these points deserve a package of their own (probably dependant on Cookies and meteor account). So I wouldn’t depend on the rest of your stack assumptions.

For the admin route and the account-ui, I believe you provide good examples in your current repo. It may be worth adding a readme in your repo though :smiley:

What do you think?

This does look awesome and I really look forward to trying it, thanks @manuel!

I agree with @antoninadert that having the required components as packages I could install into my current projects would be fantastic. As it is, I’m unlikely to be starting any new project anytime soon.

As for SSR in my own project, I’ve moved away from this a while ago because it was causing a server memory leak which I just couldn’t track down. I also realised that I don’t really need SSR on any of my app routes which required data. So I settled for “poor-man’s SSR” on the ‘sales’ landing pages whereby I just inject a copy/paste of the rendered html into the initial html response using the onPageLoad event. The sales pages don’t change often so this is easy to keep up to date, and it gives an instant page load which is easy on the server. Works for me :wink:

When I get some time though I will investigate how your new boilerplate works and see if I can port it across to my existing project. It would be nice to have hydrated SSR again…

How it’s made? Where in your code?

Just because I love how ViewModel is elegant to write, I will tell you @orloff
It is under: meteor-ssr/ui/Admin/Admin.js

The code of this component is this:

Admin({
  isAdmin() {
    const user = Meteor.user();
    return user && user.isAdmin;
  },
  render() {
    return (
      <div b="if: isAdmin">
        <AdminHome b="defer: true" />
      </div>
    );
  }
});

And this line: <AdminHome b="defer: true" /> means: lazy load the component AdminHome.
No need for other libraries. ViewModel has all kinds of the ‘must have’ you would expect from a front-end framework

2 Likes

@wildhart @antoninadert

I think this falls more in the realm of a pattern than implementation. For starters (pun?) there isn’t that much to do to make it work (just authenticate the user with a cookie and prerender with the ssr package). I believe it would take the same effort to understand how to use and configure a package that does this, and actually implementing it by hand. Then we have the authorization itself which can happen in many different ways. Here I’m relying on Meteor’s account system, but what if you used a cloud service?