Does one Meteor project = one SPA?

I thought I had a pretty basic use case, but I haven’t been able to make a workable implementation.

  1. I have an SPA (Single Page Application) built in Meteor (think: admin interface)
  2. But I also want to expose a server-rendered home page separate from the SPA. (and other server-rendered non-SPA pages, and other static pages) (Think: public facing website)

I have been googling and reading for a week, but I don’t seem to be getting any closer to a workable solution. I hope someone can steer me in the right direction!

I would be ok with either 1 + 2 in the same Meteor Project, or 1 + 2 hosted on separate projects/domains.

Am I going about this all wrong? Why does it seem so hard to accomplish this?

1 Like

You can do either. Both have tradeoffs.

###One SPA for public and admin

  • Easy to deploy, all in one codebase
  • Don’t have to modularize code or worry about sharing common files
  • User roles can determine if the UI should show/hide menus or options, server can confirm those actions (eg update/delete).
  • Larger payload size as public will get unused client code for client/admin

###Two SPAs for public and admin

  • More granular control over everything
  • Smaller initial file size
  • Have to modularize code and make modules sharable (eg private NPM modules, import outside of project, or local meteor packages)

The Meteor Roles package is going to be essential here. You can also roll your own but using this is more secure (less bugs): https://github.com/alanning/meteor-roles

With React I made a simple ‘higher order component’ helper to redirect if the user does not have the required roles… eg:

const DashBoard = React.createClass(...);

export default authorizeForRole('admin', DashBoard)

You can also do this manually in either Blaze or React by checking the user role and redirecting if they don’t have the correct roles in the ‘rendered’ or ‘will render’ callbacks.

You need to also check the current user role before sending down sensitive data in the publications… basically return null if the user is not and admin and return the cursor if they are.
This was If the user hacks the frontend to make their role an ‘admin’ than they will only see an empty admin page without the data.

Hope this helps! :thumbsup:

If you’re just looking for a a separate front-facing public site then I would use Jekyll or something similar to generate a static site, on a different host. An often used paradigm is to have your static site at www.myawesomeapp.com and your app hosted at app.myawesomeapp.com.

If you’re looking at using some data from the SPA, you could connect to the MongoDB and use the data in there.

What exactly is your intended use case?

Thanks for describing the tradeoffs so clearly between one and two SPAs. I haven’t begun thinking about user roles yet, but those tips will come in handy later I’m sure.

I think what I’m really struggling with is how to work with Meteor in a NON-SPA context, rather than whether I should have one or two SPAs. For the public pages what I want is server-side rendered pages (aka a traditional server-rendered website). Despite all the attention given to SPAs these days, I think non-SPAs still has many advantages.

Further clarification:

public and admin in the same Meteor project

Using meteorhacks:ssr and meteorhacks:picker is almost what I need:
https://meteorhacks.com/meteor-server-sider-rendering-for-seo-purpose/

I don’t think it will work because I would like the home page (/) to be the server-side rendered page, and Meteor wants to take that page for itself, with no way of overriding it (it seems).

public and admin in separate domains/projects

I was originally going to use a Meteor DDP client (and use it in my server-side Node/Express application), but realized that I would have to be able to handle DDP notifications rather than the final data, which feels too low-level to me. Oh, actually, maybe I can use DDP to expose methods rather than subscriptions? Could that work?

My other idea right now is to expose my Meteor data using a REST API, and set up a totally separate, non-meteor project to consume that REST API (serverside) and render a page of HTML out. However, this means building out #2 from scratch and basically losing all benefits of using Meteor.

@Stan Yes, I’m looking to use some data from the SPA.

I can be more specific about my use case. It’s pretty basic:

  • The Meteor Admin is an article editor, from which logged in users can create articles.
  • On the public home page, I just want to show a list of articles. (rendered serverside, not an SPA).
  • Clicking on the article should take me to the article view (rendered serverside, not an SPA).

So now it seems I have 3 workable alternatives:

  1. use Meteor DDP Client to connect to the Meteor serverside and call methods that return data
  2. setup some REST endpoints to be consumed
  3. query the MongoDB myself and fetch the data myself

Perhaps 3 is the cleanest approach of them all?