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.
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
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.
| Type | Description |
|---|---|
text | A block of Markdown text. |
separator | A horizontal divider, with optional spacing. |
section | Up to 3 lines of text plus a button or thumbnail beside them. |
gallery | A grid of up to 10 images or videos. |
file | An attached file. |
container | A bordered group of other blocks, with an optional accent color. |
buttons | A row of buttons. |
menu | A select menu. |
text
{ type: "text", content: "Hello, **world**!" }| Field | Type | Required |
|---|---|---|
content | string | Yes |
separator
{ type: "separator", spacing: "large", divider: true }| Field | Type | Default |
|---|---|---|
divider | boolean | true (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.
{
type: "section",
content: ["**Premium**", "Unlock extra features."],
button: { id: "upgrade", label: "Upgrade", style: "Success" },
}{
type: "section",
content: "New avatar uploaded.",
thumbnail: { url: "attachment://avatar.png", description: "User avatar" },
}| Field | Type | Required |
|---|---|---|
content | string | string[] (max 3 lines) | Yes |
button | Button definition | Exactly 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.
gallery
{
type: "gallery",
items: [
{ url: "attachment://screenshot1.png" },
{ url: "attachment://screenshot2.png", spoiler: true },
],
}| Field | Type | Required |
|---|---|---|
items | { url, description?, spoiler? }[] (1-10) | Yes |
file
{ 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.
{
type: "container",
color: "#5865F2",
components: [
{ type: "text", content: "## Changelog" },
{ type: "separator" },
{ type: "text", content: "- Fixed a crash\n- Added /poll command" },
],
}| Field | Type | Required |
|---|---|---|
components | Block[] | Yes |
color | ColorResolvable | No |
spoiler | boolean | No |
Warning
A container can hold text, separator, section, gallery, file, buttons, and menu blocks; but not another container. Containers can't be nested.
buttons
{
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.
menu
{
type: "menu",
menu_id: "language",
content: "Choose a language",
fields: [
{ name: "English", value: "en" },
{ name: "Spanish", value: "es" },
],
}| Field | Type | Default |
|---|---|---|
menu_id | string | required |
menu_type | "normal" | "user" | "role" | "channel" | "normal" |
content | string | ; |
min/max | number | unset (discord.js defaults apply) |
fields | Field[] ("normal" only) | [] |
Note
Same field shape as SelectMenus.
Full example
Blocks can be nested inside a container to group them visually:
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.