{"id":31879399,"url":"https://github.com/activist-org/i18n-check","last_synced_at":"2026-04-25T22:00:56.946Z","repository":{"id":254690884,"uuid":"847238002","full_name":"activist-org/i18n-check","owner":"activist-org","description":"Check i18n/L10n keys and values","archived":false,"fork":false,"pushed_at":"2026-04-23T20:53:04.000Z","size":7252,"stargazers_count":3,"open_issues_count":3,"forks_count":13,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-23T22:17:06.388Z","etag":null,"topics":["cd","ci","cicd","continuous-delivery","continuous-integration","github-actions","hacktoberfest","i18n","internationalization","l10n","localization","python","validation"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/activist-org.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-08-25T08:39:52.000Z","updated_at":"2026-04-23T20:53:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"4fc6c6a2-bb2f-4b45-8014-e302ca38c32f","html_url":"https://github.com/activist-org/i18n-check","commit_stats":null,"previous_names":["activist-org/i18n-check-action","activist-org/i18n-check"],"tags_count":36,"template":false,"template_full_name":null,"purl":"pkg:github/activist-org/i18n-check","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/activist-org%2Fi18n-check","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/activist-org%2Fi18n-check/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/activist-org%2Fi18n-check/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/activist-org%2Fi18n-check/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/activist-org","download_url":"https://codeload.github.com/activist-org/i18n-check/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/activist-org%2Fi18n-check/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32278249,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T18:29:39.964Z","status":"ssl_error","status_checked_at":"2026-04-25T18:29:32.149Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cd","ci","cicd","continuous-delivery","continuous-integration","github-actions","hacktoberfest","i18n","internationalization","l10n","localization","python","validation"],"created_at":"2025-10-13T00:29:01.620Z","updated_at":"2026-04-25T22:00:56.930Z","avatar_url":"https://github.com/activist-org.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca id=\"top\"\u003e\u003c/a\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://github.com/activist-org/i18n-check\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/activist-org/i18n-check/main/.github/resources/images/i18nCheckGitHubBanner.png\" width=1024 alt=\"i18n check logo\"\u003e\u003c/a\u003e\n\u003c/div\u003e\n\n[![rtd](https://img.shields.io/readthedocs/i18n-check.svg?label=%20\u0026logo=read-the-docs\u0026logoColor=ffffff)](http://i18n-check.readthedocs.io/en/latest/)\n[![ci_static_analysis](https://img.shields.io/github/actions/workflow/status/activist-org/i18n-check/ci_static_analysis.yaml?branch=main\u0026label=%20\u0026logo=ruff\u0026logoColor=ffffff)](https://github.com/activist-org/i18n-check/actions/workflows/ci_static_analysis.yaml)\n[![ci_pytest](https://img.shields.io/github/actions/workflow/status/activist-org/i18n-check/ci_pytest.yaml?branch=main\u0026label=%20\u0026logo=pytest\u0026logoColor=ffffff)](https://github.com/activist-org/i18n-check/actions/workflows/ci_pytest.yaml)\n[![issues](https://img.shields.io/github/issues/activist-org/i18n-check?label=%20\u0026logo=github)](https://github.com/activist-org/i18n-check/issues)\n[![python](https://img.shields.io/badge/Python-4B8BBE.svg?logo=python\u0026logoColor=ffffff)](https://github.com/activist-org/i18n-check/blob/main/CONTRIBUTING.md)\n[![pypi](https://img.shields.io/pypi/v/i18n-check.svg?label=%20\u0026color=4B8BBE)](https://pypi.org/project/i18n-check/)\n[![pypistatus](https://img.shields.io/pypi/status/i18n-check.svg?label=%20)](https://pypi.org/project/i18n-check/)\n[![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)\n[![coc](https://img.shields.io/badge/Contributor%20Covenant-ff69b4.svg)](https://github.com/activist-org/i18n-check/blob/main/.github/CODE_OF_CONDUCT.md)\n[![matrix](https://img.shields.io/badge/Matrix-000000.svg?logo=matrix\u0026logoColor=ffffff)](https://matrix.to/#/#activist_community:matrix.org)\n\n# Contents\n\n- [About i18n-check](#about-i18n-check)\n- [Installation](#installation)\n  - [Users](#users)\n  - [Development Build](#development-build)\n- [Key Conventions](#key-conventions)\n- [How It Works](#how-it-works)\n  - [Commands](#commands)\n  - [Checks](#checks)\n  - [Example Responses](#example-responses)\n- [Configuration](#configuration)\n  - [YAML File](#yaml-file)\n  - [Arguments](#arguments)\n  - [Additional Arguments](#additional-arguments)\n  - [pre-commit](#pre-commit)\n  - [GitHub Action](#github-action)\n- [Contributing](#contributing)\n  - [Contact the Team](#contact-the-team)\n  - [Contributors](#contributors)\n\n# About i18n-check\n\n\u003e [!IMPORTANT]\n\u003e Before you contribute, read the [contributing guide](CONTRIBUTING.md).\n\n`i18n-check` is a Python package that automates the validation of keys and values for your internationalization and localization processes.\n\nDeveloped 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.\n\n# Installation\n\n## Users\n\nYou can install `i18n-check` using [uv](https://docs.astral.sh/uv/) (recommended) or [pip](https://pypi.org/project/i18n-check/).\n\n### uv\n\n(Recommended - fast, Rust-based installer)\n\n```bash\nuv pip install i18n-check\n```\n\n### pip\n\n```bash\npip install i18n-check\n```\n\n## Development Build\n\nYou can install the latest development build using uv, pip, or by cloning the repository.\n\n### Clone the Repository (Development Build)\n\n```bash\ngit clone https://github.com/activist-org/i18n-check.git  # or ideally your fork\ncd i18n-check\n```\n\n### uv (Development Build)\n\n```bash\nuv sync --all-extras  # install all dependencies\nsource .venv/bin/activate  # activate venv (macOS/Linux)\n# .venv\\Scripts\\activate  # activate venv (Windows)\n```\n\n### pip (Development Build)\n\n```bash\npython -m venv .venv  # create virtual environment\nsource .venv/bin/activate  # activate venv (macOS/Linux)\n# .venv\\Scripts\\activate  # activate venv (Windows)\npip install -e .\n```\n\n\u003csub\u003e\u003ca href=\"#top\"\u003eBack to top.\u003c/a\u003e\u003c/sub\u003e\n\n# Key Conventions\n\n`i18n-check` enforces these conventions for all keys:\n\n- All keys must begin with `i18n.`.\n- The base path must be the file path where the key is used.\n- If a key is used in more than one file, the base path must be the lowest common directory and end with `_global`.\n- Base paths must be followed by a minimally descriptive content reference (`i18n-check` only checks content references for formatting).\n- Separate base paths with periods (`.`).\n- Separate directory / file name components and content references with underscores (`_`).\n- Repeated words in the file path, including the file name, must not be repeated in the key.\n\n\u003e [!NOTE]\n\u003e Example of a valid file / key pair:\n\u003e\n\u003e **File:** `components/component/ComponentName.ext`\n\u003e\n\u003e **Key:** `\"i18n.components.component_name.content_reference\"`\n\n\u003csub\u003e\u003ca href=\"#top\"\u003eBack to top.\u003c/a\u003e\u003c/sub\u003e\n\n# How It Works\n\n## Commands\n\nThese are some example commands:\n\n**View Help**\n\n```bash\ni18n-check -h\n```\n\n**Generate a Configuration File**\n\n```bash\ni18n-check -gcf\n```\n\n**Generate Test Frontends**\n\n```bash\n# i18n-check includes test frontends for testing the functionalities.\ni18n-check -gtf\n```\n\n**Run All Checks**\n\n```bash\ni18n-check -a\n```\n\n**Run a Specific [Check](#checks)**\n\n```bash\ni18n-check -CHECK_ID\n```\n\n**Interactive Mode - Add Missing Keys**\n\n```bash\ni18n-check -mk -f -l ENTER_ISO_2_CODE\n```\n\n**Delete Unused Keys**\n\n```bash\ni18n-check -uk -d\n```\n\n**Delete Non-Source Keys**\n\n```bash\ni18n-check -nsk -d\n```\n\n\u003e [!NOTE]\n\u003e 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.\n\n## Checks\n\nWhen `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).\n\nYou can run these checks across your codebase:\n\n| Check                                                                                        | Command                   | Resolution                                                                                                                                                                              | Fix Command                                                                                                                                              |\n| -------------------------------------------------------------------------------------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| 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.                                                                                               |\n| 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.                                                                                                   |\n| 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.                                                                                                    |\n| 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.                                                                               |\n| 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.                                                                        |\n| 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. \u003cbr\u003e \u003cbr\u003e **Note:** The existence of repeat keys prevents keys from being sorted by the `sorted-keys` check. | n/a                                                                                                                                                      |\n| 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                                                                                                                                                      |\n| 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. \u003cbr\u003e \u003cbr\u003e **Note:** The `--fix` option for other checks will sort the keys if this check is active. |\n| 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                                                                                                                     |\n| 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. \u003cbr\u003e 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.                                                          |\n| 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.                                                                                                      |\n| 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.                                                                                                             |\n\n## Example Responses\n\nThese GIFs show the response to the command `i18n-check -a` when all checks pass or fail.\n\n### All Checks Pass\n\n![i18n_check_all_pass](https://github.com/user-attachments/assets/09783690-ff3a-47d1-affd-438b3d394dd4)\n\n### All Checks Fail\n\n![i18n_check_all_fail](https://github.com/user-attachments/assets/aaec959b-daf5-4269-872c-2ca8c929524a)\n\n\n\u003csub\u003e\u003ca href=\"#top\"\u003eBack to top.\u003c/a\u003e\u003c/sub\u003e\n\n# Configuration\n\n## YAML File\n\nYou can configure `i18n-check` using the `.i18n-check.yaml` (or `.yml`) configuration file.\n\nFor an example, see the [configuration file for this repository](/.i18n-check.yaml) that we use in testing.\n\nThe following details the potential contents of this file:\n\n\u003e [!NOTE]\n\u003e 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:\n\u003e\n\u003e ```yaml\n\u003e checks:\n\u003e   global:\n\u003e     active: true\n\u003e   missing-keys:\n\u003e     active: false # disabled even though global is active\n\u003e ```\n\n```yaml\nsrc-dir: frontend\ni18n-dir: frontend/i18n\ni18n-src: frontend/i18n/en.json\n\nfile-types-to-check: [.ts, .js]\n\nchecks:\n  # Global configurations are applied to all checks.\n  global:\n    active: true # enables all checks by default\n    directories-to-skip: [frontend/node_modules]\n    files-to-skip: []\n  key-formatting:\n    active: true # can be used to override individual checks\n    keys-to-ignore: [] # regexes for ignoring keys\n  key-naming:\n    active: true\n    directories-to-skip: []\n    files-to-skip: []\n    keys-to-ignore: []\n  nonexistent-keys:\n    active: true\n    directories-to-skip: []\n    files-to-skip: []\n    search-dirs: [] # additional directories to search for key usage (e.g., test directories)\n  unused-keys:\n    active: true\n    directories-to-skip: []\n    files-to-skip: []\n    keys-to-ignore: []\n  non-source-keys:\n    active: true\n  repeat-keys:\n    active: true\n  repeat-values:\n    active: true\n  sorted-keys:\n    active: true\n  nested-files:\n    active: true\n  missing-keys:\n    active: true\n    locales-to-check: [] # iso codes, or leave empty to check all\n  aria-labels:\n    active: true\n  alt-texts:\n    active: true\n```\n\n## Arguments\n\nIn the `.i18n-check.yaml` or `.i18n-check.yml` [configuration](#configuration) file, provide these arguments:\n\n- `src-dir`: The directory path to your source code.\n- `i18n-dir`: The directory path to your i18n files.\n- `i18n-src`: The name of your i18n source file.\n- `file-types-to-check`: The file types to include in the check.\n\n## Additional Arguments\n\nYou can find common additional arguments for using specific web frameworks here:\n\n\u003cdetails\u003e\u003csummary\u003eVue.js\u003c/summary\u003e\n\u003cp\u003e\n\n```yaml\nfile_types_to_check: [.vue]\n\nchecks:\n  global:\n    directories_to_skip: [frontend/.nuxt, frontend/.output, frontend/dist]\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n## pre-commit\n\nThis is an example of a [prek](https://prek.j178.dev/) or [pre-commit](https://github.com/pre-commit/pre-commit) hook:\n\n```yaml\n- repo: local\n  hooks:\n    - id: run-i18n-check\n      name: run i18n-check key-value checks\n      files: ^src-dir/\n      entry: uv run i18n-check -a\n      language: python\n      pass_filenames: false\n      additional_dependencies:\n        - i18n-check\n```\n\n## GitHub Action\n\nThis is an example YAML file for a GitHub Action to check your `i18n-files` on PRs and commits:\n\n```yaml\nname: ci_i18n_check\non:\n  workflow_dispatch:\n  pull_request:\n    branches:\n      - main\n    types:\n      - opened\n      - reopened\n      - synchronize\n  push:\n    branches:\n      - main\n\njobs:\n  i18n_check:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout Project\n        uses: actions/checkout@v6\n\n      - name: Setup Python\n        uses: actions/setup-python@v6\n        with:\n          python-version: \"3.12\"\n\n      - name: Install uv\n        uses: astral-sh/setup-uv@v7\n\n      - name: Install Dependencies\n        run: uv sync --frozen --all-extras\n\n      - name: Execute All i18n-check Key-Value Checks\n        run: |\n          uv run i18n-check -a\n```\n\n\u003csub\u003e\u003ca href=\"#top\"\u003eBack to top.\u003c/a\u003e\u003c/sub\u003e\n\n# Contributing\n\nSee the [contribution guidelines](CONTRIBUTING.md) before contributing. You can help by:\n\n- 🐞 Reporting bugs.\n- ✨ Working with us on new features.\n- 📝 Improving the documentation.\n\nWe 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).\n\n## Contact the Team\n\n\u003ca href=\"https://matrix.to/#/#activist_community:matrix.org\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/activist-org/Organization/main/resources/images/logos/MatrixLogoGrey.png\" width=\"175\" alt=\"Public Matrix Chat\" align=\"right\"\u003e\u003c/a\u003e\n\nactivist 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.\n\nWe recommend using the [Element](https://element.io/) client and [Element X](https://element.io/app) for a mobile app.\n\n## Contributors\n\nThanks to all our amazing [contributors](https://github.com/activist-org/i18n-check/graphs/contributors)! ❤️\n\n\u003ca href=\"https://github.com/activist-org/i18n-check/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=activist-org/i18n-check\" /\u003e\n\u003c/a\u003e\n\n\u003csub\u003e\u003ca href=\"#top\"\u003eBack to top.\u003c/a\u003e\u003c/sub\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Factivist-org%2Fi18n-check","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Factivist-org%2Fi18n-check","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Factivist-org%2Fi18n-check/lists"}