📦 ULTIMATE GUIDE TO DISCORD.JS FLEXIBLE COMPONENTS (V2)

💡 WHY CV2?

Flexible Components replace traditional embeds with LEGO-like blocks – text, images, buttons and menus – giving you richer layouts and eliminating many Discord API errors such as "Invalid Form Body (type must be 1)".

⚙️ PREREQUISITES

• Node.js 16.9.0 or higher • discord.js 14.19.3 or higher • Always send the MessageFlags.IsComponentsV2 flag when replying or editing a reply

🛠️ MINIMAL REPLY EXAMPLE (TypeScript)


import { MessageFlags } from "discord.js";
await interaction.reply({
components: [/* your ContainerBuilder instance */],
flags: MessageFlags.IsComponentsV2
});

📑 CORE BUILDERS CHEAT-SHEET


• 'ContainerBuilder' – //root component that holds everything else
• 'TextDisplayBuilder' – //Markdown-capable text block
• 'SectionBuilder' – //text plus ONE accessory (thumbnail or button) on the right
• 'ThumbnailBuilder' – //thumbnail image accessory
• 'MediaGalleryBuilder' – //grid / gallery of images
• 'MediaGalleryItemBuilder' – //a single image inside the gallery
• 'ActionRowBuilder' – //horizontal row for buttons or select menus
• 'ButtonBuilder' – //creates a button
• 'StringSelectMenuBuilder' – //creates a dropdown menu
• 'SeparatorBuilder' – //simple horizontal divider

🍳 LAYOUT COOKBOOK

1️⃣ BASIC CONTAINER


const container = new ContainerBuilder();
interaction.reply({ components: [container], flags: MessageFlags.IsComponentsV2 });

2️⃣ HANDLING SLOW OPERATIONS


interaction.deferReply({ flags: MessageFlags.IsComponentsV2 | MessageFlags.Ephemeral });
// heavy work here …
interaction.editReply({ components: [container], flags: MessageFlags.IsComponentsV2 });

3️⃣ HEADER WITH THUMBNAIL


const header = new SectionBuilder()
.addTextDisplayComponents(new TextDisplayBuilder().setContent("### Character Sheet"))
.setThumbnailAccessory(new ThumbnailBuilder().setURL("IMAGE_URL"));
container.addSectionComponents(header);

4️⃣ IMAGE GALLERY


const gallery = new MediaGalleryBuilder().addItems(
new MediaGalleryItemBuilder().setURL("IMAGE_URL").setDescription("Awesome picture")
);
container.addMediaGalleryComponents(gallery);

5️⃣ BUTTON ROW


const buttons = new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder().setCustomId("ok").setLabel("OK").setStyle(ButtonStyle.Primary),
new ButtonBuilder().setCustomId("cancel").setLabel("Cancel").setStyle(ButtonStyle.Danger)
);
container.addActionRowComponents(buttons);