Events Localization
Event handlers in CommandKit can also benefit from localization, allowing you to create multilingual responses and messages for various Discord events like message creation, member joins, and more.
Using Translations in Event Handlersβ
Since event handlers don't have the same context as commands, you need to import the locale
function directly from the i18n plugin:
src/app/events/messageCreate/handler.ts
import { locale } from '@commandkit/i18n';
import type { Message } from 'discord.js';
export default async function onMessageCreate(message: Message) {
// Skip bot messages
if (message.author.bot) return;
// Get translations for the guild's preferred locale
const { t } = locale(message.guild?.preferredLocale);
if (message.content.toLowerCase() === 'hello') {
await message.reply(t('greeting', { user: message.author.displayName }));
}
if (message.content.toLowerCase() === 'help') {
await message.reply(t('help_message'));
}
}
Event Translation Filesβ
Create translation files for your events using descriptive names:
src/app/locales/en-US/messageCreate.event.json
{
"greeting": "π Hello {{user}}! Welcome to our server!",
"help_message": "π Use `/help` to see all available commands",
"auto_mod": {
"warning": "β οΈ {{user}}, please watch your language!",
"timeout": "π {{user}} has been timed out for inappropriate language"
}
}
src/app/locales/fr/messageCreate.event.json
{
"greeting": "π Salut {{user}} ! Bienvenue sur notre serveur !",
"help_message": "π Utilisez `/help` pour voir toutes les commandes disponibles",
"auto_mod": {
"warning": "β οΈ {{user}}, attention Γ votre langage !",
"timeout": "π {{user}} a Γ©tΓ© mis en sourdine pour langage inappropriΓ©"
}
}
Advanced Event Localizationβ
Guild Welcome Messagesβ
src/app/events/guildMemberAdd/handler.ts
import { locale } from '@commandkit/i18n';
import type { GuildMember } from 'discord.js';
export default async function onGuildMemberAdd(member: GuildMember) {
const { t } = locale(member.guild.preferredLocale);
// Find welcome channel
const welcomeChannel = member.guild.channels.cache.find(
(channel) => channel.name === 'welcome',
);
if (welcomeChannel?.isTextBased()) {
const memberCount = member.guild.memberCount;
await welcomeChannel.send({
content: t('welcome.message', {
user: member.displayName,
guild: member.guild.name,
count: memberCount,
}),
// You can also send embeds with localized content
embeds: [
{
title: t('welcome.embed.title'),
description: t('welcome.embed.description', {
user: member.displayName,
}),
color: 0x00ff00,
fields: [
{
name: t('welcome.embed.fields.rules'),
value: t('welcome.embed.fields.rules_description'),
},
{
name: t('welcome.embed.fields.channels'),
value: t('welcome.embed.fields.channels_description'),
},
],
},
],
});
}
}
src/app/locales/en-US/guildMemberAdd.event.json
{
"welcome": {
"message": "π Welcome {{user}} to **{{guild}}**! You're our **{{count}}** member!",
"embed": {
"title": "Welcome to the Server!",
"description": "Hi {{user}}, we're glad to have you here!",
"fields": {
"rules": "π Rules",
"rules_description": "Please read our rules in #rules channel",
"channels": "π¬ Important Channels",
"channels_description": "Check out #announcements and #general"
}
}
}
}
Locale Detection Strategiesβ
When working with events, you have several options for determining the appropriate locale:
1. Guild Preferred Locale (Recommended)β
// Use the guild's preferred locale set by server admins
const { t } = locale(message.guild?.preferredLocale);
2. User Localeβ
// Use the individual user's Discord locale
const { t } = locale(message.author.locale);
3. Fallback Chainβ
// Try multiple locale sources with fallback
const detectedLocale =
message.guild?.preferredLocale || message.author.locale || 'en-US';
const { t } = locale(detectedLocale);
4. Custom Locale Detectionβ
async function detectLocale(message: Message): Promise<string> {
// Custom logic: check database for user preferences
const userSettings = await getUserSettings(message.author.id);
if (userSettings?.language) {
return userSettings.language;
}
// Fall back to guild locale
return message.guild?.preferredLocale || 'en-US';
}
export default async function onMessageCreate(message: Message) {
const userLocale = await detectLocale(message);
const { t } = locale(userLocale);
// Use translations...
}
Error Handling with Localizationβ
Handle translation errors gracefully in event handlers:
src/app/events/messageCreate/autoMod.ts
import { locale } from '@commandkit/i18n';
import type { Message } from 'discord.js';
const FORBIDDEN_WORDS = ['spam', 'scam', 'hack'];
export default async function autoModerator(message: Message) {
if (message.author.bot) return;
try {
const { t } = locale(message.guild?.preferredLocale);
const hasViolation = FORBIDDEN_WORDS.some((word) =>
message.content.toLowerCase().includes(word),
);
if (hasViolation) {
// Delete the message
await message.delete();
// Send warning
await message.channel.send({
content: t('moderation.auto_warning', {
user: message.author.displayName,
}),
});
// Log the action
console.log(
t('moderation.log_message', {
user: message.author.tag,
guild: message.guild?.name,
channel: message.channel.name,
}),
);
}
} catch (error) {
// Fallback to English if translation fails
console.error('Translation error:', error);
await message.channel.send(
`β οΈ ${message.author.displayName}, please follow our community guidelines.`,
);
}
}
Best Practices for Event Localizationβ
- Always provide fallbacks: Event handlers should gracefully handle missing translations
- Use appropriate locale sources: Choose between guild, user, or custom locale detection based on context
- Keep translations consistent: Use the same tone and style across events and commands
- Test with different locales: Ensure your events work correctly with various language settings
- Cache translations when possible: For high-frequency events, consider caching translation functions