Help us test the new header code!

When Dropdown is activated
And I click on the home logo
Then Dropdown should be dismissed on click

I remember fixing this last time but can’t seem to find the issue on meta anymore

1 Like

I deployed on our production site yesterday with no issues, FWIW…

1 Like

It’s pretty stable now. There might be one or two little quirks but nothing your users should ever notice or worry about in a serious way.


Granted if you have plugins that interact with said header, you probably still want to wait.


I’d love to help any plugins get updated. I know babble is quite far behind the latest plugin apis, but are there others?


Quick Messaging (no idea on how far behind it may be). But that is the only other one that comes to the top of my head.

Well the API is not going to change now, and all the widgets support the decorateWidget things for inserting elements. I’d encourage all the plugin authors to update to the new API and please ask me questions if you need pointers!

1 Like

My site uses a plugin that put a little icon for Mumble in the header with a server display, but I don’t know how much it’s used outside of us. I was planning to just wait for Babble/Quick Messages to update and use them as a reference to try and update the Mumble plugin.


Question: How do I now add custom menu items into the hamburger menu?

Previously I would use:

<script type='text/x-handlebars' data-template-name='/connectors/site-map-links/events'>
<li><a href="" title="Events" class="events-link" target="_blank">Events</a></li>

I’m not seeing a obvious way of adding the menu items in the right place (after badges and users, before categories).



It’s different now. So far it’s possible to add an admin links:

<script type="text/discourse-plugin" version="0.3">
  api.decorateWidget('hamburger-menu:admin-links', helper => {
    var links = [];
    links.push({ href: '',
                 rawLabel: "Events",
                 className: "events-link",
                 contents: () => "Events" });

    return => helper.attach('link', l));

It’s not possible to decorate other place yet. And I am not sure how to capture click event for this.

I can submit a PR to add a decorator for the right spot. Moreover, I wish I can decorate panel (panelContents) at will, i.e. messing around order, stuffs other than links. Don’t know whether this idea makes any sense.


I’ve taken a first pass at updating Quick Messages to the new header logic

@eviltrout Some issues / questions / thoughts:

  1. Could you break out the avatarImg method from the post widget? It seems to be a useful general way to include avatars in widgets.

  2. It’s a little inconvenient to add new menus to the header widget because the widget contents are wrapped inside html in the render function. I ended up adding the quick message menu itself as another list item after the quick message icon.

    edit I’m probably missing something, but there seems to be a similar issue for the Header Search Plugin. If I insert it after the home-logo widget, i.e. api.decorateWidget('home-logo:after' ... it ends up inside the title element, which leads to conflicts with the home-logo click event…

  3. I’m wondering what the point of having widget events as separate from widget actions is? i.e. when would you use an event instead of an action?

  4. Following your lead with the _notificationsChanged function, I put my observers for messages in the site-header component and then re-rendered all of the header widgets when the observer fires. This pattern doesn’t feel amazing. Thoughts on best practices in this kind of situation?




So the way I ended up handling this for now is by overriding the ‘click’ event in the home-logo and popping the routeTo function in a condition that checks if the target is the site logo

      api.attachWidgetAction('home-logo', 'click', function(e) {
        if (wantsNewWindow(e)) { return false; }
        if ( === 'site-logo') {
        return false;

ps. I’ve finished widgetizing the header-search plugin:


Would it be possible to create a widget and attach it before another using decorateWidget so that you can put your own click handler in there?

  1. Sure I think that’s a good idea. I’m in the middle of other work right now but if you did a PR for that I’d accept it :slight_smile:

  2. What we could do is add a new decorator target in this case. Something like header:afterPanels. Then it could be added that way.

  3. When you say events are you talking about browser events like click or the app-events? Both exist for different reasons.

  4. It’s a serious downside of the widget approach - they are meant to only update when you interact with them. This is a pattern that came out of creating it for our post stream, where the vast majority of rendering only ever had to happen following a click of some sort. If your data is coming in via a different mechanism (say our message bus) I recommend you use the app-events to trigger a rerender. If your data comes in via interacting with the header you shouldn’t need to do anything. The observer thing was mostly there to simplify and reuse the previous code. If I coded it from scratch I would probably just use app-events for it.


@eviltrout do you have any plans for the addition of user menu items?

I’m finding mobile users are having issues navigating and wanting the sites custom menu links back.

If you checkout the latest version of Discourse you can now add links to the general section like this:

<script type="text/discourse-plugin" version="0.4">
  api.decorateWidget('hamburger-menu:generalLinks', () => {
    return { href: '/users/eviltrout', rawLabel: 'evil trout' };

Currently this doesn’t work for domains different to the Discourse install.

So for a setup where:

  • Discourse is installed at:
  • And the blog / homepage is at:

Using this code to add a non-Discourse instance domain link:

<script type="text/discourse-plugin" version="0.4">
  api.decorateWidget('hamburger-menu:generalLinks', () => {
    return { href: '', rawLabel: 'Example' };

Links to (when clicked):
instead of:

The HTML is correct, so I’m guessing the click handler does something funky.

EDIT: Thank you so much for adding this! :fonzie:

EDIT #2: I attempted to add permalinks to the Discourse instance to work around this and redirect to the correct external link. This however didn’t work it appears permalinks are not followed by the menu links, however permalinks are followed when the link appears in post content.

1 Like

Fixed here:


Yay! Thanks - can confirm links to external sites work.

Although it’s not important to me, I also tested a link to a Discourse “permalink”, this simply displayed the standard “not found” page.