> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/discordplace/discord.place/llms.txt
> Use this file to discover all available pages before exploring further.

# Localization

> Add new languages to the discord.place client and server.

discord.place supports multiple languages across both the Next.js client and the Discord bot server. Translations are stored as JSON files and wired up through a small amount of configuration.

## Currently supported locales

<Tabs>
  <Tab title="Client">
    The client (`client/locales/`) currently ships with these language files:

    | Language    | Code | File      |
    | ----------- | ---- | --------- |
    | English     | `en` | `en.json` |
    | Turkish     | `tr` | `tr.json` |
    | Azerbaijani | `az` | `az.json` |

    English is the default locale.
  </Tab>

  <Tab title="Server">
    The server (`server/src/locales/`) currently ships with these language files:

    | Language | Code | File      |
    | -------- | ---- | --------- |
    | English  | `en` | `en.json` |
    | Turkish  | `tr` | `tr.json` |

    English is the default locale.
  </Tab>
</Tabs>

## Adding a new language

<Tabs>
  <Tab title="Client">
    <Steps>
      <Step title="Create the locale JSON file">
        Add a new JSON file to `client/locales/` named after the language code, e.g. `fr.json` for French. Use an existing file like `en.json` as a reference for all the keys that need to be translated.

        The JSON structure is a nested object where keys are translation identifiers and values are the translated strings:

        ```json client/locales/fr.json theme={null}
        {
          "home": {
            "title": "Tout ce qui concerne Discord",
            "subtitle": "..."
          }
        }
        ```
      </Step>

      <Step title="Register the locale in config.js">
        Add the new locale to the `availableLocales` array in `client/config.js`:

        ```javascript client/config.js theme={null}
        availableLocales: [
          // ...existing locales
          {
            name: 'French',
            code: 'fr',
            dateFnsKey: 'fr',
            flag: '🇫🇷',
            countryCode: 'fr'
          }
        ],
        ```

        The `dateFnsKey` must match the locale key used by the [`date-fns`](https://date-fns.org/docs/I18n) library.
      </Step>

      <Step title="Import the locale file in the language store">
        Open `client/stores/language/index.js` and add an import for your new locale file alongside the existing ones:

        ```javascript client/stores/language/index.js theme={null}
        import en from '@/locales/en.json';
        import tr from '@/locales/tr.json';
        import az from '@/locales/az.json';
        import fr from '@/locales/fr.json'; // add this
        ```
      </Step>

      <Step title="Add the locale to localeContents">
        In the same file (`client/stores/language/index.js`), add your new locale to the `localeContents` object inside the `t()` function:

        ```javascript theme={null}
        const localeContents = {
          en,
          tr,
          az,
          fr, // add this
        };
        ```

        The client will now serve your new language to users who select it in the language picker.
      </Step>
    </Steps>

    <Warning>
      If you want to change the **default locale**, set `default: true` on the desired locale object in `client/config.js` (and remove it from the current default). You must also update the `DEFAULT_LOCALE_CODE` environment variable in `.github/workflows/validate-locale-files.yml` — otherwise the locale validation GitHub Actions workflow will report errors on every push.
    </Warning>
  </Tab>

  <Tab title="Server">
    <Steps>
      <Step title="Create the locale JSON file">
        Add a new JSON file to `server/src/locales/` named after the language code, e.g. `fr.json` for French. Use `en.json` as a reference for all the keys that need to be translated.

        The JSON structure is a flat or nested object of translation strings:

        ```json server/src/locales/fr.json theme={null}
        {
          "time": {
            "seconds": "secondes",
            "minutes": "minutes",
            "hours": "heures",
            "days": "jours"
          }
        }
        ```
      </Step>

      <Step title="Register the locale in config.yml">
        Add an entry for the new language to the `availableLocales` array in `server/config.yml`:

        ```yaml server/config.yml theme={null}
        availableLocales:
          - name: 'English'
            code: 'en'
            flag: '🇺🇸'
            default: true
            countryCode: 'us'
          - name: 'French'   # add this entry
            code: 'fr'
            flag: '🇫🇷'
            countryCode: 'fr'
        ```
      </Step>

      <Step title="Add all translation keys">
        Fill in every key from the reference `en.json` file in your new locale file. Keys that are missing will not fall back gracefully — the raw key string is returned instead.

        <Note>
          Some languages may not be officially supported by the Discord client, which affects how locale-specific features behave within Discord itself.
        </Note>
      </Step>
    </Steps>
  </Tab>
</Tabs>

## Locale file structure

Both the client and server use JSON files with a nested key structure. Top-level keys group related strings by feature area.

**Client locale example** (`client/locales/en.json`):

```json theme={null}
{
  "home": {
    "title": "All things related to Discord",
    "subtitle": "A place for all things that related to Discord..."
  },
  "common": {
    "save": "Save",
    "cancel": "Cancel"
  }
}
```

**Server locale example** (`server/src/locales/en.json`):

```json theme={null}
{
  "time": {
    "seconds": "seconds",
    "minutes": "minutes",
    "hours": "hours",
    "days": "days"
  },
  "commands": {
    "shared": {
      "errors": {
        "missing_permissions": "You don't have permission to use this command."
      }
    }
  }
}
```

Some strings support interpolation placeholders using curly braces, e.g. `"An error occurred: {errorMessage}"`.

## Contributing translations

If you'd like to contribute a new translation or improve an existing one, see the [Contributing Translations](/contributing/translations) guide.
