> ## Documentation Index
> Fetch the complete documentation index at: https://www.chapterjs.org/llms.txt
> Use this file to discover all available pages before exploring further.

# language()

> Everything language() declares, and t, which every function receives

`language()` declares one language of the bot, from any file of `src/`. It takes one object, `LanguageConfig`, whose `locale` is the language.

```ts src/messages/en-US.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
import { language } from 'chapterjs';

export default language({
  locale: 'en-US',
  default: true,
  texts: {
    pong: 'Pong!',
    welcome: 'Welcome {name}, you are member #{count}!',
    next: 'Page {page}',
    members: { one: '{count} member', other: '{count} members' },
  },
});
```

> [!NOTE]
>
> How to write the files and which language `t` speaks is in the
> [guide](https://www.chapterjs.org/translated-messages.md). This page lists what exists.

## language()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
language<const T extends MessageTexts, L extends Locale>(config: LanguageConfig<T, L>): LanguageDeclaration<T, L>
```

Declares one language of the bot, or more texts of it. Export the result from any file of `src/`; `locale` says which language: every handler then receives `t`, which gives a text in the language of who will read the message, with its `{placeholders}` filled in. A language may be declared in several places: the texts of a feature next to it, with the same `locale`, add to the others.

### LanguageConfig

What a file gives to `language()`.

**locale** `Locale` *required*

The language these texts are in: `'en-US'`, `'fr'`...

**texts** `MessageTexts` *required*

The texts of the bot in this language, by key.

**default** `boolean`

Whether this is the language used when the one of a person or of a server is
not declared. Exactly one language says so; with one language, it goes
without saying. When another language already says it, this is refused:
only one can be the default. Once the files ran (`chapterjs dev`, `chapterjs
    build`), a second language saying so is a type error on the `default: true`
of both (see `ProjectLanguageDefaults`).

**commands** `CommandsTranslations`

What Discord shows of the commands in this language.

**framework** `Partial\<FrameworkTexts\>`

What the bot answers by itself in this language, when it can't run what was
asked: the phrases of `FrameworkTexts`, the ones this file wants to translate.
The others stay in English.

### MessageTexts

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type MessageTexts = Record<string, MessageText>;
```

The texts of one language, by key.

### MessageText

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type MessageText = string | PluralText;
```

One text of a language: a string, with its `{placeholders}`, or a text with several forms, picked by `count`.

### PluralText

A text with several forms, one per quantity: `t('members', { count })` picks the form of the language for that number (`one` for 1 in English, `other` for the rest; French, Russian or Arabic have others). `other` is always there; the forms a language does not use are left out. `{count}` in a form is the number itself.

**other** `string` *required*

**zero** `string`

For 0, in every language; and where a language has a form of its own for other numbers too (Arabic, Latvian).

**one** `string`

**two** `string`

**few** `string`

**many** `string`

### FrameworkTexts

What the bot answers by itself, when it can't run what was asked: where a command or a component can't be used, a button of an old message, a `run` that failed... Every phrase has an English version; a language file gives its own in `framework`, the ones it wants. `{what}` is the word for what was used: `command`, `button`, `menu` or `form`, given here too.

| Key | English |
| - | - |
| `command` | The word for a command: "command". |
| `button` | The word for a button: "button". |
| `menu` | The word for a select menu: "menu". |
| `form` | The word for a form: "form". |
| `guildOnly` | "This {what} can only be used in a server." |
| `dmOnly` | "This {what} can only be used in a private message with me." |
| `notHere` | "This {what} can not be used here." |
| `unavailable` | "This command is not available right now." (its file is gone or broken) |
| `gone` | "This {what} is not available any more." (an old message, its file is gone) |
| `outdated` | "This {what} is out of date." (an old message, its `data` changed) |
| `authorOnly` | "Only the person who used the command can use this {what}." |
| `failed` | "Something went wrong while running this {what}." |
| `missingPermission` | "I don't have the permission to do that here." |
| `cooldown` | "You can use this {what} again {when}." (a `cooldown` not over yet); `{when}` is a Discord timestamp, shown as "in 5 seconds" (or a date and time past 15 minutes) in the language of the person. |
| `needsPermissions` | "You need the {permissions} permission to use this command." A plural of `count`, how many permissions are missing; `{permissions}` is their names as people read them (Ban Members), separated by commas. |

### CommandsTranslations

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type CommandsTranslations = {
  readonly [
    Path in keyof ProjectCommands as ProjectCommands[Path] extends true
      ? Path
      : never
  ]?: CommandTranslation;
};
```

What Discord shows of the commands in one language: by the name of the command (`'ping'`, `'mod ban'`), its name, description, options and choices in that language, as the `locales` of a command file take them ([`CommandTranslation`](https://www.chapterjs.org/reference/command#commandtranslation)). The editor offers the commands of the project that have no `description` in their file (one that has owns its texts, `locales` included); their options and choices are checked when the files load.

### ProjectCommands

The commands of the project, as the editor sees them: the name of each command, `true` when the language files describe it, `false` when the command has its own `description`. Filled in by the `.chapterjs/` folder of the project, so that the `commands` of a language file offers the ones it may translate. The options and choices are checked when the files load.

### ProjectLanguageDefaults

The languages that say `default: true` when more than one does, as the editor sees them: one key per language. Filled in by the `.chapterjs/` folder of the project, so that each of them is underlined; empty when at most one language says it.

### LanguageDeclaration

What `language()` returns: a declaration the framework finds in the exports of a file.

**config** `LanguageConfig\<T, L\>` *required*

What the file gave to `language()`, not checked yet.

## Translator

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
interface Translator<M extends object = ProjectMessages>
```

`t`, as handlers receive it: gives a text of the language files in the language of who will read the message, with its placeholders filled in. `M` is the texts of the default language, which types the keys and the params: a text another language does not have is taken from it.

### t()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
t<K extends keyof M & string>(key: K, ...params: ParamsArgs<TextOf<M, K>>): string
```

**locale** `Locale` *required*

The language the texts come from: the one asked, or the closest one declared.

### in()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
in<L extends ProjectLocale | (string & {}), K extends keyof M & string>(locale: LocaleGiven<L>, key: K, ...params: ParamsArgs<TextOf<M, K>>): string
```

A text in another language: `t.in('fr', 'welcome', { name })`, or `t.in(owner.locale, 'pong')`. The language of the person who will read it, when it is not the one `t` speaks.

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
in<L extends ProjectLocale | (string & {})>(locale: LocaleGiven<L>): Translator<M>
```

The same `t` for another language, to write several texts: `t.in('fr')('welcome', { name })`.

### ProjectLocales

The languages of the project, as the editor sees them: one key per language declared. Filled in by the `.chapterjs/` folder of the project, empty when the project has no language.

### ProjectLocale

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type ProjectLocale = keyof ProjectLocales & string;
```

A language of the project: `'en-US'`, `'fr'`...

### LocaleGiven

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type LocaleGiven<L extends string> = L extends Locale ? L : ProjectLocale;
```

A language given to `t.in()`: the editor offers the ones of the project, and any language of Discord is accepted (the one of a person, of a server), `t` then taking the closest one declared. A word that is no language of Discord is underlined, with the ones of the project.

### TranslationContext

`TranslationContext` is what every handler receives when the project has a language: `t`. Nothing otherwise.

**t** `Translator`

The texts of the language files, in the right language.

### ProjectMessages

The texts of the project, as the editor sees them: the keys `t` accepts and the placeholders of each, from every declaration of every language, the default language first. Filled in by the `.chapterjs/` folder of the project when it has a language, empty otherwise.

### MergedMessages

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type MergedMessages<T extends readonly object[]>
```

The texts of several declarations, the first one winning for a key several have: what `t` is typed from when a project has several languages, the default one first, then the others (a text the default language does not have is taken from the language that has it).

### MessagesOf

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type MessagesOf<F> = F extends LanguageDeclaration<infer T> ? T : never;
```

What `t` is typed from, for a language file: its texts.

## The texts of a component

### DynamicText

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type DynamicText<Data extends DataShape = DataShape> =
  string | ((context: TextContext<Data>) => string);
```

A text shown by a component: written as is, or computed when the message is sent, from `t` and the data of the component.

### TextContext

What a text of a component is computed from when it is a function: `t` in the language of who will read the message, and the data the component carries.

**t** `Translator` *required*

The texts of the language files, in the language of who will read the message.

**data** `DataValuesOf\<Data\>` *required*

What the component carries, as declared in `data`.

## Placeholders

### Placeholders

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type Placeholders<T extends MessageText>
```

The placeholders of a text: `'Hello {name}'` has `'name'`. Written between braces, a placeholder is a name made of letters, digits and `_`; `{{` and `}}` are braces written as is. A plural has `count`, and the placeholders of its forms.

### ParamsOf

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type ParamsOf<T extends MessageText> = {
  [Name in Placeholders<T>]: Name extends 'count'
    ? T extends PluralText
      ? number
      : string | number
    : string | number;
};
```

What `t` takes for a text: one value per placeholder, or nothing when the text has none. A number is written the way the language writes numbers (`1,234` in English, `1 234` in French): give a text to keep it as is. The `count` of a plural is a number.

### ParamsArgs

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type ParamsArgs<T extends MessageText> = string extends T
  ? [params?: Record<string, string | number>]
  : [Placeholders<T>] extends [never]
    ? []
    : [params: ParamsOf<T>];
```

The arguments of `t` after the key: the params, only when there are some.

[Discord documentation](https://docs.discord.com/developers/reference#locales)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.