A Nuxt module for building Discord bots with slash commands, featuring hot module replacement, automatic command registration, and web interface for command management.
- 🤖 Discord Bot Integration - Seamlessly integrate Discord.js with your Nuxt application
- ⚡ Slash Commands - Type-safe slash command definitions with automatic registration
- 🎯 Auto-sync - Automatically sync commands with Discord's servers
- 🖥️ Web Interface - Beautiful UI for managing and viewing slash commands
- 🔄 Real-time Updates - WebSocket-based live updates in development
Install the module to your Nuxt application:
pnpm install nuxt-discord discord.js
Add the module to your nuxt.config.ts
:
export default defineNuxtConfig({
modules: ['nuxt-discord'],
discord: {
// Discord bot configuration
client: {
intents: ['Guilds'], // Discord gateway intents
deferOnPromise: true, // Auto-defer interactions when command returns a promise
},
dir: 'discord', // Directory for Discord-related files
autoStart: true, // Auto-start the bot on server startup
watch: {
enabled: true, // Enable HMR for commands
port: 5720, // HMR server port
showURL: false, // Show HMR server URL in console
sync: {
debounce: 1000 // Sync delay in milliseconds
}
}
}
})
Set up your environment variables:
# .env
DISCORD_TOKEN=your_bot_token_here
DISCORD_CLIENT_ID=your_application_id_here
Create slash commands in the /discord/commands
directory:
// discord/commands/ping.ts
/**
* @name ping
* @description A simple ping command that responds with 'pong!'
*/
export default function ping() {
return 'pong!'
}
Defining a command this way this module automatically deduces the name and description from the JSDoc comments. The command name is inferred following this set of priorities: describeCommand
macro > @name
JSDoc tag > function name > file name.
// discord/commands/add.ts
/**
* @name add
* @description Adds two numbers together
* @param a The first number to add
* @param b The second number to add
*/
export default (a: number, b: number) => {
// Add parameter validation
describeOption(a, {
min: -100,
max: 100,
})
describeOption(b, {
min: -100,
max: 100,
})
return `The sum of ${a} and ${b} is ${a + b}!`
}
// discord/commands/greet.ts
/**
* @name greet
* @description Greet someone with a custom message
* @param name The person to greet
* @param style The greeting style
*/
export default (name: string, style: string) => {
describeOption(name, {
minLength: 1,
maxLength: 32,
})
describeOption(style, {
choices: [
{ name: 'Formal', value: 'formal' },
{ name: 'Casual', value: 'casual' },
{ name: 'Enthusiastic', value: 'enthusiastic' },
],
})
const greetings = {
formal: `Good day, ${name}.`,
casual: `Hey ${name}!`,
enthusiastic: `HELLO THERE ${name.toUpperCase()}!!! 🎉`,
} as const
return greetings[style as keyof typeof greetings]
}
Access the command management interface at /discord/slash-commands
in your application. The interface provides:
- 📋 Command Overview - View all registered commands with their parameters
- 🏷️ Parameter Details - See type information, validation rules, and constraints
- 🔄 Sync Commands - Monitor local commands' synced status with server
- ➕ Register Commands - Easily register newly added commands
- ⚡ Live Updates - Real-time updates during development
Coming Soon: Live command execution/testing, i18n support, logging dashboard, and more fine-grained client control
The module is highly customizable and provides access to the internal Discord client and runtime hooks for advanced use cases.
import { useDiscordClient } from '#imports'
export default async () => {
const client = useDiscordClient()
// Access the internal Discord.js client
const discordJS = client.internalClient
const guilds = discordJS?.guilds.cache.size || 0
return `Bot is in ${guilds} servers!`
}
The module provides several hooks for customizing bot behavior:
// nitro/plugins/discord-config.ts
export default defineNitroPlugin(async (nitro) => {
// Configure Discord client options
nitro.hooks.hook('discord:client:config', (options) => {
options.presence = {
status: 'online',
activities: [{
name: 'Powered by Nuxt',
}]
}
})
// Handle client ready event
nitro.hooks.hook('discord:client:ready', (client) => {
console.log('Discord bot is ready!')
})
// Handle client errors
nitro.hooks.hook('discord:client:error', (error) => {
console.error('Discord error:', error)
})
})
export default (message: string) => {
// Return different response types
return reply.ephemeral(`This is private: ${message}`) // Only visible to user
// or
return `Public response: ${message}` // Visible to everyone
}
Refer to /src/types.ts for detailed type definitions for how you can define commands return types for advanced behavior.
// nuxt.config.ts
export default defineNuxtConfig({
discord: {
client: {
intents: [
'Guilds',
'GuildMessages'
],
deferOnPromise: true, // Auto-defer interactions when command returns a promise
},
dir: 'discord',
autoStart: true,
watch: {
enabled: true,
port: 5720, // HMR server port
showURL: false, // Show HMR server URL in console
sync: {
debounce: 1000
}
}
}
})
Use the 'nitro:client:config' hook to configure other options passed to the Discord client.
Here's what's planned for future releases:
- [ ] Full slash command options support
- [x] String type
- [x] Number type
- [x] Integer type
- [x] Boolean type
- [ ] Role type
- [ ] User type
- [ ] Mentionable type
- [ ] Attachment type
- [ ] Better JSDocs support JSDoc comments
- [ ] Localization support
- [ ] File-based subcommands
- [x] Auto-complete API
- [ ] Guild-specific commands
- [ ] Nuxt-devtools integration
- [ ] Unit tests
- [ ] Live command execution
- [ ] Command testing interface
- [ ] i18n management
- [ ] Logging dashboard
- [ ] Detailed client control panel
- [ ] Command analytics
- [ ] Fine grained diff display
Refer to the official Module Author Guide
- Generated from the module starter template
- Implementation details and best practices are inspired by
- UI components are based on Nuxt UI and UnoCSS
MIT - Made with 💚