DWEEB
Developer guide · Components V2

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

Message component type IDs and placement
ComponentUse it forImportant rule
Text Display (10)Markdown text, headings, lists and mentionsCounts toward the message-wide character budget
Section (9)One to three text blocks beside a thumbnail or buttonIts accessory is part of the Section
Thumbnail (11)Compact media beside Section textUsed as a Section accessory
Media Gallery (12)One or more large images or media itemsUp to 10 items
File (13)A downloadable attachment cardPlace at the top level or inside a Container
Separator (14)A divider or deliberate vertical spaceCan use small or large spacing
Container (17)An embed-like group with an optional accent colourContainers cannot be nested
Action Row (1)Buttons or one select menuUp to 5 buttons
Button (2)A link or an application-handled actionPlace in an Action Row or as a Section accessory
String Select (3)A dropdown with choices you defineOne per Action Row; requires an interaction handler
User / Role / Mentionable / Channel Select (5 / 6 / 7 / 8)A dropdown of Discord entitiesOne 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
Sending the payload from a bot or your own code
Where you send it fromWhat to passWhat to watch
A webhook URL, directly over HTTPSPOST the JSON to the webhook URL with the components array and the V2 flagAdd ?with_components=true to the URL, or components are silently dropped
A bot library such as discord.jsPass the same object through the library's message payload, or use its builder classesSet the IS_COMPONENTS_V2 flag; content and embeds are rejected once it is set
A library without Components V2 helpersUse a documented raw-payload API, or call Discord's HTTP API directlyNumeric type values are the contract; helper classes are convenience only
An AI client, through DWEEB's MCP connectorAsk for the message; the connector validates and previews before anything postsIt 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 →

Primary sources

Keep learning