Задайте питання та отримайте підсумок документа, вказавши цю сторінку та обраного вами постачальника штучного інтелекту
Історія версій
- "Початкова історія"v9.3.112.08.2026
Вміст цієї сторінки перекладено за допомогою штучного інтелекту.
Переглянути останню версію оригінального вмісту англійськоюIf you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.
GitHub link to the documentationCopy doc Markdown to clipboard
Плагін ESLint x OXLint
eslint-plugin-intlayer виявляє ті типи помилок i18n, які TypeScript не здатний помітити:
- Жорстко закодований текст, який так і не потрапив до словника.
- Динамічні виклики, які проходять перевірку типів і виконуються, але які компілятор Intlayer не може оптимізувати.
- Мертвий вміст (Dead content) — словники та поля, які ніде в проєкті не зчитуються (за бажанням/opt-in).
Невідомі ключі словників, невідомі шляхи до полів та відсутні локалі вже є помилками компіляції, тому плагін не дублює їх повідомлення.
Встановлення
Скопіюйте код у буфер обміну
npm install --save-dev eslint-plugin-intlayerПотрібен ESLint 9 або новішої версії (flat config). ESLint 10 підтримується.
Використання
Плагін працює як в ESLint, так і в oxlint — однакові правила, однакові параметри.
Або розгорніть конфігурацію та задайте рівні самостійно:
Конфігурації (Configs)
Відкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
| Конфігурація | no-raw-text | static-dictionary-key | no-dynamic-field-access | enforce-adapter-import | no-unused-content |
|---|---|---|---|---|---|
recommended | warn | error | error | off | off |
strict | error (+ рядкові літерали поза JSX) | error | error | error | off |
contract-only | off | error | error | off | off |
recommended навмисно залишає no-raw-text зі статусом warn: застосування правила до наявної кодової бази виявить усі неперекладені рядки одночасно, що не повинно ламати збірку з першого ж дня.
enforce-adapter-import типово вимкнено — увімкніть його явно, якщо це необхідно.
no-unused-content вимкнено в усіх пресетах, включно зі strict. Це єдине правило, яке зчитує конфігурацію Intlayer і сканує вихідні файли з диска, тому його ввімкнення має бути свідомим вибором.
Правила
no-raw-text
Повідомляє про текст для користувача, який не оголошено у словнику. Використовує ту саму логіку виявлення, що й intlayer extract, тому назви брендів, класи CSS та технічні ідентифікатори ігноруються.
Скопіюйте код у буфер обміну
// ✗ Повідомлено<h1>Welcome to our documentation</h1><input placeholder="Enter your email address" />// ✓ Усе добреconst { title } = useIntlayer("home");<h1>{title}</h1>Файли оголошення вмісту (*.content.ts, …) пропускаються.
Щоб виправити весь файл одночасно, виконайте npx intlayer extract, і компілятор автоматично перенесе рядки до словника.
Параметри
static-dictionary-key
Вимагає, щоб ключ словника був рядковим літералом.
Компілятор може попередньо завантажити словник лише тоді, коли може прочитати ключ безпосередньо в місці виклику. У разі використання обчислюваного ключа оптимізація мовчки пропускається, і замість цього в бандл включаються всі словники.
Скопіюйте код у буфер обміну
// ✗ ПовідомленоuseIntlayer(dictionaryKey);useIntlayer(`home-${suffix}`);getTranslations({ namespace: page });// ✗ Змінна все одно не є літераломconst key = "home";useIntlayer(key);// ✓ Усе добреuseIntlayer("home");getTranslations({ namespace: "home" });Це стосується useIntlayer, getIntlayer та всіх адаптерів сумісності (useTranslation, useTranslations, formatMessage, <FormattedMessage id>, <Trans i18nKey>, …).
no-dynamic-field-access
Вимагає, щоб поле, яке зчитується зі словника, було статично відомим.
Компілятор видаляє поля, використання яких він не виявив. Динамічний доступ для нього невидимий, тому читання може повернути undefined під час виконання.
Скопіюйте код у буфер обміну
// ✗ Повідомленоconst content = useIntlayer("home");content[fieldName];const t = useTranslations("home");t(messageKey);// ✓ Усе добреcontent.title;content["title"];content.items[0];t("hero.title");enforce-adapter-import
Віддає перевагу адаптеру сумісності @intlayer/* перед оригінальним пакетом. Оригінальний пакет переходить в Intlayer лише за наявності налаштованого псевдоніма бандлера; адаптер працює завжди. Підтримує автовиправлення через --fix.
Скопіюйте код у буфер обміну
// ✗ Повідомленоimport { useTranslation } from "react-i18next";import { getTranslations } from "next-intl/server";// ✓ Усе добреimport { useTranslation } from "@intlayer/react-i18next";import { getTranslations } from "@intlayer/next-intl/server";no-unused-content
Типово вимкнено. Повідомляє про вміст, який ніде в проєкті не зчитується, а також про ключі словників, оголошені в кількох місцях.
Скопіюйте код у буфер обміну
export default { key: "home", // ✗ Повідомляється, якщо жоден виклик у проєкті не запитує "home" content: { title: t({ uk: "Заголовок", en: "Title" }), // ✗ Повідомляється, якщо ніщо не зчитує `hero` hero: { subtitle: t({ uk: "Підзаголовок", en: "Subtitle" }), }, },};На відміну від інших правил, це правило не може вирішити лише за поточним файлом — поле є невикористаним лише відносно всього проєкту. Під час першого оголошення вмісту під час лінтингу воно завантажує конфігурацію Intlayer, сканує вихідні файли за шляхами з конфігурації (build.traversePattern, compiler.transformPattern) і запускає той самий аналізатор використання, який живить @intlayer/lsp та закреслення «невикористаного» в розширенні VS Code. Результат кешується на cacheTtl мілісекунд, тому сканування відбувається один раз за запуск, а не для кожного файлу.
Параметри
Зменште cacheTtl, якщо ви запускаєте лінтинг із довгоживучого сервера редактора і хочете швидше бачити зміни; встановіть baseDir, коли один запуск лінтингу охоплює кілька проєктів Intlayer у монорепозиторії.
Схильне до мінімізації помилкових спрацьовувань. Хибне спрацьовування тут призведе до видалення потрібного перекладу, тому нічого не повідомляється, якщо словник використовується способом, який аналіз не може відстежити: об'єкт вмісту передано повністю, прив'язана функція перекладача (const t = useTranslations("home")), оголошення отримано через прямий імпорт (useDictionary(myDictionary)), викликnest()з іншого словника або список полів, який став невичерпним через оператор spread. Однофайлові компоненти (.vue,.svelte,.astro) вважаються такими, що використовують кожне поле згаданих словників, оскільки їхні блоки скриптів тут не парсяться.
reportDuplicateKeys зчитує необ'єднані словники, які збірка записує у .intlayer/, тому воно залишається неактивним, доки проєкт не буде зібрано принаймні один раз. Два оголошення з однаковим ключем об'єднуються, що є коректним шаблоном — звіт формується тому, що поле, визначене з обох боків, непомітно зберігає лише одне з двох значень.
Аналізатор завантажується з @intlayer/lsp, який постачається як ESM. Тому правилу потрібна версія Node, здатна виконувати require() для ES-модулів — Node 20.19+ або 22.12+. На старіших версіях воно нічого не повідомляє, щоб не зупиняти процес лінтингу.
Фреймворки
Кожне правило працює в усіх інтеграціях Intlayer, включно з шаблонами Vue, Svelte та Angular. Потрібно лише вказати ESLint, який парсер зчитує кожен тип файлів.
Відкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
| Фреймворк | Файли | Парсер |
|---|---|---|
| React, Preact, Solid, Lit | .jsx .tsx | typescript-eslint |
| Next.js | .jsx .tsx | typescript-eslint |
| Vue, Nuxt | .vue | vue-eslint-parser |
| Svelte, SvelteKit | .svelte | svelte-eslint-parser |
| Angular | .ts | typescript-eslint |
| Шаблони Angular | .component.html | @angular-eslint/template-parser |
| Astro | .astro | astro-eslint-parser |
Встановлюйте лише ті парсери, які потрібні вашому проєкту.
Відоме обмеження. У шаблонах Vue та Angular вираз на кшталт{{ content[key] }}не перевіряється правиломno-dynamic-field-access. Динамічні звернення всередині блоку script виявляються у звичайному режимі.