Buttons
Creating and handling button interactions with djs-core.
Buttons are interactive components that users can click to trigger actions in your Discord bot.
Buttons in src/components/buttons/ are auto-registered. The customId comes from the file path — you do not call .setCustomId() in the handler file.
File-based routing
| File path | customId |
|---|---|
src/components/buttons/confirm.ts |
confirm |
src/components/buttons/demo/subdemo.ts |
demo.subdemo |
src/components/buttons/shop/buy.ts |
shop.buy |
Nested folders use dot notation, same as slash commands.
Creating a button
import { Button } from "@djs-core/runtime";import { ButtonStyle } from "discord.js";
export default new Button() .setLabel("Click me!") .setStyle(ButtonStyle.Primary) .run(async (interaction) => { await interaction.reply("Button clicked!"); });Button styles
Discord provides several button styles:
ButtonStyle.Primary(Blurple)ButtonStyle.Secondary(Gray)ButtonStyle.Success(Green)ButtonStyle.Danger(Red)ButtonStyle.Link(Gray with external link icon)
Using buttons in commands
Import the button and add it to an ActionRowBuilder:
import confirmButton from "../../components/buttons/confirm";import { Button, Command } from "@djs-core/runtime";import { ActionRowBuilder } from "discord.js";
export default new Command() .setDescription("Show a button") .run(async (interaction) => { const row = new ActionRowBuilder<Button>().addComponents(confirmButton);
await interaction.reply({ content: "Click the button below!", components: [row], }); });Passing data with .withData()
Declare the data shape with .withData<T>(), then call .setData() when attaching the button to a message:
import { Button } from "@djs-core/runtime";import { ButtonStyle } from "discord.js";
export default new Button() .withData<{ userId: string; action: string }>() .setLabel("Confirm") .setStyle(ButtonStyle.Danger) .run(async (interaction, data) => { await interaction.reply(`Processing ${data.action} for user ${data.userId}`); });import deleteButton from "../../components/buttons/delete";import { Button } from "@djs-core/runtime";import { ActionRowBuilder } from "discord.js";
const row = new ActionRowBuilder<Button>().addComponents( deleteButton.setData({ userId: interaction.user.id, action: "delete" }),);Data TTL
Optionally expire stored data after a number of seconds:
deleteButton.setData({ userId: "123", action: "delete" }, 60);Link buttons
Link buttons navigate to external URLs and do not trigger interaction handlers:
import { Button } from "@djs-core/runtime";import { ButtonStyle } from "discord.js";
export default new Button() .setLabel("Visit Website") .setStyle(ButtonStyle.Link) .setURL("https://example.com");Link buttons are the only buttons that need .setURL(). Handler buttons get their customId from the file path automatically.