dr-ui
Localization

ESLint Rules

ESLint configuration and rules for i18n development

ESLint Rules for i18n

To ensure consistent and error-free internationalization development, you can configure ESLint rules that help catch common i18n issues.

Installation

Install the necessary ESLint plugins:

npm install --save-dev eslint-plugin-i18next
# or
yarn add --dev eslint-plugin-i18next
# or
pnpm add --dev eslint-plugin-i18next

Configuration

Add the following to your ESLint configuration file (.eslintrc.js, .eslintrc.json, or eslint.config.mjs):

module.exports = {
  // ... other config
  plugins: ["i18next"],
  rules: {
    "i18next/no-literal-string": "error",
    "i18next/no-unused-key": "warning",
    "i18next/no-raw-text": "error",
    "no-restricted-imports": [
      "error",
      {
        paths: [
          {
            name: "react-i18next",
            importNames: ["useTranslation"],
            message:
              "Import useTranslation from @/i18n instead of react-i18next directly",
          },
          {
            name: "i18next",
            message: "Import i18n from @/i18n instead of i18next directly",
          },
        ],
      },
    ],
  },
  overrides: [
    {
      files: ["**/*.test.{js,jsx,ts,tsx}", "**/*.spec.{js,jsx,ts,tsx}"],
      rules: {
        "i18next/no-literal-string": "off",
      },
    },
  ],
};

Available Rules

i18next/no-literal-string

Prevents hardcoded strings that should be translated:

// ❌ Bad
<h1>Welcome to our app</h1>

// ✅ Good
<h1>{t('Welcome to our app')}</h1>

i18next/no-missing-key

Ensures all translation keys exist in locale files:

// ❌ Bad - key doesn't exist in locale files
{
  t("NonExistentKey");
}

// ✅ Good - key exists in locale files
{
  t("Welcome");
}

i18next/no-unused-key

Warns about unused translation keys in locale files:

// ❌ Bad - unused key
{
  "Welcome": "Welcome",
  "UnusedKey": "This key is never used"
}

i18next/no-raw-text

Prevents raw text in JSX that should be translated:

// ❌ Bad
<button>Click me</button>

// ✅ Good
<button>{t('Click me')}</button>

no-restricted-imports

Restricts useTranslation imports to only allow imports from the designated path:

// ❌ Bad - importing from other libraries
import { useTranslation } from "react-i18next";
import { useTranslation } from "i18next";

// ✅ Good - only allowed import path
import { useTranslation } from "@/lib/i18n";

Integration with TypeScript

For TypeScript projects, you can enhance type safety:

// types/i18n.d.ts
declare module 'i18next' {
  interface CustomTypeOptions {
    returnNull: false;
  }
}

// This ensures t() always returns a string
const translation: string = t('Welcome');

Best Practices

  1. Enable rules gradually: Start with basic rules and add more as your team adapts
  2. Configure exceptions: Use rule options to handle edge cases
  3. Test files: Disable rules in test files where hardcoded strings are acceptable
  4. CI/CD: Include ESLint checks in your CI pipeline
  5. Team training: Ensure all developers understand the i18n rules and their purpose

On this page