You want to create a Discord bot using Discord.js v14 and add slash commands that users can trigger from the chat bar. Slash commands are the modern way to build bot interactions because they appear in the command list, require no prefix, and support autocomplete. This guide walks you through the exact steps to register and handle a slash command using Discord.js v14 and Node.js. You will write code for a simple ping command that replies with the bot’s latency.
Key Takeaways: Setting Up a Slash Command in Discord.js v14
- Discord Developer Portal > Application > Bot: Create a bot application and copy the token for authentication.
- npm install discord.js@14: Install the Discord.js v14 library in your Node.js project.
- client.on(‘interactionCreate’): Listen for slash command interactions and reply using
interaction.reply().
What Are Slash Commands in Discord.js v14
Slash commands are a feature introduced by Discord that let users trigger bot actions by typing a forward slash followed by the command name. Discord.js v14 provides a structured API to define, register, and handle these commands. Before you begin, you need a Discord bot application created in the Discord Developer Portal, a bot token, and Node.js installed on your machine. You also need to invite the bot to a server with the applications.commands scope so it can register slash commands.
Prerequisites
You must have Node.js version 16.9.0 or higher. Create a new folder for your project and run npm init -y to generate a package.json file. Then install Discord.js v14 with npm install discord.js@14. You also need a bot token from the Discord Developer Portal under your application’s Bot section.
How Discord.js v14 Handles Commands
In Discord.js v14, slash commands are defined using the SlashCommandBuilder class. You create a command object with a name, description, and optional options such as choices or required parameters. The command must be registered globally or on a specific guild using the REST API. When a user runs the command, Discord sends an interaction to your bot, which you handle in the interactionCreate event.
Steps to Create and Register a Slash Command
Follow these steps to set up a basic ping slash command. The command will reply with the bot’s WebSocket heartbeat and round-trip latency.
- Create the bot client file
Create a file namedindex.jsin your project folder. Import the necessary classes from Discord.js v14:Client,GatewayIntentBits,REST,Routes, andSlashCommandBuilder. Initialize a new client with theGuildsintent. - Define the slash command
Usenew SlashCommandBuilder()to create a command with namepingand descriptionReplies with Pong!. Store the command data in a JSON array for registration. - Register the command with Discord
Create a newRESTinstance and set its token. Userest.put(Routes.applicationCommands(clientId), { body: commands })to register the command globally. ReplaceclientIdwith your bot’s application ID from the Developer Portal. - Log in the bot
Callclient.login('YOUR_BOT_TOKEN')at the bottom of the file. Replace the placeholder with your actual bot token. - Handle the interaction
Add an event listener forclient.on('interactionCreate', async interaction => { ... }). Check if the interaction is a command usinginteraction.isChatInputCommand(). If the command name isping, calculate the latency and reply withinteraction.reply().
Below is the complete code for index.js. Replace YOUR_BOT_TOKEN and YOUR_CLIENT_ID with your actual values.
const { Client, GatewayIntentBits, REST, Routes, SlashCommandBuilder } = require('discord.js');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
const commands = [
new SlashCommandBuilder()
.setName('ping')
.setDescription('Replies with Pong!')
].map(command => command.toJSON());
const rest = new REST({ version: '10' }).setToken('YOUR_BOT_TOKEN');
(async () => {
try {
console.log('Started refreshing application (/) commands.');
await rest.put(Routes.applicationCommands('YOUR_CLIENT_ID'), { body: commands });
console.log('Successfully reloaded application (/) commands.');
} catch (error) {
console.error(error);
}
})();
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('interactionCreate', async interaction => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'ping') {
const sent = await interaction.reply({ content: 'Pong!', fetchReply: true });
interaction.editReply(`Pong! Roundtrip latency: ${sent.createdTimestamp - interaction.createdTimestamp}ms`);
}
});
client.login('YOUR_BOT_TOKEN');
Common Mistakes and Things to Avoid
Even experienced developers run into issues when setting up slash commands. Here are the most frequent problems and how to solve them.
Command Not Appearing in Server
If the slash command does not show up after running the script, check that you invited the bot with the applications.commands scope. Go to the Discord Developer Portal, select your application, navigate to OAuth2 > URL Generator, check the bot and applications.commands scopes, and regenerate the invite URL. Also verify that the bot has the necessary permissions in the server.
Interaction Failed Error
If the bot responds with “Interaction failed” after you run the command, the bot likely crashed or the reply took too long. Discord requires a response within 3 seconds. Use interaction.deferReply() if your command needs more time, then call interaction.editReply() later. Also ensure your bot token and client ID are correct.
Global vs Guild Commands
Global commands take up to one hour to propagate across all servers. For testing, register commands on a specific guild using Routes.applicationGuildCommands(clientId, guildId). This makes commands appear instantly. Replace guildId with your test server’s ID. Remember to remove guild-specific registration before going to production.
Discord.js v14 Slash Command Setup: Options Comparison
| Item | Global Registration | Guild Registration |
|---|---|---|
| Propagation time | Up to 1 hour | Instant |
| Use case | Production bots for all servers | Development and testing |
| API endpoint | Routes.applicationCommands(clientId) |
Routes.applicationGuildCommands(clientId, guildId) |
You now have a working Discord.js v14 bot with a slash command. Start by testing with guild registration to see instant results. Next, explore adding options like string choices or subcommands using addStringOption() and addSubcommand() on the SlashCommandBuilder. For advanced handling, use interaction.options.get('optionName') to read user input.