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-i18nextConfiguration
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
- Enable rules gradually: Start with basic rules and add more as your team adapts
- Configure exceptions: Use rule options to handle edge cases
- Test files: Disable rules in test files where hardcoded strings are acceptable
- CI/CD: Include ESLint checks in your CI pipeline
- Team training: Ensure all developers understand the i18n rules and their purpose