Components V2 Documentation

Build interactive Discord components with NoveCord's Components V2 system. Create buttons, select menus, modals, and text inputs that follow Discord's latest specifications.

ButtonBuilder

Create interactive buttons that users can click to trigger actions in your Discord bot.

Basic Usage

const { ButtonBuilder } = require('novecord');
const button = new ButtonBuilder()
.setLabel('Click Me!')
.setStyle(1) // Primary style
.setCustomId('my_button')
.build();
// Send with message
client.sendMessage(channelId, {
content: 'Here is a button:',
components: [button]
});

Button Styles

StyleValueColor
Primary1Blue
Secondary2Gray
Success3Green
Danger4Red
Link5Gray (with URL)

Advanced Button Example

const { ButtonBuilder } = require('novecord');
// Create multiple buttons
const confirmButton = new ButtonBuilder()
.setLabel('Confirm')
.setStyle(3) // Success/Green
.setCustomId('confirm_action')
.setEmoji('✅')
.build();
const cancelButton = new ButtonBuilder()
.setLabel('Cancel')
.setStyle(4) // Danger/Red
.setCustomId('cancel_action')
.setEmoji('❌')
.build();
const linkButton = new ButtonBuilder()
.setLabel('Visit Website')
.setStyle(5) // Link
.setUrl('https://novecord.vercel.app')
.build();
// Send all buttons together
client.sendMessage(channelId, {
content: 'Choose an action:',
components: [confirmButton, cancelButton, linkButton]
});

ButtonBuilder Methods

  • .setLabel(text) - Set button text
  • .setStyle(number) - Set button style (1-5)
  • .setCustomId(id) - Set custom ID for interaction handling
  • .setUrl(url) - Set URL for link buttons (style 5)
  • .setEmoji(emoji) - Add emoji to button
  • .setDisabled(boolean) - Enable/disable button
  • .build() - Build the final button object

SelectMenuBuilder

Create dropdown select menus that allow users to choose from multiple options.

Basic Usage

const { SelectMenuBuilder } = require('novecord');
const selectMenu = new SelectMenuBuilder()
.setCustomId('role_select')
.setPlaceholder('Choose your role...')
.addOption('Developer', 'dev', 'Programming and development')
.addOption('Designer', 'design', 'UI/UX and graphic design')
.addOption('Manager', 'mgmt', 'Project and team management')
.setMinValues(1)
.setMaxValues(1)
.build();
client.sendMessage(channelId, {
content: 'Select your role:',
components: [selectMenu]
});

Advanced Select Menu

const { SelectMenuBuilder } = require('novecord');
const gameSelect = new SelectMenuBuilder()
.setCustomId('game_select')
.setPlaceholder('Choose your favorite games...')
.addOption('Minecraft', 'minecraft', 'Block building game', '🎮')
.addOption('Discord Bot Dev', 'botdev', 'Create awesome bots', '🤖')
.addOption('Web Development', 'webdev', 'Build websites', '💻')
.setMinValues(1)
.setMaxValues(3) // Allow multiple selections
.build();
client.sendMessage(channelId, {
content: 'What do you like to do? (Select up to 3)',
components: [gameSelect]
});

SelectMenuBuilder Methods

  • .setCustomId(id) - Set custom ID for interaction handling
  • .setPlaceholder(text) - Set placeholder text
  • .addOption(label, value, description, emoji) - Add an option
  • .setMinValues(number) - Set minimum selections
  • .setMaxValues(number) - Set maximum selections
  • .setDisabled(boolean) - Enable/disable menu
  • .build() - Build the final select menu object

TextInputBuilder

Create text input fields for use within modals. Supports both short single-line and long paragraph inputs.

Input Styles

StyleValueDescription
Short1Single line text input
Paragraph2Multi-line text area

Examples

const { TextInputBuilder } = require('novecord');
// Short text input
const usernameInput = new TextInputBuilder()
.setCustomId('username')
.setLabel('Username')
.setStyle(1) // Short
.setRequired(true)
.setMinLength(3)
.setMaxLength(20)
.setPlaceholder('Enter your username...');
// Paragraph text input
const feedbackInput = new TextInputBuilder()
.setCustomId('feedback')
.setLabel('Your Feedback')
.setStyle(2) // Paragraph
.setRequired(false)
.setMinLength(10)
.setMaxLength(1000)
.setPlaceholder('Tell us what you think...')
.setValue('Default text here'); // Pre-filled value

TextInputBuilder Methods

  • .setCustomId(id) - Set custom ID for interaction handling
  • .setLabel(text) - Set input label
  • .setStyle(number) - Set input style (1 = short, 2 = paragraph)
  • .setRequired(boolean) - Set if input is required
  • .setMinLength(number) - Set minimum character length
  • .setMaxLength(number) - Set maximum character length
  • .setPlaceholder(text) - Set placeholder text
  • .setValue(text) - Set default value
  • .build() - Build the final text input object

Handling Component Interactions

When users interact with your components, you'll receive interaction events that you can handle.

client.on('INTERACTION_CREATE', (interaction) => {
// Handle button clicks
if (interaction.type === 3 && interaction.data.component_type === 2) {
const customId = interaction.data.custom_id;
if (customId === 'confirm_action') {
client.respondInteraction(interaction.id, interaction.token, {
content: 'Action confirmed! ✅'
});
} else if (customId === 'cancel_action') {
client.respondInteraction(interaction.id, interaction.token, {
content: 'Action cancelled! ❌'
});
}
}
// Handle select menu selections
if (interaction.type === 3 && interaction.data.component_type === 3) {
const customId = interaction.data.custom_id;
const selectedValues = interaction.data.values;
if (customId === 'role_select') {
client.respondInteraction(interaction.id, interaction.token, {
content: `You selected: ${selectedValues.join(', ')}`
});
}
}
// Handle modal submissions
if (interaction.type === 5) {
const customId = interaction.data.custom_id;
const components = interaction.data.components;
if (customId === 'profile_modal') {
const name = components[0].components[0].value;
const bio = components[1].components[0].value;
client.respondInteraction(interaction.id, interaction.token, {
content: `Profile created!\nName: ${name}\nBio: ${bio}`
});
}
}
});

Complete Example

Here's a complete example that demonstrates all component types working together.

const {
Client,
Intents,
ButtonBuilder,
SelectMenuBuilder,
ModalBuilder,
TextInputBuilder
} = require('novecord');
const client = new Client({
token: 'YOUR_BOT_TOKEN',
intents: Intents.Guilds | Intents.GuildMessages
});
client.on('READY', () => {
console.log(`${client.user.username} is ready!`);
});
client.on('MESSAGE_CREATE', (message) => {
if (message.content === '!components') {
// Create a button
const setupButton = new ButtonBuilder()
.setLabel('Setup Profile')
.setStyle(1)
.setCustomId('setup_profile')
.setEmoji('⚙️')
.build();
// Create a select menu
const themeSelect = new SelectMenuBuilder()
.setCustomId('theme_select')
.setPlaceholder('Choose a theme...')
.addOption('Dark Mode', 'dark', 'Dark theme', '🌙')
.addOption('Light Mode', 'light', 'Light theme', '☀️')
.addOption('Auto', 'auto', 'System theme', '🔄')
.build();
client.sendMessage(message.channel_id, {
content: 'Welcome! Choose your preferences:',
components: [setupButton, themeSelect]
});
}
});
client.on('INTERACTION_CREATE', (interaction) => {
if (interaction.data.custom_id === 'setup_profile') {
// Show modal when button is clicked
const nameInput = new TextInputBuilder()
.setCustomId('profile_name')
.setLabel('Display Name')
.setStyle(1)
.setRequired(true)
.setMaxLength(32);
const bioInput = new TextInputBuilder()
.setCustomId('profile_bio')
.setLabel('About You')
.setStyle(2)
.setRequired(false)
.setMaxLength(200)
.setPlaceholder('Tell us about yourself...');
const modal = new ModalBuilder()
.setTitle('Profile Setup')
.setCustomId('profile_setup_modal')
.addTextInput(nameInput)
.addTextInput(bioInput)
.build();
client.showModal(interaction.id, interaction.token, modal);
}
if (interaction.data.custom_id === 'theme_select') {
const theme = interaction.data.values[0];
client.respondInteraction(interaction.id, interaction.token, {
content: `Theme set to: ${theme} ✅`
});
}
if (interaction.data.custom_id === 'profile_setup_modal') {
const name = interaction.data.components[0].components[0].value;
const bio = interaction.data.components[1].components[0].value || 'No bio provided';
client.respondInteraction(interaction.id, interaction.token, {
content: `Profile created!\n**Name:** ${name}\n**Bio:** ${bio}`
});
}
});
client.login();