Components
Build interactive messages with Discord Components V2 syntax.
Overview
Components V2 (or cv2) is an alternative to embeds for building rich, interactive messages. Unlike embeds which are mostly display-only, Components V2 lets you build messages with interactive elements like buttons, dropdowns, galleries, and card-like containers. Use Components V2 when you want a modern, interactive layout; use embeds for text-heavy information displays.
Components V2 messages cannot contain both embeds and components in the same message—it's one or the other.
Getting Started
A Components V2 template begins with the {cv2} flag (colon optional), then contains any number of component blocks:
{cv2}
{text: Your message text}
{button: Click me && url: https://example.com}
{section: {text: Title}{thumbnail: https://example.com/image.png}}
{container: accent: #5d86cf && {text: Colored card}}
{gallery: https://example.com/1.png && https://example.com/2.png}
Components can be chained with && to separate options within a single component, and child components are nested with braces.
Components
Text
A plain text block. Variables like {user.mention} and {guild.name} are substituted normally.
{cv2}{text: Hello {user.mention}, welcome to {guild.name}!}
Section
A card containing up to 3 lines of text and one accessory (either a thumbnail image or a button). Sections are useful for highlighting featured content.
Structure:
{section: {text: Line 1}{text: Line 2}{text: Line 3}{thumbnail: url}}
or with a button instead:
{section: {text: Line 1}{button: Click here && url: https://...}}
Example:
{cv2}{section: {text: Featured Server}{text: Join 10k+ members}{text: Click the button to apply}{button: Join Now && url: https://discord.gg/greed}}
Sections require at least one text line and exactly one accessory (thumbnail or button). If either is missing, the section is skipped.
Button
A clickable button. Can be a link button (opens a URL) or a custom button (triggers a bot action).
Link buttons:
{button: Label && url: https://example.com}
Custom buttons:
{button: Label && custom_id: my_script && style: primary}
Full options (separated by &&):
label: text— Button texturl: https://...— Link target (creates a link button; always renders as Link style, ignoring anystyle:parameter)custom_id: nameorcustom: nameorid: name— Custom script name (creates a custom button that triggers the script)style: primary|secondary|success|danger— Color style (ignored for link buttons)disabled— Disables the button
Styles (and aliases):
primaryorblurplesecondaryorgreyorgraysuccessorgreendangerorred
Positional shorthand:
- A non-URL part becomes the label
- An
http://orhttps://URL becomes the link
{cv2}{button: Documentation && https://greed.best}{button: Verify && custom_id: verify && style: success}
Custom button scripts: The custom: name must refer to a custom script saved in the same server with ,custom add. The name must start with a lowercase letter or digit, be 1–32 characters total, and contain only lowercase letters, digits, underscores, or hyphens. If the label is omitted, the script's name is used as the label.
Clicking the button renders the saved script and sends it as an ephemeral reply — only the person who clicked sees it. The script is rendered against the clicker, so {user.*} refers to them and {guild.*} / {channel.*} refer to where they clicked. Every click also increments the script's use counter, visible in ,custom list.
Save the script first with ,custom add (name) (script). A button pointing at a name that doesn't exist yet, or at an invalid name, renders greyed out and cannot be clicked. If you delete or rename the script afterwards, the button stays clickable but replies with a "that script no longer exists" notice.
,custom add rules {embed}$v{title: Server Rules}$v{description: Be kind. No spam.}
{cv2}{text: Read before posting}{button: label: Server Rules && custom: rules && style: primary}
Up to 5 buttons can appear in a single action row. For more than 5 buttons, use multiple action rows.
Button & Action Rows
By default, buttons appear in action rows automatically. To control button layout or combine buttons with dropdowns, use {actionrow}:
{cv2}
{actionrow: {button: First}{button: Second}{button: Third}}
{actionrow: {select: placeholder: Choose an option && Label 1: value1 && Label 2: value2}}
Select / Dropdown
A dropdown menu for display only. This component is always disabled and cannot be interacted with—it is purely decorative. Use it to show available options or configuration possibilities to users who cannot yet interact with them.
Syntax:
{select: placeholder: Choose one && Label: value && Label: value}
Example:
{cv2}{select: placeholder: Pick a role && Member: member && Moderator: mod && Admin: admin}
Options:
placeholder: text— Sets the displayed placeholder text- Each option is
Label: valueseparated by&&. A bare word with no colon becomes both label and value. - Up to 25 options per dropdown (extras are ignored)
disabled,min_values:, andmax_values:are parsed but have no effect (the dropdown is always disabled)
Dropdowns in Components V2 are always disabled and display-only. They cannot be interacted with by users. This is a visual-only component.
Separator
A horizontal divider line. Use for visual separation between sections.
{cv2}{text: Section 1}{separator:}{text: Section 2}
Options:
largeorspacing: 2— Adds extra spacing above the separatordivider: false— Removes the visible line (just adds spacing)
{cv2}{text: Top}{separator: large}{text: Bottom}
Gallery / Media
Display multiple images in a gallery layout. Images are separated by &&.
Syntax:
{gallery: url1 && url2 && url3}
Per-image options:
description: text— Caption for the previous imagespoiler— Marks the previous image as spoiler
Example:
{cv2}{gallery: https://example.com/photo1.png && description: First photo && https://example.com/photo2.png && spoiler && description: Hidden photo}
Container
A colored card that groups content together. All content inside inherits the accent color styling.
Syntax:
{container: accent: #hex && {text: ...}{button: ...}{section: ...}}
Accent color options:
accent: #5d86cforaccent_color: #5d86cforaccent_colour: #5d86cf
Inside a container, you can nest:
{text: ...}{button: ...}{section: ...}{separator: ...}{gallery: ...}{actionrow: ...}{select: ...}
Example:
{cv2}{container: accent: #5d86cf && {text: Official Announcement}{text: Read the details below}{separator:}{text: We've launched a new feature! Check it out.}{button: Learn More && url: https://greed.best}}
Variables & Substitution
All standard greed variables resolve inside Components V2 templates, just as they do in embeds. Refer to the Variables page for the complete list.
{cv2}{text: Hello {user.mention}!}{text: Server: {guild.name}}{button: Your Profile && url: https://example.com}
URL Validation
URLs must be valid HTTP/HTTPS links or use the attachment:// scheme:
https://example.com/image.png✓http://example.com/file.png✓attachment://filename✓ (must be longer than 13 characters)example.com/image.png✗ (missing protocol)ftp://example.com✗ (protocol not supported)
Invalid URLs are silently dropped from the message.
Limits & Constraints
Discord enforces strict limits on Components V2 messages:
- Maximum 5 buttons per action row
- Maximum 25 options per dropdown
- Maximum 3 text lines per section
- Maximum 1 accessory (thumbnail or button) per section
- Section requires at least one text line
- Container can hold multiple children but must have at least one
- Message cannot mix embeds and components
Troubleshooting
Missing {cv2} flag: If your template lacks {cv2} at the start, it's parsed as a regular embed script instead of Components V2. The syntax will fail validation.
Section with no accessory: If a section has text but no thumbnail or button, it's skipped entirely.
Invalid URLs: If a gallery, thumbnail, or button URL is malformed (e.g., missing protocol), that element is dropped but the rest of the message renders.
Too many section lines: If a section contains more than 3 text blocks, extras are ignored.
Formatting text: For multi-line text blocks, you can embed real newlines in the template, or use Discord's Markdown formatting (**bold**, *italic*, etc.) within text.
Case sensitivity: Component names are case-insensitive ({TEXT:} works same as {text:}), but variable names are case-sensitive ({user.mention} ≠ {User.Mention}).