An open API service indexing awesome lists of open source software.

https://github.com/activist-org/i18n-check

Check i18n/L10n keys and values
https://github.com/activist-org/i18n-check

cd ci cicd continuous-delivery continuous-integration github-actions hacktoberfest i18n internationalization l10n localization python validation

Last synced: about 2 months ago
JSON representation

Check i18n/L10n keys and values

Awesome Lists containing this project

README

          


i18n check logo

[![rtd](https://img.shields.io/readthedocs/i18n-check.svg?label=%20&logo=read-the-docs&logoColor=ffffff)](http://i18n-check.readthedocs.io/en/latest/)
[![ci_static_analysis](https://img.shields.io/github/actions/workflow/status/activist-org/i18n-check/ci_static_analysis.yaml?branch=main&label=%20&logo=ruff&logoColor=ffffff)](https://github.com/activist-org/i18n-check/actions/workflows/ci_static_analysis.yaml)
[![ci_pytest](https://img.shields.io/github/actions/workflow/status/activist-org/i18n-check/ci_pytest.yaml?branch=main&label=%20&logo=pytest&logoColor=ffffff)](https://github.com/activist-org/i18n-check/actions/workflows/ci_pytest.yaml)
[![issues](https://img.shields.io/github/issues/activist-org/i18n-check?label=%20&logo=github)](https://github.com/activist-org/i18n-check/issues)
[![python](https://img.shields.io/badge/Python-4B8BBE.svg?logo=python&logoColor=ffffff)](https://github.com/activist-org/i18n-check/blob/main/CONTRIBUTING.md)
[![pypi](https://img.shields.io/pypi/v/i18n-check.svg?label=%20&color=4B8BBE)](https://pypi.org/project/i18n-check/)
[![pypistatus](https://img.shields.io/pypi/status/i18n-check.svg?label=%20)](https://pypi.org/project/i18n-check/)
[![license](https://img.shields.io/github/license/activist-org/i18n-check.svg?label=%20)](https://github.com/activist-org/i18n-check/blob/main/LICENSE.txt)
[![coc](https://img.shields.io/badge/Contributor%20Covenant-ff69b4.svg)](https://github.com/activist-org/i18n-check/blob/main/.github/CODE_OF_CONDUCT.md)
[![matrix](https://img.shields.io/badge/Matrix-000000.svg?logo=matrix&logoColor=ffffff)](https://matrix.to/#/#activist_community:matrix.org)

# Contents

- [About i18n-check](#about-i18n-check)
- [Installation](#installation)
- [Users](#users)
- [Development Build](#development-build)
- [Key Conventions](#key-conventions)
- [How It Works](#how-it-works)
- [Commands](#commands)
- [Checks](#checks)
- [Example Responses](#example-responses)
- [Configuration](#configuration)
- [YAML File](#yaml-file)
- [Arguments](#arguments)
- [Additional Arguments](#additional-arguments)
- [pre-commit](#pre-commit)
- [GitHub Action](#github-action)
- [Contributing](#contributing)
- [Contact the Team](#contact-the-team)
- [Contributors](#contributors)

# About i18n-check

> [!IMPORTANT]
> Before you contribute, read the [contributing guide](CONTRIBUTING.md).

`i18n-check` is a Python package that automates the validation of keys and values for your internationalization and localization processes.

Developed by the [activist community](https://github.com/activist-org), this package helps keep development and i18n/L10n teams in sync when using JSON-based localization processes.

# Installation

## Users

You can install `i18n-check` using [uv](https://docs.astral.sh/uv/) (recommended) or [pip](https://pypi.org/project/i18n-check/).

### uv

(Recommended - fast, Rust-based installer)

```bash
uv pip install i18n-check
```

### pip

```bash
pip install i18n-check
```

## Development Build

You can install the latest development build using uv, pip, or by cloning the repository.

### Clone the Repository (Development Build)

```bash
git clone https://github.com/activist-org/i18n-check.git # or ideally your fork
cd i18n-check
```

### uv (Development Build)

```bash
uv sync --all-extras # install all dependencies
source .venv/bin/activate # activate venv (macOS/Linux)
# .venv\Scripts\activate # activate venv (Windows)
```

### pip (Development Build)

```bash
python -m venv .venv # create virtual environment
source .venv/bin/activate # activate venv (macOS/Linux)
# .venv\Scripts\activate # activate venv (Windows)
pip install -e .
```

Back to top.

# Key Conventions

`i18n-check` enforces these conventions for all keys:

- All keys must begin with `i18n.`.
- The base path must be the file path where the key is used.
- If a key is used in more than one file, the base path must be the lowest common directory and end with `_global`.
- Base paths must be followed by a minimally descriptive content reference (`i18n-check` only checks content references for formatting).
- Separate base paths with periods (`.`).
- Separate directory / file name components and content references with underscores (`_`).
- Repeated words in the file path, including the file name, must not be repeated in the key.

> [!NOTE]
> Example of a valid file / key pair:
>
> **File:** `components/component/ComponentName.ext`
>
> **Key:** `"i18n.components.component_name.content_reference"`

Back to top.

# How It Works

## Commands

These are some example commands:

**View Help**

```bash
i18n-check -h
```

**Generate a Configuration File**

```bash
i18n-check -gcf
```

**Generate Test Frontends**

```bash
# i18n-check includes test frontends for testing the functionalities.
i18n-check -gtf
```

**Run All Checks**

```bash
i18n-check -a
```

**Run a Specific [Check](#checks)**

```bash
i18n-check -CHECK_ID
```

**Interactive Mode - Add Missing Keys**

```bash
i18n-check -mk -f -l ENTER_ISO_2_CODE
```

**Delete Unused Keys**

```bash
i18n-check -uk -d
```

**Delete Non-Source Keys**

```bash
i18n-check -nsk -d
```

> [!NOTE]
> We use `--delete` (`-d`) instead of `--fix` (`-f`) for unused and non-source keys so they're not deleted during `i18n-check --all --fix`. Delete must be passed explicitly.

## Checks

When `i18n-check` finds errors, it provides directions for resolving them. You can also disable checks in the workflow by modifying the configuration [YAML file](#yaml-file).

You can run these checks across your codebase:

| Check | Command | Resolution | Fix Command |
| -------------------------------------------------------------------------------------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Does the source file contain keys that don't follow the required formatting rules? | `key-formatting` (`kf`) | Format the keys in the source file to match the conventions. | `--fix` (`-f`) to fix all formatting issues automatically. |
| Are key names consistent with how and where they are used in the codebase? | `key-naming` (`kn`) | Rename them so i18n key usage is consistent and their scope is communicated in their name. | `--fix` (`-f`) to fix all naming issues automatically. |
| Does the codebase include i18n keys that are not within the source file? | `nonexistent-keys` (`nk`) | Check their validity and resolve if they should be added to the i18n files or replaced. | `--fix` (`-f`) to interactively add nonexistent keys. |
| Does the source file have keys that are not used in the codebase? | `unused-keys` (`uk`) | Remove them so the localization team isn't working on strings that aren't used. | `--delete` (`-d`) to delete unused keys from all JSON files automatically. |
| Do the target locale files have keys that are not in the source file? | `non-source-keys` (`nsk`) | Remove them as they won't be used in the application. | `--delete` (`-d`) to delete non-source keys from target JSON files automatically. |
| Do any of localization files have repeat keys? | `repeat-keys` (`rk`) | Separate them so that the values are not mixed when they're in production.

**Note:** The existence of repeat keys prevents keys from being sorted by the `sorted-keys` check. | n/a |
| Does the source file have repeat values that can be combined into a single key? | `repeat-values` (`rv`) | Combine them so the localization team only needs to localize one of them. | n/a |
| Are the i18n source and target locale files sorted alphabetically? | `sorted-keys` (`sk`) | Sort them alphabetically to reduce merge conflicts from the files changing. Sorting is done such that periods come before underscores (some JSON extensions do otherwise). | `--fix` (`-f`) to sort the i18n files automatically.

**Note:** The `--fix` option for other checks will sort the keys if this check is active. |
| Do the i18n files contain nested JSON structures? | `nested-files` (`nf`) | Flatten them to make replacing invalid keys easier with find-and-replace all. | `--fix` (`-f`) to flatten JSON files |
| Are any keys from the source file missing in the locale files? | `missing-keys` (`mk`) | Add the missing keys to ensure all translations are complete.
Keys with empty string values are considered missing. | `--fix --locale ENTER_ISO_2_CODE` (`-f -l ENTER_ISO_2_CODE`) to interactively add missing keys. |
| For both LTR and RTL languages, do keys that end in `_aria_label` end in punctuation? | `aria-labels` (`al`) | Remove the punctuation, as it negatively affects screen reader experience. | `--fix` (`-f`) to remove punctuation automatically. |
| For both LTR and RTL languages, are keys that end in `_alt_text` missing proper punctuation? | `alt-texts` (`at`) | Add periods to the end to comply with alt text guidelines. | `--fix` (`-f`) to add periods automatically. |

## Example Responses

These GIFs show the response to the command `i18n-check -a` when all checks pass or fail.

### All Checks Pass

![i18n_check_all_pass](https://github.com/user-attachments/assets/09783690-ff3a-47d1-affd-438b3d394dd4)

### All Checks Fail

![i18n_check_all_fail](https://github.com/user-attachments/assets/aaec959b-daf5-4269-872c-2ca8c929524a)

Back to top.

# Configuration

## YAML File

You can configure `i18n-check` using the `.i18n-check.yaml` (or `.yml`) configuration file.

For an example, see the [configuration file for this repository](/.i18n-check.yaml) that we use in testing.

The following details the potential contents of this file:

> [!NOTE]
> When `global.active` is set to `true`, all checks are enabled by default. You can then disable specific checks by setting their `active` value to `false`. This allows for more concise configuration files. Example:
>
> ```yaml
> checks:
> global:
> active: true
> missing-keys:
> active: false # disabled even though global is active
> ```

```yaml
src-dir: frontend
i18n-dir: frontend/i18n
i18n-src: frontend/i18n/en.json

file-types-to-check: [.ts, .js]

checks:
# Global configurations are applied to all checks.
global:
active: true # enables all checks by default
directories-to-skip: [frontend/node_modules]
files-to-skip: []
key-formatting:
active: true # can be used to override individual checks
keys-to-ignore: [] # regexes for ignoring keys
key-naming:
active: true
directories-to-skip: []
files-to-skip: []
keys-to-ignore: []
nonexistent-keys:
active: true
directories-to-skip: []
files-to-skip: []
search-dirs: [] # additional directories to search for key usage (e.g., test directories)
unused-keys:
active: true
directories-to-skip: []
files-to-skip: []
keys-to-ignore: []
non-source-keys:
active: true
repeat-keys:
active: true
repeat-values:
active: true
sorted-keys:
active: true
nested-files:
active: true
missing-keys:
active: true
locales-to-check: [] # iso codes, or leave empty to check all
aria-labels:
active: true
alt-texts:
active: true
```

## Arguments

In the `.i18n-check.yaml` or `.i18n-check.yml` [configuration](#configuration) file, provide these arguments:

- `src-dir`: The directory path to your source code.
- `i18n-dir`: The directory path to your i18n files.
- `i18n-src`: The name of your i18n source file.
- `file-types-to-check`: The file types to include in the check.

## Additional Arguments

You can find common additional arguments for using specific web frameworks here:

Vue.js

```yaml
file_types_to_check: [.vue]

checks:
global:
directories_to_skip: [frontend/.nuxt, frontend/.output, frontend/dist]
```

## pre-commit

This is an example of a [prek](https://prek.j178.dev/) or [pre-commit](https://github.com/pre-commit/pre-commit) hook:

```yaml
- repo: local
hooks:
- id: run-i18n-check
name: run i18n-check key-value checks
files: ^src-dir/
entry: uv run i18n-check -a
language: python
pass_filenames: false
additional_dependencies:
- i18n-check
```

## GitHub Action

This is an example YAML file for a GitHub Action to check your `i18n-files` on PRs and commits:

```yaml
name: ci_i18n_check
on:
workflow_dispatch:
pull_request:
branches:
- main
types:
- opened
- reopened
- synchronize
push:
branches:
- main

jobs:
i18n_check:
runs-on: ubuntu-latest
steps:
- name: Checkout Project
uses: actions/checkout@v6

- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: "3.12"

- name: Install uv
uses: astral-sh/setup-uv@v7

- name: Install Dependencies
run: uv sync --frozen --all-extras

- name: Execute All i18n-check Key-Value Checks
run: |
uv run i18n-check -a
```

Back to top.

# Contributing

See the [contribution guidelines](CONTRIBUTING.md) before contributing. You can help by:

- 🐞 Reporting bugs.
- ✨ Working with us on new features.
- 📝 Improving the documentation.

We track work that is in progress or may be implemented in the [issues](https://github.com/activist-org/i18n-check/issues) and [projects](https://github.com/activist-org/i18n-check/projects).

## Contact the Team

Public Matrix Chat

activist uses [Matrix](https://matrix.org/) for team communication. [Join us in our public chat rooms](https://matrix.to/#/#activist_community:matrix.org) to share ideas, ask questions, or just say hi to the team.

We recommend using the [Element](https://element.io/) client and [Element X](https://element.io/app) for a mobile app.

## Contributors

Thanks to all our amazing [contributors](https://github.com/activist-org/i18n-check/graphs/contributors)! ❤️



Back to top.