# Reuse Discourse Hamburger Functionality

**URL:** https://meta.discourse.org/t/reuse-discourse-hamburger-functionality/85578
**Category:** Support
**Created:** [April 17, 2018, 9:42pm UTC](https://meta.discourse.org/t/reuse-discourse-hamburger-functionality/85578 "2018-04-17T21:42:12Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![sarahann](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sarahann/32/96703_2.png) [@sarahann](https://meta.discourse.org/u/sarahann)
#### Post date: [April 17, 2018, 9:42pm UTC](https://meta.discourse.org/t/reuse-discourse-hamburger-functionality/85578/1 "2018-04-17T21:42:12Z")

</div>

Hello Discourse Team!

I am using the discourse CLI [Install the Discourse Theme CLI console app to help you build themes](https://meta.discourse.org/t/discourse-theme-cli-console-app-to-help-you-build-themes/82950) and the plugin API [A versioned API for client side plugins](https://meta.discourse.org/t/a-new-versioned-api-for-client-side-plugins/40051) to help me create my theme.

I have added a custom header in the header.html file. On mobile, I was hoping to create a hamburger menu that functions like discourse’s hamburger

 ![image](https://global.discourse-cdn.com/meta/original/3X/6/e/6ec0452e0ded284f56454826b9aea1159a70efcb.jpg)  
But has completely different menu contents.

I could create the hamburger and menu with my knowledge of css/html/js. But I was hoping for a way to use the functionality that discourse has already implemented (opening, closing, etc..).

Any suggestions on how to achieve this?

- I thought maybe I would be able to extend the widget for the current navigation, change the settings, then attach it to the html I have written for my nav. But the connectors seemed to be predefined, and I wasnt sure how to connect my widget to my html. This might not be the right direction at all either…

---

<div class="post-metadata">

### Author: ![sarahann](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sarahann/32/96703_2.png) [@sarahann](https://meta.discourse.org/u/sarahann)
#### Post date: [April 18, 2018, 5:06pm UTC](https://meta.discourse.org/t/reuse-discourse-hamburger-functionality/85578/2 "2018-04-18T17:06:28Z")

</div>

Okay, so I think I have a better understanding on what I am trying to do.

I would like to create a connector where I can connect to one of the elements that I have added to the page.

I’m guessing this isn’t possible???

The plugin API ([https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/lib/plugin-api.js.es6#L11](https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/lib/plugin-api.js.es6#L11)) has api.registerConnectorClass but I cannot seem to figure out how to connect this to my custom element.

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [April 18, 2018, 10:47pm UTC](https://meta.discourse.org/t/reuse-discourse-hamburger-functionality/85578/4 "2018-04-18T22:47:02Z")

</div>

> [@sarahann](#):
>
> On mobile, I was hoping to create a hamburger menu that functions like discourse’s hamburger

The [Brand Header](https://meta.discourse.org/t/brand-header-theme-component/77977) might give you some ideas about how to approach this. You can find its code here: [GitHub - discourse/discourse-brand-header: Brand header theme component for Discourse · GitHub](https://github.com/discourse/discourse-brand-header). It only displays a hamburger menu in mobile mode. You can get the mobile view on a desktop by appending  
`?mobile_view=1` to your forum’s URL.

---

<div class="post-metadata">

### Author: ![awesomerobot](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/awesomerobot/32/142900_2.png) [@awesomerobot](https://meta.discourse.org/u/awesomerobot)
#### Post date: [April 19, 2018, 1:17am UTC](https://meta.discourse.org/t/reuse-discourse-hamburger-functionality/85578/5 "2018-04-19T01:17:59Z")

</div>

This is slightly rough but should get you 99% of the way there when it comes to having an additional menu item with a dropdown panel. Calling this one a pizza menu 🍕. Add this to your header.html file.

```JS
<script type="text/discourse-plugin" version="0.8">
        
api.createWidget('pizza-menu', {
  tagName: 'div.pizza-panel',

  panelContents() {
    return "hello world";
  },

  html() {
    return this.attach('menu-panel', {
      contents: () => this.panelContents()
    });
  },

  clickOutside() {
    this.sendWidgetAction('togglePizza');
  }
});
    
api.decorateWidget('header-icons:after', function(helper) {
  const headerState = helper.widget.parentWidget.state;
  let contents = [];
    contents.push(helper.attach('header-dropdown', {
      title: 'pizza-menu',
      icon: 'cutlery',
      active: headerState.pizzaVisible,
      iconId: 'toggle-pizza-menu',
      action: 'togglePizza',
    }));
    if (headerState.pizzaVisible) {
            contents.push(helper.attach('pizza-menu'));
    }
    return contents;
});

api.attachWidgetAction('header', 'togglePizza', function() {
  this.state.pizzaVisible = !this.state.pizzaVisible;
});

</script>
        

```

---

<div class="post-metadata">

### Author: ![sarahann](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sarahann/32/96703_2.png) [@sarahann](https://meta.discourse.org/u/sarahann)
#### Post date: [April 19, 2018, 7:51pm UTC](https://meta.discourse.org/t/reuse-discourse-hamburger-functionality/85578/6 "2018-04-19T19:51:34Z")

</div>

Yes! This is very close!

My only concern was the connect part:

> [@awesomerobot](#):
>
> api.attachWidgetAction(‘header’, ‘togglePizza’, function() {  
> this.state.pizzaVisible = !this.state.pizzaVisible;  
> });

What if I wanted to add the pizza menu to a custom HTML element (defined in common/head\_tag.html)?

---

<div class="post-metadata">

### Author: ![awesomerobot](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/awesomerobot/32/142900_2.png) [@awesomerobot](https://meta.discourse.org/u/awesomerobot)
#### Post date: [April 20, 2018, 6:18pm UTC](https://meta.discourse.org/t/reuse-discourse-hamburger-functionality/85578/7 "2018-04-20T18:18:34Z")

</div>

Ah ok in that case you’re looking at something more like what @simon mentioned in the brand header theme component, I was attaching the action to the existing header widget… the brand header adds it to a new one. The new widget here w/ toggleHamburger:

```plaintext
 api.createWidget('brand-header', {
    tagName: 'header.b-header.clearfix',
    buildKey: () => `header`,
  
    defaultState() {
      let states = {
        hamburgerVisible: false
      };
  
      return states;
    },
  
    toggleHamburger() {
      this.state.hamburgerVisible = !this.state.hamburgerVisible;
    },

```

and then the action is added to an HTML element in another widget here

```plaintext
api.createWidget('brand-header-icons', {
    tagName: 'ul.icons.clearfix',
  
    buildAttributes() {
      return { role: 'navigation' };
    },
  
    html(attrs) {
      const hamburger = this.attach('header-dropdown', {
                              title: 'hamburger_brand_menu',
                              icon: 'bars',
                              iconId: 'toggle-hamburger-brand-menu',
                              active: attrs.hamburgerVisible,
                              action: 'toggleHamburger'
                            });
      const icons = [hamburger];
      return icons;
    },
  });

```

---

<div class="post-metadata">

### Author: ![kimardenmiller](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kimardenmiller/32/119631_2.png) [@kimardenmiller](https://meta.discourse.org/u/kimardenmiller)
#### Post date: [March 30, 2019, 7:00am UTC](https://meta.discourse.org/t/reuse-discourse-hamburger-functionality/85578/8 "2019-03-30T07:00:20Z")

</div>

> [@awesomerobot](#):
>
> Calling this one a pizza menu 🍕.

Thank you for this code. Can you point me in the right direction on filling out the panelContents? [I see some indication](https://github.com/discourse/discourse/blob/b58867b6e936a5247304e9f06f827cf5012a92ed/app/assets/javascripts/discourse/widgets/hamburger-menu.js.es6), but not sure how it all links together.

---

<div class="post-metadata">

### Author: ![Queth](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/queth/32/154753_2.png) [@Queth](https://meta.discourse.org/u/Queth)
#### Post date: [January 2, 2020, 5:55pm UTC](https://meta.discourse.org/t/reuse-discourse-hamburger-functionality/85578/9 "2020-01-02T17:55:53Z")

</div>

hello! I know this is an old topic but this is almost what I’m looking for/trying to do. So therefore I post here (instead of making a new topic). Please bear in mind that I am not a developer and I don’t know how the plugins work and I cannot write javascript. But I know how to copy-paste code 😉

What I’m trying to do is add login to a chatroom inside a dropdown menu. Thus, I want a “chat” icon, and in the dropdown menu will be an input field and a submit button, and some help text / link to help page.

Can I adapt your code then, instead of the ‘cutlery’ icon a ‘chat’ icon, how to do that?  
and secondly, how can I insert HTML code instead of the ‘hello world’ statement. (basically how to enter HTML in there?

thank you very much in advance!

---

<div class="post-metadata">

### Author: ![ngets](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ngets/32/185583_2.png) [@ngets](https://meta.discourse.org/u/ngets)
#### Post date: [July 2, 2020, 9:34am UTC](https://meta.discourse.org/t/reuse-discourse-hamburger-functionality/85578/10 "2020-07-02T09:34:44Z")

</div>

In relation to Queth’s post, is it possible to insert an additional link right before FAQ on the dropdown panel?

This component could work. Just have to move the custom link right before FAQ  
[https://meta.discourse.org/t/custom-hamburger-menu-links/87644/41](https://meta.discourse.org/t/custom-hamburger-menu-links/87644/41)

---

<div class="post-metadata">

### Author: ![spirobel](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/spirobel/32/170908_2.png) [@spirobel](https://meta.discourse.org/u/spirobel)
#### Post date: [July 2, 2020, 2:32pm UTC](https://meta.discourse.org/t/reuse-discourse-hamburger-functionality/85578/11 "2020-07-02T14:32:46Z")

</div>

haha by coincidence I am looking at exactly the same thing too. I think the best way is to reopen the hamburger-menu widget and override the html method.

> <https://github.com/discourse/discourse/blob/c200238bdc241586bfe82b2d0fc1f600fec45b1f/app/assets/javascripts/discourse/app/widgets/hamburger-menu.js#L328>

I will [unshift](https://www.hostingadvice.com/how-to/javascript-add-to-array/) my widget in front of the faq thingy. I didnt check if it works, but that will be my approach 😃  
Here it seems to work

```javascript
  api.reopenWidget("hamburger-menu", {

      html() {
        let conti = this.panelContents()
        conti.unshift(h('div',[h('span','blabla description: '),this.attach('widget-dropdown',
  {id: "from", translatedLabel: "bla",onChange: "changeaction",
  content: [
      { id: 1, label: "foo.bar" },
      { id: 2, translatedLabel: "FooBar" },
      { id: 3, label: "foo.baz", icon: "times" },
      { id: 4, html: "<b>foo</b>" },
    ],
    options: {bodyClass: "lang-drop-body"}
  })]))
        return this.attach("menu-panel", {
          contents: () => conti,
          maxWidth: this.settings.maxWidth
        });
      },
  });

```

I added a dropdown for example.  
cheers

---

<div class="post-metadata">

### Author: ![ngets](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ngets/32/185583_2.png) [@ngets](https://meta.discourse.org/u/ngets)
#### Post date: [July 10, 2020, 5:38am UTC](https://meta.discourse.org/t/reuse-discourse-hamburger-functionality/85578/12 "2020-07-10T05:38:46Z")

</div>

Hi, how can I place this right after the search icon? And how to add custom html inside panelContents?
