8 rules for Lingui best practices — from catching unlocalized strings to enforcing consistent plurals. TypeScript's type system eliminates false positives, no endless whitelists needed.
// ✅ Automatically ignored — TypeScript knows these
document.createElement("div")
element.addEventListener("click", handler)
fetch(url, { mode: "cors" })
type Status = "idle" | "loading" | "error"
const status: Status = "loading" // ✅ ignored
// ❌ Reported — actual user text
const message = "Welcome to our app" // 🚨
<button>Save changes</button> // 🚨
TypeScript's type system + intelligent heuristics handle the heavy lifting. Focus on your app, not your linter config.
"idle" | "loading" | "error" automatically detected as technical strings.
Event names, element types, Intl options — all recognized via TypeScript definitions.
className, backgroundColor, Tailwind classes — auto-ignored.
Prices, dates, times like "€99.99" or "12:30" are not user text.
Mark custom loggers, analytics, storage keys as unlocalized with unlocalized().
Verifies t, Trans come from @lingui/* — no false positives.
For loggers, analytics, or any strings that shouldn't be translated — use branded types for type-safe ignore patterns.
UnlocalizedFunction<T> — wrap entire interfaces
unlocalized() — helper for automatic type inference
UnlocalizedEvent, UnlocalizedKey — specific use cases
import { unlocalized } from "eslint-plugin-lingui-typescript/types"
function createLogger(prefix = "[App]") {
return unlocalized({
info: (...args) => console.info(prefix, ...args),
error: (...args) => console.error(prefix, ...args),
})
}
const logger = createLogger()
logger.info("Server started") // ✅ ignored
logger.error("Connection failed") // ✅ ignored
Traditional i18n linters rely on heuristics and manual whitelists. This plugin leverages TypeScript to do the work for you.
| Feature | Traditional | This Plugin |
|---|---|---|
| String literal unions | Manual whitelist | ✓ Auto-detected |
| DOM API strings | Manual whitelist | ✓ Auto-detected |
| Intl method arguments | Manual whitelist | ✓ Auto-detected |
| Styling props & constants | Manual whitelist | ✓ Auto-detected |
| Numeric/symbolic strings | Manual whitelist | ✓ Auto-detected |
| Custom ignore patterns | Config arrays | ✓ Branded types |
| Lingui macro verification | Name-based only | ✓ Package origin |
Comprehensive coverage for Lingui best practices, from unlocalized strings to macro usage.
Detect user-visible strings not wrapped in Lingui macros
Require context text around variables in messages
Prevent nesting Lingui macros inside each other
Restrict expressions to simple identifiers only
Ensure t macro calls are inside functions
Require text around single JSX elements in Trans
Enforce consistent plural value format
Enforce project-specific text patterns
Get up and running in under a minute.
npm install --save-dev eslint-plugin-lingui-typescript
// eslint.config.ts
import eslint from "@eslint/js"
import tseslint from "typescript-eslint"
import linguiPlugin from "eslint-plugin-lingui-typescript"
export default [
eslint.configs.recommended,
...tseslint.configs.strictTypeChecked,
linguiPlugin.configs["flat/recommended"],
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname
}
}
}
]
npx eslint .