Components

String Select Menus

Learn how to create and use string select menu components with djs-core.

String select menus (also called dropdowns) allow users to select one or more options from a predefined list of text choices.

String select menus can display up to 25 options and support emojis, descriptions, and custom values. They're perfect for choices that don't change dynamically.

Creating a String Select Menu

String select menus in djs-core are created using the StringSelectMenu class. Each select menu component file in src/components/selects/string/ is automatically registered.

Use string select menus when you have a fixed list of options. For dynamic content (like users, roles, or channels), use the specialized select menu types instead.

Basic Select Menu

import { StringSelectMenu } from "@djs-core/runtime";

export default new StringSelectMenu()
    .setPlaceholder("Choose a color")
    .addOptions([
        { label: "Red", value: "red" },
        { label: "Blue", value: "blue" },
        { label: "Green", value: "green" },
    ])
    .run(async (interaction) => {
        const selectedColor = interaction.values[0];
        await interaction.reply(`You selected: ${selectedColor}`);
    });

Multiple Options

You can add multiple options to a select menu (up to 25 options):

import { StringSelectMenu } from "@djs-core/runtime";

export default new StringSelectMenu()
    .setPlaceholder("Select your language")
    .addOptions([
        { label: "English", value: "en" },
        { label: "French", value: "fr" },
        { label: "Spanish", value: "es" },
        { label: "German", value: "de" },
        { label: "Italian", value: "it" },
    ])
    .run(async (interaction) => {
        const language = interaction.values[0];
        await interaction.reply(`Language set to: ${language}`);
    });

Options with Emojis

You can add emojis to options:

import { StringSelectMenu } from "@djs-core/runtime";

export default new StringSelectMenu()
    .setPlaceholder("Choose your favorite food")
    .addOptions([
        { label: "Pizza", value: "pizza", emoji: "🍕" },
        { label: "Burger", value: "burger", emoji: "🍔" },
        { label: "Sushi", value: "sushi", emoji: "🍣" },
        { label: "Taco", value: "taco", emoji: "🌮" },
    ])
    .run(async (interaction) => {
        const food = interaction.values[0];
        await interaction.reply(`Great choice! ${food} is delicious!`);
    });

Multiple Selections

String select menus can allow users to select multiple options:

import { StringSelectMenu } from "@djs-core/runtime";

export default new StringSelectMenu()
    .setPlaceholder("Select your interests")
    .setMinValues(1)
    .setMaxValues(5)
    .addOptions([
        { label: "Gaming", value: "gaming" },
        { label: "Music", value: "music" },
        { label: "Sports", value: "sports" },
        { label: "Movies", value: "movies" },
        { label: "Books", value: "books" },
    ])
    .run(async (interaction) => {
        const interests = interaction.values;
        await interaction.reply(`You selected: ${interests.join(", ")}`);
    });

Min and Max Values

  • setMinValues(n) - Minimum number of selections required (1-25)
  • setMaxValues(n) - Maximum number of selections allowed (1-25)
import { StringSelectMenu } from "@djs-core/runtime";

export default new StringSelectMenu()
    .setPlaceholder("Select 2-4 tags")
    .setMinValues(2)
    .setMaxValues(4)
    .addOptions([
        { label: "Tag 1", value: "tag1" },
        { label: "Tag 2", value: "tag2" },
        { label: "Tag 3", value: "tag3" },
        { label: "Tag 4", value: "tag4" },
        { label: "Tag 5", value: "tag5" },
    ])
    .run(async (interaction) => {
        const tags = interaction.values;
        await interaction.reply(`Selected ${tags.length} tag(s): ${tags.join(", ")}`);
    });

Using Select Menus in Commands

Select menus are typically sent as part of a command response:

import { Command, StringSelectMenu } from "@djs-core/runtime";
import { ActionRowBuilder } from "discord.js";
import colorSelect from "../../components/selects/string/color";

export default new Command()
    .setDescription("Choose a color")
    .run(async (interaction) => {
        const row = new ActionRowBuilder<StringSelectMenu>().addComponents(
            colorSelect,
        );
        
        await interaction.reply({
            content: "Select a color from the menu below:",
            components: [row],
        });
    });

Select Menu Data

Select menus can receive custom data. Important: The data is not set in the component definition, but when you use the select menu from a command or another component.

Component Definition (without data)

src/components/selects/string/product.ts
import { StringSelectMenu } from "@djs-core/runtime";

export default new StringSelectMenu<{ category: string }>()
    .setPlaceholder("Select a product")
    .run(async (interaction, data) => {
        const product = interaction.values[0];
        await interaction.reply(
            `Selected ${product} from category: ${data.category}`,
        );
    });

Using Select Menu with Data

When using the select menu from a command, set the data:

src/interactions/commands/shop.ts
import { Command, StringSelectMenu } from "@djs-core/runtime";
import { ActionRowBuilder } from "discord.js";
import productSelect from "../../components/selects/string/product";

export default new Command()
    .setDescription("Browse products")
    .addStringOption((option) =>
        option
            .setName("category")
            .setDescription("Product category")
            .setRequired(true),
    )
    .run(async (interaction) => {
        const category = interaction.options.getString("category");
        
        // Set data and add options when using the select menu
        const row = new ActionRowBuilder<StringSelectMenu>().addComponents(
            productSelect
                .setData({ category })
                .addOptions([
                    { label: "Laptop", value: "laptop" },
                    { label: "Phone", value: "phone" },
                    { label: "Tablet", value: "tablet" },
                ]),
        );
        
        await interaction.reply({
            content: `Select a product from ${category}:`,
            components: [row],
        });
    });

Disabled Select Menu

Select menus can be disabled:

import { StringSelectMenu } from "@djs-core/runtime";

export default new StringSelectMenu()
    .setPlaceholder("This menu is disabled")
    .setDisabled(true)
    .addOptions([
        { label: "Option 1", value: "opt1" },
        { label: "Option 2", value: "opt2" },
    ])
    .run(async (interaction) => {
        // This won't be called when disabled
        await interaction.reply("Menu is disabled");
    });

Ephemeral Responses

Select menu responses can be ephemeral:

import { StringSelectMenu } from "@djs-core/runtime";
import { MessageFlags } from "discord.js";

export default new StringSelectMenu()
    .setPlaceholder("Select an option")
    .addOptions([
        { label: "Private Option 1", value: "opt1" },
        { label: "Private Option 2", value: "opt2" },
    ])
    .run(async (interaction) => {
        await interaction.reply({
            content: "This response is only visible to you!",
            flags: [MessageFlags.Ephemeral],
        });
    });

Select Menu Organization

Select menus can be organized in subdirectories:

src/components/selects/string/
  ├── color.ts
  ├── language.ts
  └── settings/
      ├── theme.ts
      └── notification.ts