Last Updated: December 26, 2018
·
9.919K
· benjaminrh

Active links in Meteor

If you use Meteor Router or a similar routing solution, you might want to give navbar links an active class when you're on that page. If you're trying Template helpers, you're probably going about it the wrong way. It couldn't be simpler to register a custom Handlebars helper.

First, we define a method that gets the current path. This simply returns the path without a / at the end, or just / if we're at the root path:

// Get the current path for URL
curPath=function(){var c=window.location.pathname;var b=c.slice(0,-1);var a=c.slice(-1);if(b==""){return"/"}else{if(a=="/"){return b}else{return c}}};

Next, we'll register the helper. Notice the closure as the second argument? This is what we will enter when we use the helper in our view. Then we just check to see if our path argument matches the actual path of the current page, and return "active" if that's the case. Easy:

// Determine if current link should be active
Handlebars.registerHelper('active', function(path) {
    return curPath() == path ? 'active' : '';
});

Now we can use it in our view:

<ul class="nav">
    <li class="{{active '/'}}">
        <a href="/">Home</a>
    </li>
    <li class="{{active '/some/page'}}">
        <a href="/some/page">Some Page</a>
    </li>
    <li class="{{active '/about'}}">
        <a href="/about#faq">FAQ</a>
    </li>
    ...
</ul>

Voila!

For an excellent set of handy helpers, check out raix's excellent Meteor Handlebar Helpers package.

4 Responses
Add your response

If you're using meteor-router you can use Meteor.Router.path() to get the named path of the current page. You can then wrap the whole li in a handlebar helper:

Handlebars.registerHelper('navLink', function(page, icon) {
  var ret = "<li ";
  if (Meteor.Router.page() == page) {
    ret += "class='active'";
  }
  ret += "><a href='" + Meteor.Router.namedRoutes[page].path + "'><i class='" + icon + " icon-fixed-width'></i></a></li>";
  return new Handlebars.SafeString(ret);
});
</code>
</pre>
The icon can be replaced with text according to your needs. This can then be used like so:

<ul class="nav pull-right">
{{navLink 'booksList' 'icon-book'}}
{{navLink 'projectsList' 'icon-edit'}}
{{navLink 'info' 'icon-info'}}
</ul>
</code>
</pre>

This has the benefit of replacing the ugly curPath function with pages that meteor-router knows and prevents the repeated /some/page present in your code
over 1 year ago ·

I'm using this code from discover Meteor book and is working fine for me.

Handlebars.registerHelper('activeRouteClass', function () {/* routes names */
var args = Array.prototype.slice.call(arguments, 0),
    active;
args.pop();

active = _.any(args, function (name) {
    return Router.current().route.name === name;
});
if (active) {
    return 'active';
}
return '';
});

Is just call this with the route name.

over 1 year ago ·

An improvement to this would be to have the helper return {class: 'active'} like this:

// Determine if current link should be active.
Handlebars.registerHelper('active', function(path) {
  return curPath() == path ? {class: 'active'} : '';
});

And we can use it now like this now:
<li {{active '/'}}> <a href="/">home</a> </li>

That way, we don't get empty class attributes in the markup.

over 1 year ago ·

you can even do this with this package https://github.com/zimme/meteor-active-route

over 1 year ago ·