1.1.1 • Published 2 months ago

@spaced-out/eslint-plugin-i18n v1.1.1

Weekly downloads
-
License
ISC
Repository
github
Last release
2 months ago

eslint-plugin-i18n

ESLint Rules for Translation and Internationalization:

This repository introduces two ESLint rules designed to enforce best practices for internationalization (i18n) in your codebase. These rules ensure that static labels are replaced with translation functions and that all translation keys are defined in the corresponding en.json(source of truth).

Rules overview

1. no-static-labels

Description:

This rule identifies and prevents the use of static labels (hardcoded strings) in JSX code. It enforces wrapping all static labels with a translation function (e.g., t('key', 'defaultValue')).

Key Features:

  • Detects static strings in JSX elements, attributes, and variables.
  • Identifies template literals, binary expressions, logical expressions, and conditional expressions containing static strings.
  • Supports dynamic attribute checks, including menu, options, tooltip, and more.
  • Auto-fix functionality to wrap detected static labels in a translation function.

Why Use It?

Ensures that all user-facing text is localized, improving the scalability and maintainability of your application for internationalization.

2. missing-translation

Description:

This rule checks if the translation keys used in your t function are present in your source translation JSON file (e.g., en.json,). It warns developers about missing keys, ensuring translation files remain consistent with the codebase.

Key Features:

  • Verifies translation keys passed to the t function.
  • Supports t as a standalone function and as a method (e.g., this.t()).
  • Helps maintain completeness of translation files.
  • Warns developers if keys are missing from the source of truth JSON file (en.json).

Why Use It?

Ensures all user-facing text is properly localized and prevents runtime issues due to missing translations.

3. invalid-translation-key-format

Description:

This rule enforces a strict naming convention for translation keys used in the t('key', 'defaultValue') function to ensure consistency and predictability across translation files.

Convention Rules:

  • All spaces in the fallback value must be replaced by underscores (_) in the key.
  • The key must preserve the exact casing of the fallback string (no forced lowercase).
  • No special characters allowed in the key, except a single apostrophe (').

4. no-react-i18next-import

Description:

This rule disallows the use of the useTranslation hook from react-i18next in your codebase. It enforces a centralized approach to translation using the t('key', 'fallback') pattern, instead of dynamically obtaining t via hooks. (rule specifically for sense repo)

Key Features:

  • Detects imports of useTranslation from react-i18next.
  • Reports any invocation of useTranslation() in the code.

Installation

1. Install ESLint and the plugin:

npm install @spaced-out/eslint-plugin-i18n --save-dev

2. Add the rules to your .eslintrc.js configuration:

module.exports = {
  extends: [
    // other configurations...
  ],
  plugins: ['@spaced-out'],
  rules: {
    '@spaced-out/no-static-labels': 'error',
    '@spaced-out/missing-translation': 'warn',
    '@spaced-out/invalid-translation-key': 'error',
    '@spaced-out/no-react-i18next-import': 'error',
  },
};

3. Configure your translation files:

Place your translation files (e.g., en.json, fr.json) in the translations folder inside your i18n directory. The rules will automatically pick up these files to validate translation keys.

How It Works

Rule: no-static-labels

The rule inspects your code for hardcoded static strings. For example:

Input:

<div>Hello, World!</div>
const message = "Welcome!";
<h1>{message}</h1>

Output: The rule suggests wrapping the strings in a translation function:

<div>{t('Hello_World', 'Hello, World!')}</div>
const message = t('Welcome', 'Welcome!');
<h1>{message}</h1>

Supported Contexts:

  • JSX Text (<div>Static Text</div>)
  • JSX Attributes (<button label="Click me" />)
  • JavaScript Variables (const label = "Static text";)
  • Template Literals, Binary Expressions, Logical Expressions, Conditional Expressions, and Object Properties.

Rule: missing-translation

The rule checks translation keys used in the t function. If a key is missing in the JSON files, a warning is displayed:

Input:

const message = t('NonExistentKey', 'Default Message');

Warning Message:

Translation key "NonExistentKey" is missing in the config translations JSON file.

Supported Function Usages:

  • t('key', 'defaultValue')

Rule: invalid-translation-key-format

This rule checks that the key passed to t() matches the fallback string (with underscores for spaces, identical casing, and only apostrophes allowed as special characters).

Input:

t('youre cute', "You're cute");

Output: The rule suggests fixing the key of wrapped translation function:

Translation key "youre_cute" is invalid. It should be "You're_cute".

Supported Contexts:

  • JSX Text (<div>Static Text</div>)
  • JSX Attributes (<button label="Click me" />)
  • JavaScript Variables (const label = "Static text";)
  • Template Literals, Binary Expressions, Logical Expressions, Conditional Expressions, and Object Properties.

Fix Suggestions and Workflow

Auto-Fix for no-static-labels

  • The no-static-labels rule supports auto-fix functionality. Run ESLint with the --fix flag to automatically wrap static labels in the t function.
    npx eslint . --fix

Handling Missing Translations

  1. Run the linter to identify missing keys:
    npx eslint .
  2. Use a script to generate the missing keys in your translation files. For example:
    yarn generate-translations
    This script should:
  • Parse all translation keys from the codebase.
  • Compare the keys with existing translation JSON files.
  • Append missing keys with default values.
1.1.1

2 months ago

1.1.0

2 months ago

1.0.9

4 months ago

1.0.8

6 months ago

1.0.7

7 months ago

1.0.6

7 months ago

1.0.5

7 months ago

1.0.4

8 months ago

1.0.3

8 months ago

1.0.2

8 months ago

1.0.1

8 months ago

1.0.0

8 months ago