The Persistent Menu

The persistent menu allows you to have an always-on user interface element inside Messenger conversations. This is an easy way to help people discover and access the core functionality of your Messenger bot at any point in the conversation.

Contents

Requirements

For the persistent menu to appear, the following must be true:

  • The person must be running Messenger v106 or above on iOS or Android.
  • The Facebook Page the Messenger bot is subscribe to must be published.
  • The Messenger bot must be set to "public" in the app settings.
  • The Messenger bot must have the pages_messaging permission.
  • The Messenger bot must have a get started button set.

Supported Buttons

The persistent menu is composed of an array of buttons. The following button types are supported in the persistent menu:

  • web_url: Specifes the item is a URL button.
  • postback: Specifies the item is a postback button.
  • nested: Specifies the item opens a nested menu.

Setting the Persistent Menu

To set the persistent menu, send a POST request to the Messenger Profile API to set the persistent_menu property of your bot's Messenger profile.

The property should include an array of objects with a set of up to 3 buttons to include in the menu in a call_to_actions array.

{
  "persistent_menu":[
    {
      "locale":"default",
      "composer_input_disabled": true,
      "call_to_actions":[
        {
          "title":"My Account",
          "type":"nested",
          "call_to_actions":[
            {
              "title":"Pay Bill",
              "type":"postback",
              "payload":"PAYBILL_PAYLOAD"
            },
            {
              "type":"web_url",
              "title":"Latest News",
              "url":"https://www.messenger.com/",
              "webview_height_ratio":"full"
            }
          ]
        }
      ]
    }
  ]
}

Using Nested Menus

It is often the case that menus need multiple levels. To accomodate this, the persistent menu supports nested menus. To include a nested menu, set "type": "nested" for a menu item, and include a call_to_actions array with up to 5 buttons:

{
  "persistent_menu":[
    {
      "locale":"default",
      "composer_input_disabled": true,
      "call_to_actions":[
        {
          "title":"My Account",
          "type":"nested",
          "call_to_actions":[
            {
              "title":"Pay Bill",
              "type":"postback",
              "payload":"PAYBILL_PAYLOAD"
            },
            {
              "title":"History",
              "type":"postback",
              "payload":"HISTORY_PAYLOAD"
            },
            {
              "title":"Contact Info",
              "type":"postback",
              "payload":"CONTACT_INFO_PAYLOAD"
            }
          ]
        },
        {
          "type":"web_url",
          "title":"Latest News",
          "url":"http://www.messenger.com/",
          "webview_height_ratio":"full"
        }
      ]
    },
    {
      "locale":"zh_CN",
      "composer_input_disabled":false,
      "call_to_actions":[
        {
          "title":"Pay Bill",
          "type":"postback",
          "payload":"PAYBILL_PAYLOAD"
        }
      ]    
    }
  ]
}

Disabling the Composer

You may disable the composer to make the persistent menu the only way for a person to interact with your Messenger bot. This is useful if your bot has a very specific purpose or set of options.

To do this, set "composer_input_disabled":true when you create the persistent menu.

Localization

You may provide default and localized button text for the persistent menu that will be displayed based on a person's locale.

To do this, specify a separate object in the persistent_menu array for each locale. To specify the locale for each object, set the locale property to a supported locale:

{
  "locale":"default",
  "call_to_actions":[...]
},
{
  "locale: "zh_CN",
  "call_to_actions":[...]
}

Refreshing the Persistent Menu

The persistent menu is cached locally, but updates are fetched periodically. If you update the menu while testing, you can force this fetch to happen by deleting the conversation and beginning a new one.

Best Practices

Like buttons, menu items can produce a webview or postback. They can also drill down to a second-level menu. Your menu is the same for all users of your bot: you can't make per-user changes or change it in real time.

Use the menu for entry points into your bot's functionality.

Be descriptive: your menu lets people know what your bot can do. It instantly lets users know what they can reach for your bot for in the future.

Use sub-menus and hierarchy that match your user's mental model of your functionality.

Don't expect the menu to contain user-specific data: it's the same for everyone who uses your bot, though it can be localized.

Don't put a "Menu" button in the menu that sends the user a message containing a menu. Just put that content directly in the menu — that's what it's for!

Don't put generic actions like "Restart" in the menu.

Don't use prime menu real estate for secondary, "colophon" style info like about, terms of service, privacy policy, or "powered by", neglecting to expose your bot's main functionality. If you want to include these items, consider placing them in a sub-menu.