Display

The Display class builds Discord's newer "Components V2" message layout: a stack of blocks; text, separators, sections with an accessory, image galleries, files, nested containers, buttons, and select menus; instead of a single content string plus an embeds array.

JavaScript
const { Display } = require("syntx.js");

Warning

Components V2 messages work differently from normal ones. You must send them with flags: MessageFlags.IsComponentsV2, and you can't combine them with content or embeds in the same message; put any text inside a "text" block instead.

Creating a layout

JavaScript
const { MessageFlags } = require("discord.js");

const display = new Display([
  { type: "text", content: "## Server Stats" },
  { type: "separator" },
  { type: "text", content: "We currently have **1,204** members." },
]);

channel.send({
  components: display.build(),
  flags: MessageFlags.IsComponentsV2,
});

Tip

Text blocks support the same Markdown you'd use in a normal message; **bold**, *italic*, ## headings, bullet lists, and so on.

Block types

Every entry in the array passed to new Display([...]) is an object with a type. Any block can also take an optional id (a number) if you need to reference it elsewhere.

TypeDescription
textA block of Markdown text.
separatorA horizontal divider, with optional spacing.
sectionUp to 3 lines of text plus a button or thumbnail beside them.
galleryA grid of up to 10 images or videos.
fileAn attached file.
containerA bordered group of other blocks, with an optional accent color.
buttonsA row of buttons.
menuA select menu.

text

JavaScript
{ type: "text", content: "Hello, **world**!" }
FieldTypeRequired
contentstringYes

separator

JavaScript
{ type: "separator", spacing: "large", divider: true }
FieldTypeDefault
dividerbooleantrue (visible line)
spacing"small" | "large""small"

section

A short block of text (1 to 3 lines) with exactly one accessory beside it; either a button or a thumbnail.

JavaScript
{
  type: "section",
  content: ["**Premium**", "Unlock extra features."],
  button: { id: "upgrade", label: "Upgrade", style: "Success" },
}
JavaScript
{
  type: "section",
  content: "New avatar uploaded.",
  thumbnail: { url: "attachment://avatar.png", description: "User avatar" },
}
FieldTypeRequired
contentstring | string[] (max 3 lines)Yes
buttonButton definitionExactly one of button/thumbnail
thumbnail{ url, description?, spoiler? }Exactly one of button/thumbnail

Warning

A section needs exactly one accessory. Passing both button and thumbnail; or neither; throws a SyntxError. For plain text with no accessory, use a "text" block instead.

JavaScript
{
  type: "gallery",
  items: [
    { url: "attachment://screenshot1.png" },
    { url: "attachment://screenshot2.png", spoiler: true },
  ],
}
FieldTypeRequired
items{ url, description?, spoiler? }[] (1-10)Yes

file

JavaScript
{ type: "file", url: "attachment://report.pdf" }

Note

url is usually attachment://<filename>, pointing at a file you attach to the same message through discord.js's files send option.

container

Groups other blocks together with a border and an optional accent color.

JavaScript
{
  type: "container",
  color: "#5865F2",
  components: [
    { type: "text", content: "## Changelog" },
    { type: "separator" },
    { type: "text", content: "- Fixed a crash\n- Added /poll command" },
  ],
}
FieldTypeRequired
componentsBlock[]Yes
colorColorResolvableNo
spoilerbooleanNo

Warning

A container can hold text, separator, section, gallery, file, buttons, and menu blocks; but not another container. Containers can't be nested.

buttons

JavaScript
{
  type: "buttons",
  buttons: [
    { id: "yes", label: "Yes", style: "Success" },
    { id: "no", label: "No", style: "Danger" },
  ],
}

Uses the same button definition as the Buttons class.

Warning

Unlike the standalone Buttons class, a buttons block doesn't auto-wrap into multiple rows; every button goes into a single row, so keep it to 5 or fewer.

JavaScript
{
  type: "menu",
  menu_id: "language",
  content: "Choose a language",
  fields: [
    { name: "English", value: "en" },
    { name: "Spanish", value: "es" },
  ],
}
FieldTypeDefault
menu_idstringrequired
menu_type"normal" | "user" | "role" | "channel""normal"
contentstring;
min/maxnumberunset (discord.js defaults apply)
fieldsField[] ("normal" only)[]

Note

Same field shape as SelectMenus.

Full example

Blocks can be nested inside a container to group them visually:

JavaScript
const display = new Display([
  {
    type: "container",
    color: "Blue",
    components: [
      { type: "text", content: "## Welcome to the server!" },
      {
        type: "section",
        content: "Read the rules before chatting.",
        thumbnail: { url: "attachment://rules-icon.png" },
      },
      { type: "separator", spacing: "large" },
      {
        type: "buttons",
        buttons: [{ id: "accept-rules", label: "I agree", style: "Success" }],
      },
    ],
  },
]);

channel.send({
  components: display.build(),
  flags: MessageFlags.IsComponentsV2,
});

build()

Returns an array of raw discord.js component builders, ready for the components send option.