diff --git a/apps/guide/content/docs/legacy/interactions/images/modal-example.png b/apps/guide/content/docs/legacy/interactions/images/modal-example.png
index 9cee3d67d..7b494dcd2 100644
Binary files a/apps/guide/content/docs/legacy/interactions/images/modal-example.png and b/apps/guide/content/docs/legacy/interactions/images/modal-example.png differ
diff --git a/apps/guide/content/docs/legacy/interactions/images/selectephem.png b/apps/guide/content/docs/legacy/interactions/images/selectephem.png
deleted file mode 100644
index 2f109b358..000000000
Binary files a/apps/guide/content/docs/legacy/interactions/images/selectephem.png and /dev/null differ
diff --git a/apps/guide/content/docs/legacy/interactions/modals.mdx b/apps/guide/content/docs/legacy/interactions/modals.mdx
index 4bdc32bc4..2367dfac7 100644
--- a/apps/guide/content/docs/legacy/interactions/modals.mdx
+++ b/apps/guide/content/docs/legacy/interactions/modals.mdx
@@ -2,30 +2,27 @@
title: Modals
---
-With modals you can create pop-up forms that allow users to provide you with formatted inputs through submissions. We'll cover how to create, show, and receive modal forms using discord.js!
+Modals are pop-up forms that allow you to prompt users for additional input. This form-like interaction response blocks the user from interacting with Discord until the modal is submitted or dismissed. In this section, we will cover how to create, show, and receive modals using discord.js!
- This page is a follow-up to the [interactions (slash commands) page](../slash-commands/advanced-creation). Please
- carefully read that section first, so that you can understand the methods used in this section.
+ This page is a follow-up to the [interactions (slash commands) page](../slash-commands/advanced-creation). Reading
+ that page first will help you understand the concepts introduced in this page.
## Building and responding with modals
-Unlike message components, modals aren't strictly components themselves. They're a callback structure used to respond to interactions.
+With the `ModalBuilder` class, discord.js offers a convenient way to build modals step by step using setters and callbacks.
- You can have a maximum of five `ActionRowBuilder`s per modal builder, and one `TextInputBuilder` within an
- `ActionRowBuilder`. Currently, you can only use `TextInputBuilder`s in modal action rows builders.
+ You can have a maximum of five top-level components per modal, each of which can be a label or a text display
+ component.
-To create a modal you construct a new `ModalBuilder`. You can then use the setters to add the custom id and title.
-
```js
const { Events, ModalBuilder } = require('discord.js');
client.on(Events.InteractionCreate, async (interaction) => {
if (!interaction.isChatInputCommand()) return;
-
if (interaction.commandName === 'ping') {
const modal = new ModalBuilder().setCustomId('myModal').setTitle('My Modal');
@@ -35,105 +32,321 @@ client.on(Events.InteractionCreate, async (interaction) => {
```
- The custom id is a developer-defined string of up to 100 characters. Use this field to ensure you can uniquely define
- all incoming interactions from your modals!
+ The `customId` is a developer-defined string of up to 100 characters and uniquely identifies this modal instance. You
+ can use it to differentiate incoming interactions.
-The next step is to add the input fields in which users responding can enter free-text. Adding inputs is similar to adding components to messages.
+The next step is adding components to the modal, which may either request input or present information.
-At the end, we then call `ChatInputCommandInteraction#showModal` to display the modal to the user.
+### Label
-
-If you're using typescript you'll need to specify the type of components your action row holds. This can be done by specifying the generic parameter in `ActionRowBuilder`:
-
-```diff
-- new ActionRowBuilder()
-+ new ActionRowBuilder()
-```
-
-
+Label components wrap around other modal components (text input, select menus, etc.) to add a label and description to it.
+Since labels are not stand-alone components, we will use this example label to wrap a text input component in the next section:
```js
-const { ActionRowBuilder, Events, ModalBuilder, TextInputBuilder, TextInputStyle } = require('discord.js');
+const { LabelBuilder, ModalBuilder } = require('discord.js');
client.on(Events.InteractionCreate, async (interaction) => {
if (!interaction.isChatInputCommand()) return;
-
if (interaction.commandName === 'ping') {
+ // [!code focus:11]
// Create the modal
const modal = new ModalBuilder().setCustomId('myModal').setTitle('My Modal');
- // Add components to modal
+ // [!code ++:5]
+ const hobbiesLabel = new LabelBuilder()
+ // The label is a large header text that identifies the interactive component for the user.
+ .setLabel('What are some of your favorite hobbies?')
+ // The description is an additional optional subtext that aids the label.
+ .setDescription('Activities you like to participate in');
- // Create the text input components
- const favoriteColorInput = new TextInputBuilder()
- .setCustomId('favoriteColorInput')
- // The label is the prompt the user sees for this input
- .setLabel("What's your favorite color?")
- // Short means only a single line of text
- .setStyle(TextInputStyle.Short);
-
- const hobbiesInput = new TextInputBuilder()
- .setCustomId('hobbiesInput')
- .setLabel("What's some of your favorite hobbies?")
- // Paragraph means multiple lines of text.
- .setStyle(TextInputStyle.Paragraph);
-
- // An action row only holds one text input,
- // so you need one action row per text input.
- const firstActionRow = new ActionRowBuilder().addComponents(favoriteColorInput);
- const secondActionRow = new ActionRowBuilder().addComponents(hobbiesInput);
-
- // Add inputs to the modal
- modal.addComponents(firstActionRow, secondActionRow);
-
- // Show the modal to the user
- await interaction.showModal(modal); // [!code word:showModal]
+ // [!code ++:2]
+ // Add label to the modal
+ modal.addLabelComponents(hobbiesLabel);
}
});
```
-Restart your bot and invoke the `/ping` command again. You should see a popup form resembling the image below:
-
-
-
-
- Showing a modal must be the first response to an interaction. You cannot `defer()` or `deferUpdate()` then show a
- modal later.
+
+ The `label` field has a max length of 45 characters. The `description` field has a max length of 100 characters.
-### Input styles
+### Text input
-Currently there are two different input styles available:
+Text input components prompt users for single or multi line free-form text.
-- `Short`, a single-line text entry;
-- `Paragraph`, a multi-line text entry similar to the HTML `
-### String select menu options
+## String select menu options
String select menu options are custom-defined by the user, as shown in the example above. At a minimum, each option must have it's `label` and `value` defined. The label is shown to the user, while the value is included in the interaction sent to the bot.
diff --git a/apps/guide/content/docs/legacy/popular-topics/display-components.mdx b/apps/guide/content/docs/legacy/popular-topics/display-components.mdx
index dc9b363ca..269c59348 100644
--- a/apps/guide/content/docs/legacy/popular-topics/display-components.mdx
+++ b/apps/guide/content/docs/legacy/popular-topics/display-components.mdx
@@ -32,6 +32,9 @@ Text Display components let you add markdown-formatted text to your message and
Sending user and role mentions in text display components **will notify users and roles**! You can and should control
mentions with the `allowedMentions` message option.
+
+ Text display components can be used in modals. See the [modal guide](../interactions/modals#text-display) for usage.
+
The example below shows how you can send a Text Display component in a channel.