This guide has been moved to . Please visit the new guide instead, since this one might be outdated.
The new guide looks better, has better explanations, and is way better overall.
Docs:
Credits:
Sub-Classing discord.ui.View
Copy class MyView(discord.ui.View):
@discord.ui.button(label='A button', style=discord.ButtonStyle.primary, emoji='😎')
async def button_callback(self, button, interaction):
await interaction.response.send_message('Button was pressed', ephemeral=True)
view = MyView()
@bot.command()
async def button(ctx):
await ctx.send('Press the button!', view=view)
Copy class MyButton(discord.ui.Button):
def __init__(self):
super().__init__(label='A button', style=discord.ButtonStyle.primary)
async def callback(self, interaction):
await interaction.response.send_message('Button was pressed', ephemeral=True)
view = discord.ui.View()
view.add_item(MyButton())
@bot.command()
async def ctx.send('Press the button!', view=view)
Copy view = discord.ui.View()
view.add_item(discord.ui.Button(label='Go to website', url='https://gist.github.com/MhmCats/500eafdad0aaf278b94c612764688976', style=discord.ButtonStyle.url))
Styles
discord.ButtonStyle.primary
discord.ButtonStyle.secondary
discord.ButtonStyle.success
discord.ButtonStyle.danger
Copy view = discord.ui.View()
view.add_item(discord.ui.Button(label='Go to website', url='https://gist.github.com/MhmCats/500eafdad0aaf278b94c612764688976', style=discord.ButtonStyle.url))
@bot.command()
async def url(ctx):
await ctx.send(content="Press the button!", view=view)
Here's how you can disable a single button or multiple buttons on press:
Disable a single button Disable all buttons
Copy class MyView(discord.ui.View):
@discord.ui.button(label='A button', style=discord.ButtonStyle.primary, disabled=True)
async def button_callback(self, button, interaction):
...
view = MyView()
@bot.command()
async def button(ctx):
await ctx.send('Press the button!', view=view)
Timeouts
You probably wanna set a timeout too, and its quite simple, really!
Copy class MyView(discord.ui.View):
def __init__(self):
super().__init__(timeout=10)
async def on_timeout(self):
for child in self.children:
child.disabled = True
await self.message.edit(view=self)
@discord.ui.button(style=discord.ButtonStyle.primary, emoji=':sunglasses:')
async def callback(self, button, interaction):
await interaction.response.send_message('Button was pressed', ephemeral=True)
@bot.command()
async def hi(ctx):
view = MyView()
view.message = await ctx.send("hi", view=view)
Rows
A message can have up to five "action rows" and each of these "action" rows have five slots where you can put message components. A button takes up one of these slots but a select menus takes up all five slots of a "action row". Keep this in mind when creating your views since you don't want to run out of space!
Copy class MyView(discord.ui.View):
@discord.ui.button(label="Button 1",
style=discord.ButtonStyle.primary, row=1)
async def first_button_callback(self, button, interaction):
await interaction.response.send("You pressed me!")
@discord.ui.button(label="Button 2",
style=discord.ButtonStyle.primary, row=2)
async def second_button_callback(self, button, interaction):
await interaction.response.send("You pressed me!")
@bot.command()
async def button(ctx):
view.message = await ctx.send("Wow!", view=MyView())