Supporting different languages
Seyfert has a i18n built-in feature that allows you to create language files and use them in your bot.
For this section we are going to follow the setup we did in Getting Started for example purposes
Updating seyfert config
Before starting this chapter we could update seyfert.config.mjs to tell seyfert where our languages file will be.
// @ts-check
import { } from "seyfert";
export default .({
: .. ?? "",
: ["Guilds"],
: {
: "dist",
: "commands",
: "events",
: "languages" // - src/languages will be our languages directory
}
});Creating a language file
Each language file shall export by default an object containing the translations for the language.
export default {
: "Each key value pair will be the translation for the key",
: {
: "You may nest objects to create a more complex language file",
: () => `You may also use functions to pass variables to the translation and add some logic`,
: ({ }: { : number }) => `The ping is ${}`
},
: [
"You may also use arrays to create a list of translations",
"This is the second item in the list"
].("\n")
}You can create as many language files as you want, seyfert will load them and they will be available to use in your bot.
import type English from "./en";
export default {
hello: "Hola, mundo!",
foo: {
bar: "Puedes anidar objetos para crear un archivo de idioma más complejo",
baz: () => `Puedes usar funciones para pasar variables a la traducción y agregar lógica`,
ping: ({ ping }) => `El ping es ${ping}`
},
qux: [
"También puedes usar arrays para crear una lista de traducciones",
"Este es el segundo elemento de la lista"
].join("\n")
} satisfies typeof English; // This is a utility type to ensure that object is the same across languagesEach key should return either a string or a function that returns a string.
The name of the file will be the language code, that you will use to get the language translations.
Next we must do some updates to the declare module on index file:
import type English from './languages/en';
import { Client, type ParseClient, type ParseLocales } from "seyfert";
const client = new Client();
client.start();
declare module 'seyfert' {
interface UsingClient extends ParseClient<Client<true>> { }
// interface UsingClient extends ParseClient<HttpClient> { } // If you are using the rest api
interface DefaultLocale extends ParseLocales<typeof English> { }
}Preventing errors
You can assign a default language to avoid getting undefined.
import { } from "seyfert";
const = new ();
// ---cut--- snoopy
.({ : { : 'en-US' } });You can pass any of the language files to the DefaultLocale interface since they should be the same object structure.
After doing this, you can use the language in your commands, events, components, etc.
Using translations in your commands
Let's see an example with our ping command by adding an option to respond in a specific language
import {
,
,
,
,
,
type
} from 'seyfert';
import { } from 'seyfert/lib/types';
const = {
: ({
: "Hide command output",
}),
: ({
: "Language to respond in",
: [
{ : "English", : "en" },
{ : "Spanish", : "es" }
]
})
}
@({
: 'ping',
: 'Show the ping with discord'
})
@()
export default class extends {
async (: <typeof >) {
const = .. ? . : ;
const = ..;
// Get the translations for the language
const = ..();
// average latency between shards
const = ...;
await .({
: ..({ }),
,
});
}
}Below is the current file tree of the project if you did follow the previous steps.