Skip to content

Components

cordless has full support for Discord’s Components v2.

from cordless.components import (
Container, TextDisplay, Separator, MediaGallery,
Section, ActionRow, Button, ButtonStyle,
)
from cordless.components import Container, TextDisplay, ActionRow, Button, ButtonStyle
components = [
Container([
TextDisplay("Welcome to my bot!"),
ActionRow([
Button("Click me", custom_id="my_button", style=ButtonStyle.PRIMARY),
]),
])
]
await ctx.send(components=components)
from cordless import Cog, cog_button
class MyCog(Cog):
@cog_button("my_button")
async def my_button(self, ctx):
await ctx.edit(components=[
Container([TextDisplay("You clicked it!")])
])

A button with custom_id="action:123" matches a handler registered as "action", and the suffix segments land on ctx.custom_id_args (here ["123"]). This works for buttons, selects, and modals — handy for embedding state like item ids or page numbers in the component itself.

@bot.button("shop")
async def shop(ctx):
item_id, page = ctx.custom_id_args
...

For buttons that take time to process, set defer=True. The message shows a loading state while the worker runs.

@cog_button("slow_button", defer=True)
async def slow_button(self, ctx):
result = await do_work()
await ctx.edit(components=[...])