Add Active Navigation Class Based on URL

Ideally you output this class from the server side, but if you can't...

Let's say you have navigation like this:

<nav>
	<ul>
		<li><a href="/">Home</a></li>
		<li><a href="/about/">About</a></li>
		<li><a href="/clients/">Clients</a></li>
		<li><a href="/contact/">Contact Us</a></li>
	</ul>
</nav>	

And you are at the URL:

http://yoursite.com/about/team/

And you want the About link to get a class of "active" so you can visually indicate it's the active navigation.

$(function() {
  $('nav a[href^="/' + location.pathname.split("/")[1] + '"]').addClass('active');
});

Essentially that will match links in the nav who's href attribute begins with "/about" (or whatever the secondary directory happens to be).

Comments

  1. User Avatar
    Mike
    Permalink to comment#

    I’ve been struggling trying to get something like this to work on a templated HTML website (server side CSS updating not available). The structure of the menu is a little more complex than your example. Would your CSS trick work for this structure? If so, PLEASE enlighten me because I’m stuck.

  2. User Avatar
    mehdi
    Permalink to comment#

    Thanks for every things

  3. User Avatar
    Mark Johnson
    Permalink to comment#

    Danke Chris! Simple, clear and slick. High five!

  4. User Avatar
    Leon Gaban
    Permalink to comment#

    Thanks! Been looking for something like this for a while now :)

  5. User Avatar
    Don
    Permalink to comment#

    Works like a charm with one exception. One the home page the class is added to all the links. The all start with /. Any help would be appreciated.

    • User Avatar
      Don
      Permalink to comment#

      Simple fix: Don’t use the script on the home page file. Duh. :)

    • User Avatar
      Michel
      Permalink to comment#

      Try replacing the hrefˆ= with href$=

      ˆ= value begins with
      $= value ends with

    • User Avatar
      Peter
      Permalink to comment#

      This is what I did to accommodate the ‘home’ page or ‘index’.

      if (location.pathname !== '/') {
      $("a[href*='" + location.pathname + "']").addClass("current");
      } else {
      var home = document.getElementById("home").getElementsByTagName('a')[0];
      home.className = 'current';
      }

      Hope that helps.

    • User Avatar
      Justin
      Permalink to comment#

      I don’t have “/” in my navigation, so the code added “active” class to all my links on the home page. In my case, I did the following so my “/” path doesn’t run the code:

      $(function() {
          if ((location.pathname.split("/")[1]) !== ""){
              $('nav a[href^="/' + location.pathname.split("/")[1] + '"]').addClass('active');
          }
      });
      
  6. User Avatar
    bgdbraba

    Indeed. As well that pages that are called for example /about en /aboutsome are also both ‘active’ when you press ‘about’. Any solution for this, like a sort of exact matching?

  7. User Avatar
    John
    Permalink to comment#

    Hi,

    I couldn’t get the above selector to work, but used this (php specific solution) to match the current URL.

    Hope this helps someone (haven’t thoroughly tested so might have some limitations/unexpected results).

    $(‘nav a[href=””]’).addClass(‘active’);

    • User Avatar
      John
      Permalink to comment#

      My comment above stripped out PHP, so I will adjust, and you will have to use common sense when using it.
      $('nav a[href="<?php echo "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; ? >"]').addClass('active');

  8. User Avatar
    mlotfi
    Permalink to comment#

    Hi,
    I am a newbie here, can you please provide a working example ?
    Thanks.

  9. User Avatar
    Luke Etheridge
    Permalink to comment#

    Hi there guys – does anyone know how this is possible with the absolute url (whole url)?

    I’m sure this is an easy thing to do but I don’t really know where to start with the code…

    Thanks,
    Luke

    • User Avatar
      ArtyPea
      Permalink to comment#
      $(function() {
          var nav = document.getElementById("sticky"),
              anchor = nav.getElementsByTagName("a"),
              current = window.location;
      
          console.log("anchor = ",anchor,"current = ",current);
      
          for (var i = 0; i < anchor.length; i++) {
          if(anchor[i].href == current) {
              anchor[i].className = "active";
      
          }
      
      }
      });
      
  10. User Avatar
    Ramesh Chowdarapally
    Permalink to comment#

    Chris, can you provide a small demo for this?

  11. User Avatar
    Ashok
    Permalink to comment#

    Yes This is Useful…..

  12. User Avatar
    Brian
    Permalink to comment#

    Two quick questions:

    If my url is dynamic, how should I adjust the anchor part of the javascript?
    Is there a pure css method for the active state shown above? Just thought i’d ask. I would use the hover effect for non-js viewers in case anyone should want to know.

  13. User Avatar
    Wesley
    Permalink to comment#

    My situation is similar but different. I need to target a specific nav element with the active class when a non-child document is active. Any ideas on how to do this?

  14. User Avatar
    Vita
    Permalink to comment#

    I implemented a slightly different approach. I try to find the best match for the url and current location. Created a jQuery plugin for this https://github.com/Vitaa/ActiveNavigation

  15. User Avatar
    Jonno

    Any chance you could show how to do this in the PHP please?

  16. User Avatar
    George v
    Permalink to comment#

    TKX
    Vita

  17. User Avatar
    barrett fullerton
    Permalink to comment#

    Quick update not sure if its been said, but if your looking to use this as well as keep a home link as a “/”

    $(function() {
        if ((location.pathname.split("/")[1]) !== ""){
            $('nav a[href^="/' + location.pathname.split("/")[1] + '"]').addClass('active');
        }
        else {
        $('nav li.home-link a').addClass('active');
        }
    });
    

    Just do something to differentiate your home li or a tag, like in the else.

  18. User Avatar
    Alio

    Great Respect! Very helped me!

  19. User Avatar
    Esen
    Permalink to comment#

    I have this solution with vanilla JS and I have a problem. The hash(#) in the url changes slower than the active clases. So I click on the first link and nothing happends, then I click on the second one and the first one got the active class.

    <script>
        document.addEventListener("DOMContentLoaded", function(event) { 
            console.log("Oh, Hello.");
    
            //Preselect all the links 
            var links =  document.querySelectorAll('.nav-class-link');
    
            // Connect the links event-click with the event handler
            for (var i = links.length - 1; i >= 0; i--) {
                links[i].addEventListener('click', updateLinksActiveState);
            }
    
            //Event Handler
            function updateLinksActiveState(){  
                //Check for the active one
                for (var i = links.length - 1; i >= 0; i--) {
                    if(links[i].href.split("#")[1] == location.hash.split("#")[1]){
                        links[i].classList.add('active');
                    }else{
                        links[i].classList.remove('active');
                    }
                }
            }
        });
        </script>
    

Submit a Comment

Posting Code

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.

icon-closeicon-emailicon-linkicon-logo-staricon-menuicon-searchicon-staricon-tag