Discord Components V2: Complete Guide
Components V2 turns a Discord message into a real layout tree: text, sections, thumbnails, media, separators, containers and interactive controls. This guide explains the model that Discord actually accepts and gives you an editable reference instead of a disconnected code fragment.
What changed in Components V2
Legacy webhook messages split presentation between top-level content and embeds. Components V2 moves the visible message into one components array and adds layout primitives such as Container and Section. Once the IS_COMPONENTS_V2 message flag is set, top-level content and embeds are disabled; text belongs in Text Display components instead.
The result is more composable than a legacy embed. A Container can hold formatted text, separators, media galleries, files and action rows behind one accent colour. A Section can place one to three text blocks beside a thumbnail or button accessory. You can mix several top-level blocks rather than forcing the whole design into one card.
Message component type IDs and placement
| Component | Use it for | Important rule |
|---|---|---|
| Text Display (10) | Markdown text, headings, lists and mentions | Counts toward the message-wide character budget |
| Section (9) | One to three text blocks beside a thumbnail or button | Its accessory is part of the Section |
| Thumbnail (11) | Compact media beside Section text | Used as a Section accessory |
| Media Gallery (12) | One or more large images or media items | Up to 10 items |
| File (13) | A downloadable attachment card | Place at the top level or inside a Container |
| Separator (14) | A divider or deliberate vertical space | Can use small or large spacing |
| Container (17) | An embed-like group with an optional accent colour | Containers cannot be nested |
| Action Row (1) | Buttons or one select menu | Up to 5 buttons |
| Button (2) | A link or an application-handled action | Place in an Action Row or as a Section accessory |
| String Select (3) | A dropdown with choices you define | One per Action Row; requires an interaction handler |
| User / Role / Mentionable / Channel Select (5 / 6 / 7 / 8) | A dropdown of Discord entities | One per Action Row; Discord supplies its choices |
A minimal Components V2 webhook payload
This payload creates a coloured container with a heading, supporting text, a separator and a link button. The numeric flag is 32768, or 1 << 15. DWEEB adds the V2 flag when it serializes and sends a visual design.
{
"flags": 32768,
"components": [
{
"type": 17,
"accent_color": 5793266,
"components": [
{ "type": 10, "content": "# Server update\nEverything you need in one place." },
{ "type": 14, "divider": true, "spacing": 1 },
{
"type": 1,
"components": [
{ "type": 2, "style": 5, "label": "Read the guide", "url": "https://example.com/update" }
]
}
]
}
]
}Current message and nesting limits
DWEEB validates against the same limits before send, so the live issue list is also a practical limits calculator. Discord can change its API over time; the numbers below are generated from the constants used by the editor rather than copied into a second, drifting list.
- 40 components total, including nested components
- 10 top-level components
- 4,000 characters across text-bearing component fields
- 39 children in a Container when it is the only top-level component
- 1–3 Text Display children in a Section
- 10 Media Gallery items, 5 buttons per Action Row and 25 string-select options
Webhooks, buttons and app ownership
A person-created incoming webhook can post non-interactive Components V2 when the request opts into components. Link buttons are safe because Discord opens a URL and no application has to receive a click. Buttons with custom IDs and select menus are different: an application must own the webhook and acknowledge the interaction.
That distinction explains the setup badges in DWEEB. Static layouts work with any incoming webhook. DWEEB-hosted replies use a guided app-owned destination. Features that change roles, create channels or perform other privileged actions also require the relevant Discord app installation.
Sending the payload from a bot or your own code
The same components array works wherever the message is sent from, so a design checked visually does not have to be rebuilt in code. Only the transport and the flag handling differ.
- Export from the visual builder once the preview looks right, then paste the payload into your project
- Import a payload your code already sends to adjust it visually instead of editing braces
- Keep the numeric component types as the source of truth; builder classes in any library are wrappers over them
| Where you send it from | What to pass | What to watch |
|---|---|---|
| A webhook URL, directly over HTTPS | POST the JSON to the webhook URL with the components array and the V2 flag | Add ?with_components=true to the URL, or components are silently dropped |
| A bot library such as discord.js | Pass the same object through the library's message payload, or use its builder classes | Set the IS_COMPONENTS_V2 flag; content and embeds are rejected once it is set |
| A library without Components V2 helpers | Use a documented raw-payload API, or call Discord's HTTP API directly | Numeric type values are the contract; helper classes are convenience only |
| An AI client, through DWEEB's MCP connector | Ask for the message; the connector validates and previews before anything posts | It acts as your Discord account, so it reaches only what you can |
A reliable build workflow
The editable Components V2 showcase contains every major block and is a faster reference than assembling the numeric types by hand. Open it, select a component, and compare the visual tree with exported JSON.
If the API rejects a payload or drops a component, use the webhook error guide to separate layout validation from delivery and app-ownership problems. For notification behavior, see webhook mentions and allowed_mentions.
- Start with information hierarchy: one purpose, one first action and only then decoration.
- Use Containers for visual grouping, not as a wrapper around every isolated line.
- Prefer a Section when a thumbnail or single button belongs directly to a short block of text.
- Validate character, nesting and interaction ownership before you copy or send JSON.
- Test the final post in a real channel; a preview cannot reproduce every client width or permission failure.
Frequently asked questions
What are Discord Components V2?
Discord's layout system for messages. With the IS_COMPONENTS_V2 flag (32768) set, a message is a tree of components — Text Displays, Sections, Thumbnails, Media Galleries, Files, Separators and Containers, plus buttons and select menus — instead of a content string and embeds.
Can a webhook send Components V2 messages?
Yes. Set flags to 32768 and add with_components=true to the webhook URL, or Discord ignores the components. A webhook you created yourself can send every non-interactive component and link buttons; buttons and menus that run an action need a webhook owned by an application that handles the click.
Do Components V2 replace embeds?
Within a V2 message, yes: content and embeds cannot be used, and a Container gives you the card with an accent colour that an embed used to. Messages without the flag still use content and embeds, so both formats keep working.
What is a Container in Components V2?
Component type 17: a card that groups other components, with an optional accent colour stripe and an optional spoiler blur. It is the V2 equivalent of an embed's box, but it can hold sections, galleries, separators and buttons in any order.
How many components can a Components V2 message have?
Up to 40 components in total, counting every nested one, with at most 10 at the top level and 4,000 characters of text across the whole message. DWEEB counts both live as you build.
How do I send Components V2 from discord.js or discord.py?
discord.js 14.19 and later has builder classes such as ContainerBuilder and TextDisplayBuilder, sent with the MessageFlags.IsComponentsV2 flag; discord.py 2.6 and later uses a LayoutView with ui.Container and ui.TextDisplay. DWEEB's code export writes either one from a design, and the dedicated discord.js and discord.py guides walk through both.
Put the guide into practice
Open the exact workflow in DWEEB. Nothing posts until you review and confirm it.
Open the editable Components V2 example →