Search code examples
meteoriron-routeruser-accounts

Routing to home screen when not signed in


I want to redirect all users to a home page if they are not logged in. Currently I am doing this:

Router.onBeforeAction(function() {
  this.render('loading');
  if (! Meteor.userId()) {
    this.render('Home');
  } else {
    this.next();
  }
});

Which I saw online, but this seems to be prevent my 'loading' template from ever showing and instead shows the default

Loading...

in the top left of the screen. If I change this.render('Home'); to this.redirect('/') I see the correct loading template. However in the '/' route I call another this.render('Home') which I think then triggers the onBeforeAction again which in turn will redirect to '/' which means you are now in an infinite loop of loading.

So what is the correct way to fix my Router.onBeforeAction to achieve my desried goal of making sure users that are not logged in can only see the Home template no matter what URL they type in and do this without messing up my custom loading template elsewhere on the site?


Solution

  • You need to have two before hooks. One is for 'loading' and one is to check if the user is logged in.

    The 'loading' one is linked up to your subscriptions and is usually a preinstalled hook with iron router.

    Router.onBeforeAction(function() {
      if (! Meteor.userId()) {
        this.render('Home');
      } else {
        this.next();
      }
    }, {except: ['route_one', 'route_two']});
    
    Router.onBeforeAction('loading');
    

    Your route:

    Router.route('/', {
        name: 'home',
        subscriptions: function() { 
            //Array of Meteor.subscribe to wait for and display the loading template
            return [Meteor.subscribe("a_subscription")]
        },
        loadingTemplate: 'loading',
        action: function() {
            this.render("Home_logged_in");
        }
    });
    

    So here, if Meteor.subscribe("a_subscription") is loading it will display the loading template. If the user is logged in it will display the Home_logged_in template and if not logged in (on any route) the Home template.

    You can also set exceptions using the names 'route_one' and 'route_two' for your templates (which you can rename to anything else). I named your home template home. But if you added home to the except list the onBeforeAction would not apply to home.