# Internationalization (Languages)

## Internationalization

**Files:** `src/config/language.json`, `src/config/config.toml`, `src/i18n/`, `src/config/menu.*.json`, `src/content/**/<language>/` · **Skill level:** Beginner

Consultiz ships in **English** (the default, at `/`) and **French** (at `/fr/`). Every page, menu, and label exists in both. Right-to-left languages are not supported.

### What Makes Up A Language
| Part                  | Files                                                                      |
| --------------------- | -------------------------------------------------------------------------- |
| The language itself   | An entry in `src/config/language.json`                                     |
| Page and section text | A folder per language in every content folder: `src/content/sections/french/`, `src/content/blog/french/`, … |
| Interface text        | `src/i18n/fr.json` (labels, form messages, footer text)                    |
| Menus                 | `src/config/menu.fr.json`                                                  |

In `src/config/language.json`:

```json
[
  { "languageName": "English", "languageCode": "en", "ogLocale": "en_US", "contentDir": "english", "weight": 1 },
  { "languageName": "Français", "languageCode": "fr", "ogLocale": "fr_FR", "contentDir": "french", "weight": 2 }
]
```

`languageName` is shown in the language switch, `languageCode` is the URL prefix and the file suffix (`fr.json`, `menu.fr.json`), `ogLocale` is the Open Graph locale, and `contentDir` is the folder name inside each content folder.

### Language Settings
```toml
# src/config/config.toml
[settings.multilingual]
  enable               = true
  defaultLanguage      = "en"
  disableLanguages     = [""]     # for example ["fr"]
  showDefaultLangInUrl = false    # true gives /en/pricing/ instead of /pricing/
```

Restart `npm run dev` after any change here.

### Use English Only
You have two options:

- **Turn French off, keep the files.** Set `enable = false` (or `disableLanguages = ["fr"]`). Only English is built and the language switch disappears. You can turn French back on any time.
- **Delete French for good.** First set `enable = false` and run `npm run dev` or `npm run astro-check` once, so `.astro/config.generated.json` exists (the script reads your default language from it). Then save a checkpoint (a git commit or a copy of the folder) and run:

  ```bash
  npm run remove-multilingual
  ```

  It deletes every `french/` content folder, `src/i18n/fr.json`, and `src/config/menu.fr.json`, and removes French from `language.json`. This can't be undone without your checkpoint.

<Aside type="caution">
  `remove-multilingual` keeps only `en.json` and `menu.en.json`. Use it only
  when English is your default language. Also remove the `/fr/*` redirect from
  `netlify.toml` afterwards.
</Aside>

### Replace French With Another Language
The easiest way to get a Spanish (or German, or Dutch) site is to turn the French copy into it:

<Steps>

1. In `language.json`, change the French entry to `"languageName": "Español"`, `"languageCode": "es"`, `"ogLocale": "es_ES"`, `"contentDir": "spanish"`.

2. Rename every `src/content/**/french/` folder to `spanish/`.

3. Rename `src/i18n/fr.json` to `es.json` and `src/config/menu.fr.json` to `menu.es.json`.

4. Translate the text values in those files and folders. Keep every key as it is, and change internal links in Markdown text from `/fr/` to `/es/`.

5. In `netlify.toml`, change the `/fr/*` redirect to `/es/*` and `/es/404.html`.

6. Restart `npm run dev` and open `/es/`.

</Steps>

### Add A Third Language
<Steps>

1. Add an entry to `language.json`, for example `{ "languageName": "Deutsch", "languageCode": "de", "ogLocale": "de_DE", "contentDir": "german", "weight": 3 }`.

2. Copy `src/i18n/en.json` to `de.json` and `src/config/menu.en.json` to `menu.de.json`, then translate them.

3. In every content folder that has an `english/` folder, create a `german/` copy and translate it.

4. On Netlify, add a redirect block for `/de/*` to `netlify.toml`, like the French one.

5. Restart `npm run dev` and open `/de/`.

</Steps>

<FileTree>

- src/content/
  - sections/
    - english/
    - french/
    - **german/**
  - blog/
    - english/
    - french/
    - **german/**

</FileTree>

<Aside type="danger" title="generate-multilingual-content overwrites French">
  `npm run generate-multilingual-content` copies the English files over the
  `french/` folders, `fr.json`, and `menu.fr.json`, which **replaces** the
  shipped French translations with English text. Don't use it to add a
  language; follow the steps above.
</Aside>

### Links Between Pages
- In menus and in `url` fields of buttons and links in content files, write the English path (`/pricing/`). Consultiz adds the language prefix for you.
- In **Markdown text** (the body of a post or page), write the full path for that language yourself: `[see pricing](/fr/pricing/)` in a French file.
- Give each page the same file name in every language, and the same `customSlug` if you use one, so the language switch finds the matching page.
- The case study list page in French can leave out fields: missing ones fall back to the English `-index.md`.

### Translated 404 Pages
Each language has its own 404 page (`/fr/404.html`). On Netlify, the redirect in `netlify.toml` sends a missing `/fr/...` address to it; add one block per extra language. Other hosts show the default (English) 404 page for every language unless you set up a similar rule.

### Interface Text
Labels that are not page content live in `src/i18n/en.json` and `fr.json`, for example the blog post details: `blog.minutesRead` (`"{count} min read"`), `blog.lastUpdate`, and `blog.defaultAuthor` (shown for posts without an `author`, or with `author: "admin"`). The site tagline is `common.tagline` when `[site] tagline` is empty. Translate these files along with your content.