Skip to main content
Modals are pop-up forms that allow users to enter text input. Represents a legacy UI modal for InputText components.
import discord
from discord.ui import Modal, InputText

class MyModal(Modal):
    def __init__(self):
        super().__init__(title="My Modal")
        self.add_item(InputText(label="Name", placeholder="Enter your name"))

Constructor

*children
InputText
The initial items displayed in the modal. Only supports InputText.
title
str
required
The title of the modal. Must be 45 characters or fewer.
custom_id
str | None
default:"None"
The ID of the modal that gets received during an interaction. Auto-generated if not provided. Must be 100 characters or fewer.
timeout
float | None
default:"None"
Timeout in seconds from last interaction before no longer accepting input. If None, there is no timeout.
store
bool
default:"True"
Whether this modal should be stored for callback listening. Setting to False ignores its callback.

Attributes

title
str
The title of the modal.
children
List[InputText]
The child items attached to the modal.
custom_id
str
The ID of the modal that gets received during an interaction.
timeout
float | None
Timeout from last interaction before no longer accepting input.

Methods

The coroutine called when the modal is submitted. Override to handle submitted values.Parameters:
  • interaction (Interaction): The interaction that submitted the modal.
async def callback(self, interaction: discord.Interaction):
    name = self.children[0].value
    await interaction.response.send_message(f"Hello, {name}!")
Adds an InputText component to the modal.Parameters:
  • item (InputText): The item to add to the modal.
Raises:
  • ValueError: Maximum of 5 items in a modal.
  • TypeError: Item is not an InputText.
Returns: Self
modal.add_item(InputText(label="Email"))
Removes a component from the modal.Parameters:
  • item (InputText): The item to remove from the modal.
Returns: Self
modal.remove_item(input_text)
Stops listening to interaction events from the modal.
modal.stop()
Waits for the modal to be submitted.Returns: bool - Whether the modal timed out.
timed_out = await modal.wait()
A callback called when the modal’s callback fails with an error.Parameters:
  • error (Exception): The exception that was raised.
  • interaction (Interaction): The interaction that led to the failure.
async def on_error(self, error: Exception, interaction: discord.Interaction):
    await interaction.response.send_message("An error occurred!", ephemeral=True)
A callback called when a modal’s timeout elapses without being explicitly stopped.
async def on_timeout(self):
    print("Modal timed out")

InputText

Represents a UI text input field.
from discord.ui import InputText
import discord

input_text = InputText(
    label="Name",
    placeholder="Enter your name",
    style=discord.InputTextStyle.short
)

Constructor

style
InputTextStyle
default:"InputTextStyle.short"
The style of the input text field.
custom_id
str | None
default:"None"
The ID of the input text field. Auto-generated if not provided.
label
str | None
default:"None"
The label for the input text field. Must be 45 characters or fewer.
placeholder
str | None
default:"None"
The placeholder text shown if nothing is entered. Must be 100 characters or fewer.
min_length
int | None
default:"None"
The minimum number of characters that must be entered. Must be less than 4000. Defaults to 0.
max_length
int | None
default:"None"
The maximum number of characters that can be entered. Must be between 1 and 4000.
required
bool | None
default:"True"
Whether the input text field is required or not.
value
str | None
default:"None"
Pre-fills the input text field with this value. Must be 4000 characters or fewer.
row
int | None
default:"None"
The relative row this input text field belongs to (0-4).
id
int | None
default:"None"
The input text field’s ID.

Attributes

style
InputTextStyle
The style of the input text field.
custom_id
str
The ID of the input text field.
label
str
The label of the input text field.
placeholder
str | None
The placeholder text shown before anything is entered.
min_length
int | None
The minimum number of characters that must be entered.
max_length
int | None
The maximum number of characters that can be entered.
required
bool | None
Whether the input text field is required.
value
str | None
The value entered in the text field.
width
int
The width of the input in the UI layout. Always 5.

Input Text Styles

  • InputTextStyle.short - Single line input (default)
  • InputTextStyle.long - Multi-line paragraph input

Examples

import discord
from discord import app_commands
from discord.ui import Modal, InputText

class FeedbackModal(Modal):
    def __init__(self):
        super().__init__(title="Feedback Form")
        
        self.add_item(InputText(
            label="Name",
            placeholder="Enter your name",
            required=True
        ))
        
        self.add_item(InputText(
            label="Feedback",
            style=discord.InputTextStyle.long,
            placeholder="Share your thoughts...",
            required=True
        ))
    
    async def callback(self, interaction: discord.Interaction):
        name = self.children[0].value
        feedback = self.children[1].value
        
        await interaction.response.send_message(
            f"Thanks for your feedback, {name}!\nYou said: {feedback}",
            ephemeral=True
        )

@bot.tree.command()
async def feedback(interaction: discord.Interaction):
    modal = FeedbackModal()
    await interaction.response.send_modal(modal)

Notes

  • Modals can contain a maximum of 5 InputText components
  • Modal titles must be 45 characters or fewer
  • InputText labels must be 45 characters or fewer
  • InputText values can be up to 4000 characters
  • Placeholders can be up to 100 characters
Modals can only be sent as a response to interactions (slash commands, buttons, select menus). They cannot be sent directly as messages.

Build docs developers (and LLMs) love