I'm just setting up a basic application. I've got a hand full of routes and an onBeforeAction that checks if the user is logged in. If not it renders a Login template within a special layout (using this.layout()).
Also i have my basic layoutTemplate, loadingTemplate and notFoundTemplate setup in Router.configure() which as far as i understand sets a default for every Route that doesn't define things otherwise.
Basically everything works with one exception: For 404 events the onBeforeAction doesn't get called. This makes my 404 template render in the Default layout. My goal would be to have the login check in place even on not existing routes.
What would be the best way to get that done?
I had the same problem and this worked for me.
Basically the catchall route is only used to check if the user is logged in, if not redirect (or render if you prefer that) the login template, if user is logged in it just calls next(). It needs to be placed last of all the routes of course.
Instead of using Router.configure() to set the notFoundTemplate, render it in the catchall route. When you keep it as the last route, then there are no matching routes and it would be the right spot to render a notFoundTemplate.
In the example I store the url in a session object so I can get it and redirect the user on successful login to the route they tried to access, but originally I used this.redirect('auth') to redirect to a seperate route for login - that is just personal preference though. However I thought that was useful so I kept it in the code.
Router.onBeforeAction(function () {
if(!Meteor.user() && !Meteor.loggingIn()){
Session.set('returnUrl', Router.current().url);
this.render('auth');
} else {
this.next();
}
}, {except: ['auth']});
Router.route('/auth', function () {
this.render('auth');
});
Router.route('/(.*)',function(){
this.render('notFoundTemplate');
});
Update
Regarding flickering, i added the !Meteor.loggingIn() check. I also cleaned up the code a bit and used the 'except' parameter to avoid running the onBeforeAction on the auth route, but since you don't need it just remove that.