# Localization

Gravity ships with localization support and two languages (English and Spanish) out of the box. This section will example how to use localization on the server side.

{% hint style="info" %}
Refer to the [client-side localisation section](https://docs.usegravity.app/gravity-web/localization) to learn how to translate the UI.
{% endhint %}

Localization is managed with the i18n package, which can be used to translate individual requests depending on the language provided by the client using the `Accept-Language` header.

## Locale Files

Locale files are stored inside the `/locales` folder, and each language has its own folder of `.json` files. The locales are split up based on entities in the application to match the same structure as the models, views and controllers.

All `.json` files inside each locale folder are automatically imported and combined using the i18n `helper.config()` method, so you can add more JSON files without explicitly importing them anywhere.

```
/locales
  /en
    en_account.json
    en_user.json
  /es
    es_account.json
    es_user.json
```

The locale files are simple JSON files containing the strings. The keys are always the same (in English) as these are referenced in the code. The string changes depending on the language.

```javascript
// en_account.json
{
  "create": {
    "denied": "Registration denied",
    "duplicate": "You have already registered an account",
    "duplicate_child": "You already have an account registered with this email address. Please enter your original password to continue"
}

// es_account.json
"create": {
  "denied": "Registro denegado",
  "duplicate": "Ya has registrado una cuenta",
  "duplicate_child": "Ya tienes una cuenta registrada con esta dirección de correo electrónico. Por favor, introduce tu contraseña original para continuar"
  },
```

### Adding More Locales

{% hint style="info" %}
Pro tip – ask [ChatGPT](https://chat.openai.com/) to translate the JSON files to new languages.
{% endhint %}

1. Create a new folder inside /locales eg. `/fr`
2. Add the new locale to the locales array in `/helper/i18n`

```javascript
i18n.configure({

  defaultLocale: 'en',
  locales: ['en', 'es', 'fr'], // add new locale here
  updateFiles: false,
  objectNotation: true,
  staticCatalog: translations

});
```

## Performing Translations

Translations can be performed in two ways:&#x20;

1. Using the i18n package and setting the locale
2. Using the `res` object.

```javascript
// translate
const i18n = require('i18n'); 

function translateWithi18n(req, res){

 // translate using the i18n package
  i18n.setLocale(req.locale);
  return res.status(200).send({ message: i18n.__('account.plan.updated'));

}

function translateWithRes(req, res){
    
  // translate using res
  return res.status(200).send({ message: res.__('account.plan.updated'));

}

```

You can use the `locale` column on the user table when neither option is available, for example, in a background job worker.

### Translating Controllers

To translate inside a controller method with the `res` object available, use the `res.__` method.

### Translating Models & Helpers

If the `res` object is unavailable - i.e. you're translating a model or helper file, you can pass the `req.locale` var to the method.

```javascript
function controller(req, res){

  convertToMonthName(2, req.locale);
  
}

function convertToMonthName(month, locale){

  locale && i18n.setLocale(locale);
  const monthNames = i18n.__('global.months').split(',')
  return monthNames[month-1];

}
```

## Handling Plurals

The `i18nHelper` has a method for handling plurals for you. You just need to structure your JSON as follows, and pass the translation key and number to the helper.

<pre class="language-javascript"><code class="lang-javascript"><strong>{
</strong> "sent": {
   "one": "Invite sent",
   "other": "Invites sent"
  }
}

<strong>i18nHelper.plural('invite.sent', emails.length);
</strong></code></pre>

## Emails

Emails are handled slightly differently because the content is stored in the database, not the locale files. Each email in the `email` table has a `locale` column so the content can be localised. You pass the `locale` as part of the data prop to the mail method.

```javascript
await mail.send({

 to: userData.email,
 locale: req.locale,
 template: 'new_account'
 
});

```
