# How to Add New Languages to the ML-For-Beginners Curriculum Translations

> Expand the ML-For-Beginners curriculum! Learn how to add new languages by registering translations, creating dictionaries, and running the translate script.

- Repository: [Microsoft/ML-For-Beginners](https://github.com/microsoft/ML-For-Beginners)
- Tags: how-to-guide
- Published: 2026-02-28

---

**To add a new language to the ML-For-Beginners curriculum, register the language in [`site/_data/languages.yml`](https://github.com/microsoft/ML-For-Beginners/blob/main/site/_data/languages.yml), create a translation dictionary in `site/_i18n/<lang>.json`, and run [`scripts/translate_notebooks.py`](https://github.com/microsoft/ML-For-Beginners/blob/main/scripts/translate_notebooks.py) to generate localized notebooks.**

The Microsoft ML-For-Beginners repository provides a comprehensive machine learning curriculum built as Jupyter notebooks and Markdown pages. The project uses a modular internationalization (i18n) system that externalizes all user-visible strings, enabling community contributors to add new languages without modifying the core lesson logic. This guide walks through the exact file paths and commands required to extend the curriculum to additional languages.

## Register the Language in the Manifest

The first step is declaring the new language to the static site generator so it appears in the language selector and routing system.

1. Open **[`site/_data/languages.yml`](https://github.com/microsoft/ML-For-Beginners/blob/main/site/_data/languages.yml)**, which serves as the central registry of supported languages.
2. Append a new YAML block using the ISO-639-1 language code (e.g., `es` for Spanish, `de` for German). The block requires three keys:

   ```yaml
   - code: es
     name: Español
     direction: ltr
   ```

   - `code`: The ISO-639-1 identifier used in URLs and file paths.
   - `name`: The human-readable label displayed in the UI dropdown.
   - `direction`: Use `ltr` for left-to-right scripts or `rtl` for right-to-left languages like Arabic or Hebrew.
3. Commit the change. The site generator will automatically include the new option in the navigation menu during the next build cycle.

## Create the Translation Dictionary

Next, provide the actual translated strings by creating a JSON dictionary that maps source identifiers to localized text.

1. Duplicate an existing translation file as a template. For example, copy [`site/_i18n/en.json`](https://github.com/microsoft/ML-For-Beginners/blob/main/site/_i18n/en.json) to `site/_i18n/<lang>.json` (e.g., [`site/_i18n/de.json`](https://github.com/microsoft/ML-For-Beginners/blob/main/site/_i18n/de.json) for German).
2. Translate every value in the JSON file while preserving the keys exactly. The keys are the contract between the source notebooks and the translation system.

   Example excerpt from [`site/_i18n/de.json`](https://github.com/microsoft/ML-For-Beginners/blob/main/site/_i18n/de.json):

   ```json
   {
     "welcome_title": "Willkommen beim maschinellen Lernen",
     "next_button": "Weiter",
     "previous_button": "Zurück"
   }
   ```

3. Validate the JSON structure using the provided linter to ensure no keys are missing or extraneous:

   ```bash
   python scripts/check_translations.py --lang de
   ```

   The script compares your new file against the base English dictionary and reports any discrepancies. Fix any missing keys before proceeding.

## Generate Translated Notebooks

With the dictionary in place, run the translation script to produce language-specific copies of every Jupyter notebook.

Execute the following command from the repository root:

```bash
python scripts/translate_notebooks.py --source notebooks/ --target content/de/ --lang de

```

- `--source`: Path to the original English notebooks (the source of truth).
- `--target`: Output directory where translated notebooks are written. The CI pipeline typically places these under `content/<lang-code>/`.
- `--lang`: The ISO-639-1 code matching your new dictionary file.

The script processes each notebook by:

1. Parsing every Markdown cell and searching for `{{t('key')}}` template placeholders.
2. Substituting each placeholder with the corresponding value from `site/_i18n/<lang>.json`.
3. Writing the transformed notebook while leaving code cells untouched to preserve executable examples.

After generation, the GitHub Actions workflow defined in [`.github/workflows/build.yml`](https://github.com/microsoft/ML-For-Beginners/blob/main/.github/workflows/build.yml) automatically detects the new content and publishes it to a language-specific URL (e.g., `https://mlforkids.com/de/`).

## Verify the New Language on the Live Site

Before merging your contribution, validate the integration through the CI pipeline.

1. Push your branch and open a Pull Request.
2. Wait for the GitHub Actions workflow to complete. The pipeline generates a preview deployment (usually hosted on Netlify or GitHub Pages).
3. Navigate to the preview URL and test the following:
   - The language selector displays your new entry with the correct `name` from [`languages.yml`](https://github.com/microsoft/ML-For-Beginners/blob/main/languages.yml).
   - Clicking the language loads the translated notebooks with UI elements (buttons, navigation) rendered from your JSON dictionary.
   - Instructional text in Markdown cells appears in the target language while Python code blocks remain identical to the English source.
   - Browser developer tools show no 404 errors for missing translation keys or template syntax errors.

Once verification passes, maintainers can merge the PR, making the curriculum available to learners worldwide.

## Summary

- **Register the language** by adding an entry to [`site/_data/languages.yml`](https://github.com/microsoft/ML-For-Beginners/blob/main/site/_data/languages.yml) with the ISO-639-1 code, display name, and text direction.
- **Create the translation dictionary** by copying [`site/_i18n/en.json`](https://github.com/microsoft/ML-For-Beginners/blob/main/site/_i18n/en.json) to a new file named after your language code, translating all values while preserving keys, and validating with [`scripts/check_translations.py`](https://github.com/microsoft/ML-For-Beginners/blob/main/scripts/check_translations.py).
- **Generate notebooks** by running [`scripts/translate_notebooks.py`](https://github.com/microsoft/ML-For-Beginners/blob/main/scripts/translate_notebooks.py) with the appropriate source, target, and language arguments to produce localized Jupyter files.
- **Verify via CI** by opening a Pull Request and checking the preview deployment for correct UI rendering, navigation, and content translation.

## Frequently Asked Questions

### What file format is used for the translation dictionaries?

The translation dictionaries are standard JSON files stored in `site/_i18n/<lang-code>.json`. Each file contains key-value pairs where the key is a string identifier used in the notebook templates and the value is the translated text for that language.

### Do I need to translate the Python code cells in the notebooks?

No. The translation process only affects Markdown cells containing instructional text. The [`translate_notebooks.py`](https://github.com/microsoft/ML-For-Beginners/blob/main/translate_notebooks.py) script specifically preserves code cells to ensure all executable examples remain identical across languages, preventing syntax errors or behavioral differences.

### How do I validate that my translation file is complete before submitting?

Run the provided linter script `python scripts/check_translations.py --lang <your-lang-code>`. This tool compares your JSON file against the base English dictionary and reports any missing keys or extra entries that do not exist in the source, ensuring parity before generation.

### Can I add a right-to-left (RTL) language like Arabic or Hebrew?

Yes. When registering the language in [`site/_data/languages.yml`](https://github.com/microsoft/ML-For-Beginners/blob/main/site/_data/languages.yml), set the `direction` field to `rtl` instead of `ltr`. The static site generator uses this value to apply appropriate CSS text direction and layout adjustments for proper RTL rendering.