Craft CMS Stack Exchange is a question and answer site for administrators, end users, developers and designers for Craft CMS. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Just wondering how people approach setting a class of current in their navigation. Is there anything in Craft or Twig where you can set a conditional to check if a page is the current page. Or do you just need to set classes/ids on the body tag based on the segment?

Any ideas appreciated, Gareth

share|improve this question

10 Answers 10

up vote 18 down vote accepted

Tip: To keep it short and reusable I would recommend that you wrap your preferred "check-method" in a Twig macro, I like Anna's version the most:


{% macro is_active(segment) %}{% if craft.request.firstSegment == segment %}active{% endif %}{% endmacro %}


{% import "_macros.html" as macros %}

<a href="{{ url('news') }}" class="{{ macros.is_active('news') }}">News</a>
<a href="{{ url('blog') }}" class="{{ macros.is_active('blog') }}">Blog</a>
share|improve this answer
Wow great addition, thank you Victor. – Gareth Jun 28 '14 at 18:20

Assuming you use a structure called pages to create your navigation and the entry variable represents the currently viewed entry, you can output your navigation and active state as follows:

{% nav page in craft.entries.section('pages') %}
    <li class="{{ == ? 'active' }}">
        {{ }}
        {% ifchildren %}
                {% children %}
        {% endifchildren %}
{% endnav %}

See the nav tag for more details.

If, instead of a structure, you are using a channel called pages for the navigation then the nav tag method above will still work but the following code is leaner and simpler to understand:

{% for page in craft.entries.section('pages') %}
    <li class="{{ == ? 'active' }}">
        {{ }}
{% endfor %}
share|improve this answer
Thanks Ben, I hadn't even looked into the nav tag, this only works for a structured section though, right? Still very useful, thank you. – Gareth Jun 28 '14 at 15:03
it should work for a channel too, i updated my answer above with code for a channel though. – Ben Croker Jun 30 '14 at 9:01
If using this with a dedicated menu section, this shouldn't work? Because nav items in this case are pages too and the ids of a nav item and a page corresponding to it are always different. – certainlyakey Aug 22 '15 at 7:51

craft.request is useful for setting an "active" class based on URL segments.

If your URL was:

You could write conditionals like the following to target each segment:

{% if craft.request.firstSegment == "sale" %}class="active"{% endif %}
{% if craft.request.segment(2) == "products" %}class="active"{% endif %}
{% if craft.request.lastSegment == "shirts" %}class="active"{% endif %}
share|improve this answer
Thanks Anna, I was thinking down this route, great minds :) thank you for your answer - have you seen Victor's suggestion using a macro with your code, looks like a nice we to keep things DRY. – Gareth Jun 28 '14 at 18:18

Barrel Strength also have a URL segment based plugin called Sprout Active, with docs/examples here.

share|improve this answer
Thanks Matt, I'll check it out :) – Gareth Jun 28 '14 at 18:13
Sprout Active is great! I think the best solution for this. – Johannes Lamers Aug 8 '14 at 22:25

In your template you can set a var in twig:

{% set active = 'blog' %}

And then in your navigation you can run an if statement to see what the var is

    <a {% if active = 'homepage' %}class="active"{% endif %}> Home </a>
    <a {% if active = 'blog' %} class="active"{% endif %}> Blog </a>
share|improve this answer
Thank you Rob, this looks as if it works great until you re-use a template. Then I guess you would need to use a craft.request to check the segment variable? – Gareth Jun 28 '14 at 15:07
Yeah you are probably right. For simple sites using Craft Personal you can get away with my above answer. However if you're doing something much larger, you might want to check out @Anna_MediaGirl's answer. – Rob Erskine Jun 30 '14 at 14:36

Here's yet another way you can do it (in some circumstances) and it's nice and DRY:

{% if craft.request.getPath() ==  entry.uri %}
share|improve this answer
That doesn't seem tp work on the index page because entry.uri on the homepage is __home__ – KSPR Dec 5 '14 at 16:17
It only works, if entry URI is requested like this: – Dominik K Sep 1 '15 at 18:05

Another way to achieve this:

    {% for entry in entries %}
      {% set active = craft.request.path ~ '/' matches "|^#{entry.uri}/|" %}
      <a href="{{ entry.url }}" class="{{ active ? 'is-active' : '' }}">{{ entry.title }}</a>
    {% endfor %}

This accounts for even when a navigation item might not be on the top level, but you want every URI that starts with that to trigger the active class.

Note: the pipes around the regex are just the encloser. They can be anything, but since we're dealing with URLs, it's easier not to use the standard /.

share|improve this answer
Great, thank you Tim. – Gareth Aug 29 '14 at 7:54

I add a variable in my "_entry" template.

Here's a basic example:

{% extends "_layout" %}

{% set bodyClass = 'myPageType' %}

{% block content %}
<!-- entry HTML here -->
{% endblock %}

Then in my _layout template, it begins like this:

<!doctype html>
<html class="{% if bodyClass is defined %}{{ bodyClass }}{% endif %}">
<!-- the rest of the template follows -->

Does something like that work for you?

share|improve this answer
Hey, John there are a few different options now, this page has become a great resource, thank you for your answer. – Gareth Jun 28 '14 at 18:20

Here's one more for this nice collection!

This is what I use for a structure "pages" where I needed some way to not only add a class active to the current entry, but also to all of the entry's ancestors. In an Example URL both links beers and wheat-beers should be given the activeclass.

The macro takes the structure entry's uri as one parameter. The other parameter is needed to specify the part of the current URL, the entry's URI gets compared to (→ craft.request.getSegment()).

Give this parameter a value based on the entry's level within its structure.



{% macro activeLinkClass(linkUri, requestSegmentNumber) %}

    {# Request the relevant path segment in the URL #}
    {% set nthRequestSegment = craft.request.segment(requestSegmentNumber) %}

    {# Split the link's URI into a list of path segments #}
    {% set linkSegments = linkUri|split('/') %}

    {# Get the path segment relevant for our comparison #}
    {% set nthLinkSegment = linkSegments[requestSegmentNumber - 1] %}

    {# Return `active` if the nthLinkSegment equals the nthRequestSegment #}
    {% if nthLinkSegment == nthRequestSegment %}active{% endif %}

{% endmacro %}



{% import '_macros.html' as macros %}

{# Get entries from pages structure (exclude home page)  #}
{% set pages = craft.entries.section('pages').id('not 1') %}

{# Loop through entries and list the links #}
{% nav page in pages %}

    {# Add a class `active` if needed, using our macro #}
    <a href="{{ page.url }}" class="nav-link{{ macros.activeLinkClass(page.uri, page.level) }}">
        {{ page.title }}

    {% ifchildren %}{% children %}{% endifchildren %}

{% endnav %}
share|improve this answer

I think comparing the entry id's is the best way to go for the current page. But for determining if a certain page is a parent of the current page, I combined answers from @tim-kelty and @carlcs to come up with this:

{% for entry in entries %}
  {% set isInSection = craft.request.firstSegment == entry.uri|split('/')[0] %}
  <a href="{{ entry.url }}" class="{{ isInSection ? 'active' : '' }}">{{ entry.title }}</a>
{% endfor %}

EDIT: I realized my above code does something slightly different than I originally thought: it will add the 'active' class to any items that are in the current' page's section... which includes siblings. If that's what you want, then it's great. But if you only want to indicate the actual top-level section parent page, then you should do this instead:

{% for entry in entries %}
  {% set isTopParent = craft.request.firstSegment == entry.uri %}
  <a href="{{ entry.url }}" class="{{ isTopParent ? 'active' : '' }}">{{ entry.title }}</a>
{% endfor %}

Last but not least, if you want to hilite all pages that are in the parent "path" of the current page (which is what I most often need in my menus), you can do this:

{# use different var name in the loop because we assume `entry` is already set to the currently-viewed page #}
{% for page in entries %}
  {% set isInPath = entry.uri matches '{^' ~ page.uri ~ '}' %}
  <a href="{{ page.url }}" class="{{ isInPath ? 'active' : '' }}">{{ page.title }}</a>
{% endfor %}

I've posted a full example that encompasses a lot of "denote the active page or its parents" logic here:

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.