Enter at least two characters

Bottom Buttons (Bottom)

Docs version: v2.0.1

The Bottom node defines the interactive button area at the bottom of the menu, with three layout modes available: notice, confirmation, and multi. Inside multi.buttons, you can also use type: repeat to generate dynamic button lists.


Configuration Structure#

Bottom:
  type: 'mode_type'   # notice | confirmation | multi
  # Mode-specific configuration...

Type Overview#

Type Name Purpose Common Use Cases
notice Single button mode Displays one confirm button Information confirmation, reward claims, simple submit actions
confirmation Confirm/cancel dual button mode Displays confirm and cancel buttons Purchase confirmation, delete confirmation, dangerous-action confirmation
multi Multi-button matrix mode Displays multiple buttons with configurable columns and optional exit button Main menus, control panels, category entries, complex action menus

Layout Modes And Dynamic Buttons#

notice - Single Button Mode#

Displays only one confirm button, suitable for information display or simple trigger actions.

Configuration:

Field Description
confirm.text Button text, supports color codes and conditions
confirm.width Optional, button width (1-1024)
confirm.actions List of actions to execute on click

Example:

Bottom:
  type: 'notice'
  confirm:
    text: '&a[ Claim Reward ]'
    actions:
      - 'console: give %player_name% diamond 1'
      - 'tell: &aYou claimed a diamond!'
      - 'sound: entity.player.levelup'

confirmation - Confirm/Cancel Dual Button Mode#

Displays confirm and cancel buttons, suitable for dangerous operations requiring secondary confirmation.

Configuration:

Field Description
confirm.text Confirm button text, supports conditions
confirm.width Optional, confirm button width (1-1024)
confirm.actions List of actions to execute on confirm click
deny.text Cancel button text, supports conditions
deny.width Optional, cancel button width (1-1024)
deny.actions List of actions to execute on cancel click

Example:

Bottom:
  type: 'confirmation'
  confirm:
    text: '&a[ Confirm Purchase ]'
    actions:
      - 'console: eco take %player_name% 100'
      - 'console: give %player_name% diamond_sword 1'
      - 'tell: &aPurchase successful!'
      - 'sound: entity.experience_orb.pickup'
  deny:
    text: '&c[ Cancel ]'
    actions:
      - 'tell: &7Purchase cancelled.'
      - 'sound: block.note_block.bass'

multi - Multi-Button Matrix Mode#

multi displays multiple buttons at the bottom of a menu. Buttons under buttons follow YAML declaration order, columns controls how many columns appear per row, and exit can append a separate exit or back button after the matrix.

Basic Format#

Bottom:
  type: multi
  columns: 2

  buttons:
    shop:
      text: '&6[ Shop ]'
      tooltip:
        - '&7Open the server shop'
      actions:
        - 'open: shop/main'

    profile:
      text: '&b[ Profile ]'
      actions:
        - 'open: profile'

    settings:
      text: '&7[ Settings ]'
      actions:
        - 'open: settings'

    admin:
      text: '&c[ Admin Panel ]'
      show-condition: 'hasPerm.kamenu.admin'
      actions:
        - 'open: admin/tools'

  exit:
    text: '&8[ Close ]'
    actions:
      - 'close'

This example generates buttons in shop → profile → settings → admin order and arranges them in two columns. Button IDs such as shop only need to be unique inside the current buttons node.

multi Configuration#

Field Type Default Description
columns Int 2 Number of button columns per row
buttons Node List of buttons (arranged in YAML order)
exit Node Optional exit/return button (displayed at the end of the button list)

Normal Button Configuration#

Field Type Description
show-condition String Optional, button display condition; button is hidden when condition is not met
text String/List Button text, supports color codes, conditions, and MiniMessage tags
width Int Optional, button width (1-1024); uses default width if not set
tooltip List Optional, button hover tooltip (one string per line), supports color codes and MiniMessage
actions List Optional, list of actions to execute on click; if not set, clicking does nothing

Exit Button Configuration#

Field Type Description
text String/List Exit button text, supports color codes, conditions, and MiniMessage tags
width Int Optional exit button width (1-1024)
tooltip List Optional exit button hover tooltip, one string per line
actions List Optional action list; commonly uses close, open, or force-open

Display Conditions#

Normal buttons can use show-condition to control visibility:

Bottom:
  type: multi
  columns: 2
  buttons:
    admin:
      show-condition: 'hasPerm.kamenu.admin'
      text: '&c[ Admin Button ]'
      actions:
        - 'open: admin/tools'

    level_reward:
      show-condition: '%player_level% >= 10'
      text: '&e[ Level 10 Reward ]'
      actions:
        - 'actions: claim_level_reward'

    public:
      text: '&a[ Public Button ]'
      actions:
        - 'tell: &aEvery player can see this button'

Button Width#

Normal buttons and the exit button in multi mode can use width to set their Java Dialog button width:

  • The supported range is 1-1024.
  • When omitted, the default width from the Paper Dialog API is used.
  • Conditions are supported.
  • Width only affects the Java Dialog and does not affect Bedrock forms.
Bottom:
  type: multi
  columns: 2
  buttons:
    wide_button:
      text: '&a[ Wide Button ]'
      width: 200
      actions:
        - 'tell: &aThis is a wide button'

    conditional_width:
      text: '&c[ Conditional Width ]'
      width:
        - condition: '%player_is_op% == true'
          allow: 200
          deny: 100
      actions:
        - 'tell: &cButton width changes based on a condition'

  exit:
    text: '&8[ Exit ]'
    width: 80
    actions:
      - 'close'

An excessively large width may cause a button to extend beyond the screen. Adjust it for the actual layout.

repeat - Dynamic Button Lists#

A button under multi.buttons can use type: repeat to generate real native Dialog buttons from a dynamic data source. This is useful for online player lists, warp lists, friend lists, mail lists, and other content with unknown item counts.

Basic location:

Bottom:
  type: multi
  buttons:
    list_id:
      type: repeat
      source: "data source"
      item:
        text: "&a{item.value}"
        actions:
          - "tell: You clicked {item.value}"
JavaScript:
  getWarpList: |
    JSON.stringify([
      { id: "home", name: "Home", world: "world", x: 100, y: 64, z: 200 },
      { id: "mine", name: "Mine", world: "world", x: -30, y: 12, z: 80 }
    ]);

Bottom:
  type: multi
  columns: 2
  buttons:
    warp_list:
      type: repeat
      source: "[getWarpList]"
      page_size: 20
      item:
        text: "&a{item.name}"
        width: 160
        tooltip:
          - "&7World: &f{item.world}"
          - "&7Location: &f{item.x}, {item.y}, {item.z}"
          - "&eClick to teleport"
        actions:
          - "actions: teleport_warp,{item.id}"
      empty:
        text: "&7No warps"
        actions:
          - "toast: type=task;msg=No data;icon=barrier"

    prev:
      text: "&ePrevious"
      show-condition: "{page:warp_list} > 1"
      actions:
        - "page: warp_list prev"
        - "reset"

    next:
      text: "&eNext"
      show-condition: "{page:warp_list} < {pages:warp_list}"
      actions:
        - "page: warp_list next"
        - "reset"

repeat Configuration:

Field Type Default Description
type String Must be repeat
source String Data source. Recommended format is [functionName], calling a JavaScript function that returns a JSON array
split String Optional separator for non-JSON string lists, such as ","
trim Boolean true Whether to trim each item when split is used
page_size / page-size Int 20 Number of generated buttons per page, range 1-99
item Node Button template for each list item
empty Node Optional button shown when the source has no items

source is resolved through KaMenu internal variables, PAPI, {js:...}, and other text variables first. The resolved result can be a JSON array, newline text, or a simple string list used with split. Items may be objects, strings, or numbers. Object fields become {item.fieldName} and can be used in button text, tooltip, show-condition, and actions.

Matrix alignment:

On every render, KaMenu counts the repeat buttons actually generated on the current page. If that count is not divisible by columns, it appends enough blank buttons to complete the row. For example, with columns: 3 and 28 generated buttons, KaMenu adds 2 blank buttons so the repeat section contains 30 buttons. Blank buttons have no visible text but execute reset when clicked, rebuilding the current menu callback. When item.width is configured, padding buttons reuse that width so the repeat grid stays aligned; otherwise they use the default width. Normal buttons such as Previous/Next are excluded from the repeat count and are appended after the padding buttons.

Built-in list variables {list:key} and {glist:key} return JSON array strings and can be used directly as source:

Bottom:
  type: multi
  buttons:
    friends:
      type: repeat
      source: "{list:friends}"
      item:
        text: "&a{item.value}"
        actions:
          - "tell: You clicked {item.value}"

If the data source returns a simple string list such as player1, player2, player3, use split:

Events:
  Open:
    - "data: type=set;key=recent_players_raw;var=`player1, player2, player3`"

Bottom:
  type: multi
  buttons:
    player_list:
      type: repeat
      source: "{data:recent_players_raw}"
      split: ","
      trim: true
      item:
        text: "&a{item.value}"
        actions:
          - "tell: You clicked {item.value}"

Built-in item variables:

Variable Description
{item.xxx} Field from the current item object
{item.value} Value when the current item is a string or number
{item.index} Index in the full list, starting at 0
{item.number} Number in the full list, starting at 1
{item.page_index} Index on the current page, starting at 0
{item.page_number} Number on the current page, starting at 1

Pagination variables can be used in normal Bottom.buttons and repeat item templates:

Variable Description
{page:listId} Current page
{pages:listId} Total pages
{total:listId} Total item count
{start:listId} Current page start index
{end:listId} Current page end index

Pagination actions:

- "page: warp_list next"
- "page: warp_list prev"
- "page: warp_list 1"
- "page: warp_list +1"
- "page: warp_list -1"

The page: action only changes page state. It does not refresh the dialog by itself. Usually follow it with reset, open, or force-open.


Bedrock Button Icons#

When Geyser and Floodgate are installed, KaMenu can provide button images for menus without input components. KaMenu uses an icon-enabled Floodgate SimpleForm only when all of these conditions are met:

  • The current player joined through Floodgate.
  • The menu has no Inputs components.
  • At least one currently visible button has a valid icon.

Other players and menus continue to use the existing Java Dialog. Menus with Inputs are still converted automatically by Geyser, so their bottom buttons do not support icon.

icon can be configured under Bottom.confirm, Bottom.deny, Bottom.button1, Bottom.buttons.<buttonId>, Bottom.exit, and Bottom.buttons.<repeatId>.item.

URL Images#

Bottom:
  type: multi
  buttons:
    shop:
      text: '&aOpen Shop'
      icon:
        type: url
        value: 'https://example.com/images/shop.png'
      actions:
        - 'open: shop'

Only http and https URLs are accepted, with a maximum length of 2048 characters. The player's client downloads the image directly, so the image host may receive the player's IP address. Use a trusted image host.

Bedrock Resource-Pack Paths#

Bottom:
  type: multi
  buttons:
    reward:
      text: '&eClaim Reward'
      icon:
        type: path
        value: 'textures/items/diamond'
      actions:
        - 'actions: reward'

path refers to an image inside the Bedrock client resource pack, not a file on the server. Absolute paths and paths containing .. are rejected.

A URL can also use the scalar shorthand. Other scalar values are treated as resource-pack paths:

icon: 'https://example.com/images/shop.png'

Dynamic repeat Icons#

Bottom.buttons.<repeatId>.item.icon supports {item.xxx}, PAPI placeholders, and built-in KaMenu variables:

item:
  text: '&f{item.name}'
  icon:
    type: url
    value: '{item.icon}'
  actions:
    - 'tell: &aYou selected {item.name}'

A Bedrock SimpleForm is a vertical button list and has no equivalents for Java Dialog button grids, widths, or tooltips. Therefore, columns, button width, and tooltip do not affect the Bedrock form, and repeat grid-padding buttons are omitted. If a menu button uses a standalone client-side url: or copy: action, the entire menu falls back to the existing Java Dialog conversion so that action keeps working.


Conditional Button Text#

The text field of all buttons supports conditions:

Bottom:
  type: 'confirmation'
  confirm:
    text:
      - condition: "%player_level% >= 10"
        allow: '&6[ VIP Confirm ]'
        deny: '&a[ Confirm ]'
    actions:
      - 'tell: &aConfirmed'
  deny:
    text: '&c[ Cancel ]'
    actions:
      - 'tell: &7Cancelled'

For complete condition syntax, see Conditions.