Discord commands
Localize slash command names, descriptions, and options across all supported locales.
The plugin provides createCommandConfig() as a drop-in replacement for the Robo.js version. It accepts locale keys instead of hardcoded strings and auto-populates nameLocalizations and descriptionLocalizations for every discovered locale.
Setting up locale files
Store command metadata alongside your translations. Nested keys work well for organizing command names, descriptions, and option text.
{
"hey": "Hey there, {$user.name}!",
"ping": {
"name": "ping",
"desc": "Measure latency",
"arg": {
"name": "text",
"desc": "Optional text to include"
}
}
}{
"hey": "Hola, {$user.name}!",
"ping": {
"name": "ping",
"desc": "Medir latencia",
"arg": {
"name": "texto",
"desc": "Texto opcional para incluir"
}
}
}Using createCommandConfig()
Import createCommandConfig from @robojs/i18n instead of robo.js. Pass nameKey and descriptionKey to reference your locale keys.
import { createCommandConfig, t } from '@robojs/i18n'
import type { ChatInputCommandInteraction } from 'discord.js'
import type { CommandOptions } from '@robojs/discordjs'
export const config = createCommandConfig({
nameKey: 'commands:ping.name',
descriptionKey: 'commands:ping.desc',
options: [
{
type: 'string',
name: 'text',
nameKey: 'commands:ping.arg.name',
descriptionKey: 'commands:ping.arg.desc'
}
]
} as const)
export default (interaction: ChatInputCommandInteraction, options: CommandOptions<typeof config>) => {
const user = { name: options.text ?? 'Robo' }
return t(interaction, 'commands:hey', { user })
}import { createCommandConfig, t } from '@robojs/i18n'
export const config = createCommandConfig({
nameKey: 'commands:ping.name',
descriptionKey: 'commands:ping.desc',
options: [
{
type: 'string',
name: 'text',
nameKey: 'commands:ping.arg.name',
descriptionKey: 'commands:ping.arg.desc'
}
]
})
export default (interaction, options) => {
const user = { name: options.text ?? 'Robo' }
return t(interaction, 'commands:hey', { user })
}The as const assertion is required for TypeScript to correctly narrow option types in CommandOptions<typeof config>.
What it produces
At runtime, createCommandConfig() resolves all locale keys and builds a standard Robo.js command config with localizations:
descriptionis set from thedefaultLocalevalue ofdescriptionKeydescriptionLocalizationscontains values for all discovered locales- Each option's
nameis set from itsnameKeyusing the default locale - Each option gets
nameLocalizationsanddescriptionLocalizations nameKeyanddescriptionKeyare stripped from the final output
Default locale
The defaultLocale option controls which locale provides the primary name and description values. It defaults to 'en-US'.
Configure it in your plugin options:
export default {
defaultLocale: 'es-ES'
}export default {
defaultLocale: 'es-ES'
}Or in your Robo config:
export default {
plugins: [
['@robojs/i18n', {
defaultLocale: 'es-ES'
}]
]
}export default {
plugins: [
['@robojs/i18n', {
defaultLocale: 'es-ES'
}]
]
}Options
The name field on options is still required alongside nameKey. This helps TypeScript infer option types correctly for CommandOptions<typeof config>.
The descriptionKey field is optional on both the top-level config and individual options. When omitted, no description or description localizations are generated for that level.
export const config = createCommandConfig({
// No descriptionKey — description stays as-is (or undefined)
description: 'A manually set description',
options: [
{
type: 'string',
name: 'text',
nameKey: 'commands:ping.arg.name'
// No descriptionKey — option description stays undefined
}
]
} as const)export const config = createCommandConfig({
// No descriptionKey — description stays as-is (or undefined)
description: 'A manually set description',
options: [
{
type: 'string',
name: 'text',
nameKey: 'commands:ping.arg.name'
// No descriptionKey — option description stays undefined
}
]
})