Build interactive Discord components with NoveCord's Components V2 system. Create buttons, select menus, modals, and text inputs that follow Discord's latest specifications.
Create modal dialogs that pop up and allow users to input information through forms.
const { ModalBuilder, TextInputBuilder } = require('novecord');const nameInput = new TextInputBuilder() .setCustomId('user_name') .setLabel('Your Name') .setStyle(1) // Short text input .setRequired(true) .setMaxLength(50);const bioInput = new TextInputBuilder() .setCustomId('user_bio') .setLabel('Tell us about yourself') .setStyle(2) // Paragraph text input .setRequired(false) .setMaxLength(500) .setPlaceholder('Write a short bio...');const modal = new ModalBuilder() .setTitle('User Profile Setup') .setCustomId('profile_modal') .addTextInput(nameInput) .addTextInput(bioInput) .build();// Show modal in response to interactionclient.showModal(interaction.id, interaction.token, modal);
.setTitle(text)
- Set modal title.setCustomId(id)
- Set custom ID for interaction handling.addTextInput(textInput)
- Add a text input component.build()
- Build the final modal objectCreate text input fields for use within modals. Supports both short single-line and long paragraph inputs.
Style | Value | Description |
---|---|---|
Short | 1 | Single line text input |
Paragraph | 2 | Multi-line text area |
const { TextInputBuilder } = require('novecord');// Short text inputconst usernameInput = new TextInputBuilder() .setCustomId('username') .setLabel('Username') .setStyle(1) // Short .setRequired(true) .setMinLength(3) .setMaxLength(20) .setPlaceholder('Enter your username...');// Paragraph text inputconst 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
.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 objectWhen 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}` }); } }});
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();