Menu active class not Working on post

I am using this code to create a menu for my category pages. It works when I open a category. However, the active class is lost when I open a post in a category. I would like the active class to be highlighted when a post in a category is open. Is there a simple way to achieve that?

It sounds like you have each of your categories listed as pages in your navbar.

And when on the current category it is active.

Your question is how to highlight a category when on a post inside a category.


To do this you need to get the categories on the current page, in your layout

First I’d experiment on one post and then handle HTML later.

---
title: My title
category: abc
---

{{ post.categories }}

Or use page.categories

A post can be in more that one category if they are nested. So i will assume you won’t do that, to keep it simple.

Still, post.categories will be an array. So you’ll have to get the first category.

---
category: abc
---

{% assign cat = post.categories | first %}

And then make a mock navbar. I’m assuming you have page abc.md exist as your list of posts in the abc category.

Content for one post:

---
title: My title
category: abc
---

{% assign cat_page = post.categories | first | append: '.md' %}

{% for p in site.pages %}
- [{{ p.title }}]({{ p.url | relative_url }}) {% if p.name == cat_page %}Active{% endif %}
{% endfor %}

Then you can transfer that logic to your HTML. Like if you have nav.html that is used by page.html and post.html layouts.

Sorry. But I did not understand a thing. There is no simpler way for a beginner to follow? Anyways, I have the page.category assigned per post and the posts are also inside folders with the same name as categories in the _posts folder. I also have the category added in each post under the title.

Sorry I didn’t have a short answer because it wasn’t a simple solution.

I was suggesting get the first category of a page

And then compare that against the current page.

<nav>
  <a href="/my-category/" {% if page.url = '/my-category/' or page.categories[0] = 'my-category' %} class="active" {% endif %}>My category</a>
</nav>

I have an idea of another solution

Why don’t you check if the post path starts with / contains the category ?

Given a category page with url /my-category/, you can mark that category as active if the current post URL like /my-category/2021/01/01-title.html starts with the category

<nav>
  <a href="/my-category/" {% if page.url = '/my-category/' or page.url contains '/my-category/' %} class="active" {% endif %}>My category</a>
</nav>

Both solutions assume you have the category page as:

my-category.md

---
title: My category 
permalink: /my-category/
---

To avoid having my-category.html

I don’t use the category in the permalink. just the title. So I don’t think both solutions will work. Thanks anyway.

1 Like

My category pages are auto-generated by the Jekyll Paginate v2 plugin. Let me try and create the category.md file instead and get back. Both codes are throwing errors in build time though due to the = sign.

Solved using page.path

1 Like

I don’t see how that will work because then Journal is active for any post not just a Journal category post with Journal in the URL

Also page.type == 'post' is more elegant than looking at _posts in the path

I only borrowed this part page.path contains "_posts/" and implemented it inside the original code, and since my posts are grouped into folders which form the categories, then the link is _posts/folder-name for each menu link for each category. But I would be open for a better suggestion if you have one for this scenario since I am not sure page.type will work.

Edit: Seems this only works with hard coded menus and not those inside _data folder

Oh yeah I assumed you just had frontmatter for category

But if you use a directory then yes you can check

page.path contains '_posts/my-category'

You can also use url. Which works both for posts and the category page itself.

page.url contains '/my-category/'