ahlrua
Last Updated: February 25, 2016
·
8.733K
· benjaminrh
2aca501921a5a98762cc4af16da258b8

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.

Say Thanks
Respond

4 Responses
Add your response

7026
37fdb406d40696967b09a3c239b96f7c

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 ·
11866
Rubber duck

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 ·
16118
4ac7c0b696ba968d2353ba74ead0a899

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 ·
23367
None

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

over 1 year ago ·