or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

assertions.mdcomponents-v2.mdcontext-menu-commands.mdembeds.mdindex.mdmessage-components.mdmodals.mdselect-menus.mdslash-commands.mdutilities.md
tile.json

select-menus.mddocs/

Select Menus

Select menus provide dropdown interfaces for users to choose from predefined options or select Discord entities like users, roles, and channels.

BaseSelectMenuBuilder

Abstract base class for all select menu builders with common functionality.

abstract class BaseSelectMenuBuilder {
  readonly data: Partial<APISelectMenuComponent>;

  constructor(data?: Partial<APISelectMenuComponent>);
  
  setCustomId(customId: string): this;
  setPlaceholder(placeholder: string): this;
  setMinValues(minValues: number): this;
  setMaxValues(maxValues: number): this;
  setDisabled(disabled?: boolean): this;
  
  abstract toJSON(): APISelectMenuComponent;
}

StringSelectMenuBuilder

Select menu with custom string options defined by the developer.

class StringSelectMenuBuilder extends BaseSelectMenuBuilder {
  readonly options: StringSelectMenuOptionBuilder[];

  constructor(data?: APIStringSelectComponent);
  
  addOptions(...options: RestOrArray<StringSelectMenuOptionBuilder | APISelectMenuOption>): this;
  setOptions(...options: RestOrArray<StringSelectMenuOptionBuilder | APISelectMenuOption>): this;
  spliceOptions(index: number, deleteCount: number, ...options: RestOrArray<StringSelectMenuOptionBuilder | APISelectMenuOption>): this;
  
  toJSON(): APIStringSelectComponent;
}

StringSelectMenuOptionBuilder

Individual option for string select menus.

class StringSelectMenuOptionBuilder {
  readonly data: Partial<APISelectMenuOption>;

  constructor(data?: APISelectMenuOption);
  
  setLabel(label: string): this;
  setValue(value: string): this;
  setDescription(description: string): this;
  setDefault(isDefault?: boolean): this;
  setEmoji(emoji: APIMessageComponentEmoji): this;
  
  toJSON(): APISelectMenuOption;
}

UserSelectMenuBuilder

Select menu for choosing Discord users.

class UserSelectMenuBuilder extends BaseSelectMenuBuilder {
  readonly default_users?: Snowflake[];

  constructor(data?: APIUserSelectComponent);
  
  setDefaultUsers(...users: Snowflake[]): this;
  
  toJSON(): APIUserSelectComponent;
}

RoleSelectMenuBuilder

Select menu for choosing Discord roles.

class RoleSelectMenuBuilder extends BaseSelectMenuBuilder {
  readonly default_roles?: Snowflake[];

  constructor(data?: APIRoleSelectComponent);
  
  setDefaultRoles(...roles: Snowflake[]): this;
  
  toJSON(): APIRoleSelectComponent;
}

MentionableSelectMenuBuilder

Select menu for choosing mentionable entities (users or roles).

class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder {
  readonly default_users?: Snowflake[];
  readonly default_roles?: Snowflake[];

  constructor(data?: APIMentionableSelectComponent);
  
  setDefaultUsers(...users: Snowflake[]): this;
  setDefaultRoles(...roles: Snowflake[]): this;
  
  toJSON(): APIMentionableSelectComponent;
}

ChannelSelectMenuBuilder

Select menu for choosing Discord channels with optional channel type filtering.

class ChannelSelectMenuBuilder extends BaseSelectMenuBuilder {
  readonly default_channels?: Snowflake[];
  readonly channel_types?: ChannelType[];

  constructor(data?: APIChannelSelectComponent);
  
  addChannelTypes(...channelTypes: ChannelType[]): this;
  setChannelTypes(...channelTypes: ChannelType[]): this;
  setDefaultChannels(...channels: Snowflake[]): this;
  
  toJSON(): APIChannelSelectComponent;
}

Types

Select Menu Option

interface APISelectMenuOption {
  label: string;
  value: string;
  description?: string;
  emoji?: APIMessageComponentEmoji;
  default?: boolean;
}

Channel Types

enum ChannelType {
  GuildText = 0,
  DM = 1,
  GuildVoice = 2,
  GroupDM = 3,
  GuildCategory = 4,
  GuildAnnouncement = 5,
  AnnouncementThread = 10,
  PublicThread = 11,
  PrivateThread = 12,
  GuildStageVoice = 13,
  GuildDirectory = 14,
  GuildForum = 15,
  GuildMedia = 16
}

Snowflake Type

type Snowflake = string;

Usage Examples

String Select Menu

import { StringSelectMenuBuilder, StringSelectMenuOptionBuilder, ActionRowBuilder } from "@discordjs/builders";

const selectMenu = new StringSelectMenuBuilder()
  .setCustomId('color_select')
  .setPlaceholder('Choose a color')
  .setMinValues(1)
  .setMaxValues(1)
  .addOptions(
    new StringSelectMenuOptionBuilder()
      .setLabel('Red')
      .setValue('red')
      .setDescription('The color of fire')
      .setEmoji({ name: 'πŸ”΄', id: null }),
    new StringSelectMenuOptionBuilder()
      .setLabel('Blue')
      .setValue('blue')
      .setDescription('The color of water')
      .setEmoji({ name: 'πŸ”΅', id: null }),
    new StringSelectMenuOptionBuilder()
      .setLabel('Green')
      .setValue('green')
      .setDescription('The color of nature')
      .setEmoji({ name: '🟒', id: null })
      .setDefault(true) // This option will be selected by default
  );

const row = new ActionRowBuilder<StringSelectMenuBuilder>()
  .addComponents(selectMenu);

Multi-Select String Menu

const multiSelectMenu = new StringSelectMenuBuilder()
  .setCustomId('skills_select')
  .setPlaceholder('Select your skills (up to 3)')
  .setMinValues(1)
  .setMaxValues(3)
  .addOptions([
    {
      label: 'JavaScript',
      value: 'javascript',
      description: 'Web development language'
    },
    {
      label: 'Python',
      value: 'python',
      description: 'Data science and backend'
    },
    {
      label: 'TypeScript',
      value: 'typescript',
      description: 'Type-safe JavaScript'
    },
    {
      label: 'Java',
      value: 'java',
      description: 'Enterprise development'
    }
  ]);

User Select Menu

import { UserSelectMenuBuilder } from "@discordjs/builders";

const userSelect = new UserSelectMenuBuilder()
  .setCustomId('moderator_select')
  .setPlaceholder('Select moderators')
  .setMinValues(1)
  .setMaxValues(5)
  .setDefaultUsers('123456789012345678', '987654321098765432');

Role Select Menu

import { RoleSelectMenuBuilder } from "@discordjs/builders";

const roleSelect = new RoleSelectMenuBuilder()
  .setCustomId('role_select')
  .setPlaceholder('Choose roles to assign')
  .setMinValues(0)
  .setMaxValues(3)
  .setDefaultRoles('555666777888999000');

Channel Select Menu

import { ChannelSelectMenuBuilder, ChannelType } from "@discordjs/builders";

const channelSelect = new ChannelSelectMenuBuilder()
  .setCustomId('channel_select')
  .setPlaceholder('Select a text channel')
  .setMinValues(1)
  .setMaxValues(1)
  .addChannelTypes(ChannelType.GuildText, ChannelType.GuildAnnouncement)
  .setDefaultChannels('111222333444555666');

Mentionable Select Menu

import { MentionableSelectMenuBuilder } from "@discordjs/builders";

const mentionableSelect = new MentionableSelectMenuBuilder()
  .setCustomId('mention_select')
  .setPlaceholder('Select users or roles')
  .setMinValues(1)
  .setMaxValues(10)
  .setDefaultUsers('123456789012345678')
  .setDefaultRoles('987654321098765432');

Dynamic Option Management

const dynamicMenu = new StringSelectMenuBuilder()
  .setCustomId('dynamic_menu')
  .setPlaceholder('Select an option');

// Add options from an array
const gameOptions = [
  { name: 'Chess', value: 'chess', description: 'Strategic board game' },
  { name: 'Checkers', value: 'checkers', description: 'Classic board game' },
  { name: 'Poker', value: 'poker', description: 'Card game' }
];

const optionBuilders = gameOptions.map(game =>
  new StringSelectMenuOptionBuilder()
    .setLabel(game.name)
    .setValue(game.value)
    .setDescription(game.description)
);

dynamicMenu.addOptions(...optionBuilders);

// Replace an option
dynamicMenu.spliceOptions(1, 1,
  new StringSelectMenuOptionBuilder()
    .setLabel('Backgammon')
    .setValue('backgammon')
    .setDescription('Ancient board game')
);

// Set all options at once
dynamicMenu.setOptions(
  new StringSelectMenuOptionBuilder()
    .setLabel('New Game')
    .setValue('new_game')
    .setDescription('A completely new game')
);

Disabled Select Menu

const disabledMenu = new StringSelectMenuBuilder()
  .setCustomId('disabled_menu')
  .setPlaceholder('This menu is disabled')
  .setDisabled(true)
  .addOptions(
    new StringSelectMenuOptionBuilder()
      .setLabel('Option 1')
      .setValue('option1')
  );

Deprecated APIs

These aliases are deprecated and will be removed in the next major version:

// Deprecated - use StringSelectMenuBuilder instead
const SelectMenuBuilder = StringSelectMenuBuilder;

// Deprecated - use StringSelectMenuOptionBuilder instead  
const SelectMenuOptionBuilder = StringSelectMenuOptionBuilder;

Select Menu Limits

Discord enforces these limits on select menus:

  • Options: Maximum 25 options per string select menu
  • Option Label: Maximum 100 characters
  • Option Value: Maximum 100 characters
  • Option Description: Maximum 100 characters
  • Placeholder: Maximum 150 characters
  • Min Values: Minimum 0, maximum 25
  • Max Values: Minimum 1, maximum 25
  • Custom ID: Maximum 100 characters