Custom top navigation links

This is a theme component that will allow you to add links to Discourse top navigation.

Repository link:






A navigation link needs three things

  • Name
  • Description
  • Path or URL

Name is the text for the link that shows up on the menu. Description shows up when you hover the name like this:

Path/URL is where you want the link to go.

You can add links as semicolon delimited values in theme settings following this order


URL can also be relative like






How do I install this theme?

follow the official theme installation guide here:

Then add the component to your theme as a theme component and you’re all set!


Thanks a lot,
Is there chance to have menus whit sub-menus.

I’ll love to try link many urls we use.
To keep clear look it will be great to have submenus.


This is an excellent addition to our forum! :smiley: Thank you so much!

Can we also have the option to open links on a New Tab? That’ll be beneficial for 3rd party links.



You’re most welcome.

So, because this theme extends the native navigation functionality in Discourse these features will not be available right away.

Sub-menus are not within the scope of this theme and even if I get something to work it would not be optimal. I think a separate theme component works better for this.

As far as opening links in a new tab, the assumption is that your navigation links will point to pages on your site and so there’s no built-in functionality to open top nav links in a new tab. However, you can do something like:

:warning: This is very rudimentary

<script type="text/discourse-plugin" version="0.8.18">
api.onPageChange(() => {
  $("#navigation-bar a").each(function() {
    var a = new RegExp("/" + + "/");
    if (!a.test(this.href)) {
      $(this).attr("target", "_blank");

What this will do is check if a nav link points to an external site and then opens it in a new tab instead. This could be vastly improved but will have to do until I have a bit more time to refine it.

New features!

Thanks to incredible contributions by @Simon_Cossar :fire: This component will now automatically check the page you’re on and highlight it. This matches the native behaviour in Discourse.

That’s the short story.

Now here’s the long (really long) version of this:

A bit more details about Latest / Top.

To make this easier to follow let’s use Theme creator as an example.

You visit theme creator and you get this:

The nav menu has 3 items, Latest, Top and Categories. Notice the highlight is on Latest.

The paths for those items are:


So far so good, now let’s go into the Movies category:

Now you see the category dropdown indicates that the current category is Movies and that highlight is on Latest. But there’a very big difference here.

These “Latest” and “Top” nav links are not the same from before. They are relative to the current category. Here’s what the paths look like:


This means that clicking Latest while in the Movies category shows you the latest in it and not on the top-level like /latest does

So why do I need to know any of this?

Well, let’s continue with theme creator. Let’s say I install this component and add a Movies link to the top navigation like so - notice the highlight is on the top level Latest or ( /latest )

Clicking this link takes you to /c/movies

So the category dropdown shows we’re on Movies and the new nav link is highlighted indicating that we’re on Movies.

So what happens if you click on latest now? This:

The category drop-down points to Movies, highlight points to latest and the Movies nav link is not highlighted This is the type of thing that will make Steve Krug think, which I hear he doesn’t like to do too much :sweat_smile:

The actual path is /c/movies/l/latest which means latest in movies. The same applies with Top.

So, now that you’ve read through all of that, you’re in a good position to make a judgement based on your needs.

Do you need the per-category filters of Top and Latest in the top nav? Or will top-level Latest and Top (/latest & /top) and using these be enough for your community?

So let’s say you’re OK with removing per-category filters from the navigation menu, what then?

Enter Minimal mode!

I’ve added two new settings in this version:

Hide dropdowns will hide these two:


And Hide default links will hide the default Latest and Categories links from the nav menu

I’ve kept those two separate because you might want to hide one but keep the other option visible.

So, let’s see what everything looks like with both on, but before we do that,

you have to change one of your site settings top_menu to look like this (same order!):

New and Unread are 100% optional, but Latest has to be #1 and Categories #2 for this to work right.

Here’s the result:

I don’t know about you but that looks too minimal to me :sweat_smile:

Now we have to create our own navigation. The placeholder or default for the links setting looks like this:

Latest;topics with recent posts;/latest
Categories;all topics grouped by category;/categories
Top;the most active topics in the last year, month, week or day;/top

This is enough to restore those three. You can then add more links.

Let’s go back to the theme creator example:

Let’s say I leave the three “default” values from above and I add two more links. One for the Movies category and one for the Art tag.

Here’s what that would look like:

The path is /latest and shows top-level latest posts.

Now let’s click on the Movies category:

So far so good, we’re on /c/movies and the the nav link for Movies is highlighted.

Now here’s where things change.

Clicking either Latest or Top now will take you to the top-level Latest and Top pages

So you end up going to /latest instead of /c/movies/l/latest and the same for Top.

The same thing happens with tag link “Art” that we added:

This is a lot less confusing and like I mentioned you can still use these filters inside categories / tags :

And if you prefer to keep the dropdowns if you have a large number of categories and tags, there’s no harm in that as well. Just disable the hide_dropdowns setting and things will look like this:

Clicking Latest above will still take you to top-level /latest just like the previous example.

That’s all. You’re now ready to make an informed decision based on your needs.

Update the theme and hack away!

Please let me know if anything is not clear enough.


Nice theme! I don’t know if this is can replace my code?

I added this code. And it worked!

Discourse.ExternalNavItem = Discourse.NavItem.extend({
    href : function() {
      return this.get('href');
  }); = { title: "Liste", help: "Liste des formations" };

    buildList : function(category, args) {
      var list = this._super(category, args);
      if(category && == "Formations") {
        list.push(Discourse.ExternalNavItem.create({href: '/t/liste-2-0-des-formations-sur-lautosuffisance-et-la-consommation-ecoresponsable-en-2018/306', name: 'liste'}));
      return list;

I wanted to add a topic to top nav but not on all categories, just a specific one. I did a topic on this.


1 Like

No, what you have is more specific, this component will add the links to all categories.

However, I don’t think there would be an issue with using both at the same time. Your code to add a particular link to a specific category and the theme to add general links to all categories.


I added a category to nav links. when I go to another category page, the nav link turns to somthing like https://myforum/c/c/category, instead of https://myforum/c/category .

What’s the string you are trying to add?
I just test this component and it works fine

1 Like

If you are using relative links, maybe you’re missing a leading /? As in, if your link is currently c/category it should be /c/category.


Yes. This was exactly my problem. I missed a /. Thanks.


How to open in new tab?

I will always worship your work and depth of explanation, @Johani :heart:


Hi Team,

This is a great component thank you, does anyone know if there is a way to only display this nav link within a specific category?

Sure, just create a new theme component and add

.category-navigation li a[href=""] {
    display: none;
.category-CATEGORY-SLUG li a[href=""] {
    display: block;


  • is the link or path of the button
  • and .category-CATEGORY-SLUG is the category slug that appears in the category URL (it can be different from the category name). As example theme is the category slug for the #theme category: image, so this is what I should use in this example: .category-theme

Awesome thank you, this was super helpful,

 .category-navigation li a[href=""] {
display: none;

.category-Upcoming-Features li a[href=""] {
 display: block;

Hi Dax,

This works great, thank you, however while the nav link does not show in other categories other than my target category, it does show on the main home page / category list page. could I also hide it on this page too?

I think I cracked it,

I tried targeting the .list-controls class to hide the link from the font page, this seemed to work.

Thank you again

.category-navigation li a[href=""] {
    display: none;

.list-controls li a[href=""] {
    display: none;

.category-Upcoming-Features li a[href=""] {
    display: block;
    padding-top: 6px;
    color: #08c;
    background-color: #a3e0ff;
    border-radius: 28px;

This component has an annoying quirk in that if you start typing a new link and then change to another tab, what you entered so far will be lost. Chrome 73 if that’s relevant.

Though actually, this is a common problem for all custom drop down settings, such as “discourse local dates default formats” in the main settings.


Hi, Thanks for your awesome work!
There are two issues I encountered.

My setting:
Top menu in discourse setting: latest, categories
Nav links in theme:

  • latest: /
  • custom item: /c/xxx (which is a father category contains many sub-categories)
  • /categories
  • /top

When I am in homepage /, all work fine.

When I click #2 custom item, the latest item is missing.

When I click #3 categories, all work fine. When I click #4, there appears another top item in the front!

It looks fantastic.

Is it possible to load a tag within a category?

I’m trying to divide the kanban board plugin from general discussion (and also add a team calendar to each category or tag)

So users would need to stay in the same tag page or category, and load the tag after as a second filter when clicking the on it

For example: /tags/reactjs/discuss