--- createdAt: 2026-08-12 updatedAt: 2026-08-13 title: ESLint Eklentisi | Intlayer için Lint Kuralları description: eslint-plugin-intlayer ile sabit kodlanmış metinleri, Intlayer derleyicisinin optimize edemediği dinamik çağrıları ve kullanılmayan sözlük içeriğini yakalayın. React, Vue, Svelte, Angular ve Astro genelinde ESLint ve oxlint ile çalışır. keywords: - Intlayer - ESLint - oxlint - Linting - i18n - Uluslararasılaştırma - no-raw-text - Sabit kodlanmış metinler - Kullanılmayan çeviriler - Ölü içerik - React - Vue - Svelte - Angular slugs: - doc - eslint history: - version: 9.3.1 date: 2026-08-12 changes: "Başlangıç geçmişi" author: aymericzip --- # ESLint x OXLint Eklentisi `eslint-plugin-intlayer`, TypeScript'in yakalayamadığı i18n hatalarını tespit eder: 1. Bir sözlüğe hiç eklenmemiş **sabit kodlanmış metinler (hardcoded text)**. 2. Tip kontrolünden geçen ve çalışan ancak Intlayer derleyicisinin optimize edemediği **dinamik çağrılar**. 3. **Ölü içerik (Dead content)** — projedeki hiçbir yerin okumadığı sözlükler ve alanlar (isteğe bağlı). Bilinmeyen sözlük anahtarları, bilinmeyen alan yolları ve eksik yerel ayarlar zaten derleme hataları olduğundan, eklenti bunları tekrar bildirmez. ## Kurulum ```bash packageManager="npm" npm install --save-dev eslint-plugin-intlayer ``` ```bash packageManager="pnpm" pnpm add --save-dev eslint-plugin-intlayer ``` ```bash packageManager="yarn" yarn add --dev eslint-plugin-intlayer ``` ESLint 9 veya üzerini gerektirir (flat config). ESLint 10 desteklenir. ## Kullanım Eklenti hem ESLint hem de [oxlint](https://oxc.rs) üzerinde aynı kurallar ve aynı seçeneklerle çalışır. ```javascript fileName="eslint.config.mjs" codeFormat="esm" import intlayer from "eslint-plugin-intlayer"; export default [...intlayer.configs.recommended]; ``` Veya bir yapılandırmayı yayın ve önem düzeylerini kendiniz belirleyin: ```javascript fileName="eslint.config.mjs" codeFormat="esm" import intlayer from "eslint-plugin-intlayer"; export default [ ...intlayer.configs.recommended, { rules: { "intlayer/no-raw-text": "warn", "intlayer/static-dictionary-key": "error", "intlayer/no-dynamic-field-access": "error", "intlayer/enforce-adapter-import": "warn", "intlayer/no-unused-content": "warn", }, }, ]; ``` ```json fileName=".oxlintrc.json" { "jsPlugins": ["eslint-plugin-intlayer"], "rules": { "intlayer/no-raw-text": "warn", "intlayer/static-dictionary-key": "error", "intlayer/no-dynamic-field-access": "error", "intlayer/enforce-adapter-import": "warn" } } ``` İki uyarı: oxlint'in JS eklenti desteği henüz alfa aşamasındadır ve oxlint özel ayrıştırıcıları (custom parsers) desteklemez — bu nedenle `.vue`, `.svelte`, `.astro` ve Angular şablonları orada denetlenmez. JS/TS/JSX dosyalarınız için oxlint'i çalıştırın ve geri kalanı için ESLint'i kullanın. `no-unused-content` yukarıda kasıtlı olarak hariç tutulmuştur: kural bağlamından çalışma dizinine ve denetlenen dosya yoluna ihtiyaç duyar; alfa JS eklenti köprüsü bunu garanti etmez. ESLint altında çalıştırın. ### Yapılandırmalar (Configs) | Yapılandırma | `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 dışı dizeler) | error | error | error | off | | `contract-only` | off | error | error | off | off | `recommended`, `no-raw-text` kuralını kasıtlı olarak `warn` seviyesinde tutar: bunu mevcut bir kod tabanına yöneltmek tüm çevrilmemiş dizeleri aynı anda ortaya çıkarır ve bu durum derlemenizi ilk günden bozmamalıdır. `enforce-adapter-import` varsayılan olarak kapalıdır — istiyorsanız açıkça etkinleştirin. `no-unused-content`, `strict` dahil tüm yapılandırmalarda kapalıdır. Intlayer yapılandırmanızı okuyan ve kaynak dosyalarınızı diskten tarayan tek kuraldır; bu nedenle açılması, bir ön ayarın sizin yerinize yapmasından ziyade bilinçli bir seçim olmalıdır. ## Kurallar ### `no-raw-text` Bir sözlükte bildirilmemiş kullanıcıya yönelik metinleri bildirir. `intlayer extract` ile aynı algılamayı kullanır; bu nedenle marka adları, CSS sınıfları ve teknik tanımlayıcılar yoksayılır. ```jsx // ✗ Bildirildi

Welcome to our documentation

// ✓ Sorunsuz const { title } = useIntlayer("home");

{title}

``` İçerik bildirim dosyaları (`*.content.ts`, …) atlanır. Tüm bir dosyayı tek seferde düzeltmek için `npx intlayer extract` komutunu çalıştırın ve derleyicinin dizeleri sizin için bir sözlüğe taşımasına izin verin. **Seçenekler** ```javascript fileName="eslint.config.mjs" codeFormat="esm" { "intlayer/no-raw-text": [ "warn", { // Değeri kullanıcıya yönelik metin olan öznitelikler. // Varsayılan: title, placeholder, alt, aria-label, label attributes: ["title", "placeholder", "alt", "aria-label", "label"], // İçeriği asla kullanıcıya yönelik metin olmayan öğeler. // Varsayılan: code, pre, script, style ignoreElements: ["code", "pre", "script", "style"], // Asla bildirilmeyecek metinler için düzenli ifadeler. ignorePatterns: ["^Powered by"], // Biçimlendirme dışındaki dize sabitlerini de bildirin. Varsayılan: false includeStringLiterals: false, }, ], } ``` ### `static-dictionary-key` Sözlük anahtarının bir dize sabiti olmasını gerektirir. Derleyici, bir sözlüğü yalnızca çağrı noktasında anahtarı doğrudan okuyabildiğinde önceden yükleyebilir. Hesaplanmış bir anahtarla optimizasyonu sessizce atlar ve bunun yerine her sözlüğü paketler. ```typescript // ✗ Bildirildi useIntlayer(dictionaryKey); useIntlayer(`home-${suffix}`); getTranslations({ namespace: page }); // ✗ Değişken hala bir dize sabiti değildir const key = "home"; useIntlayer(key); // ✓ Sorunsuz useIntlayer("home"); getTranslations({ namespace: "home" }); ``` Bu durum `useIntlayer`, `getIntlayer` ve tüm uyumluluk bağdaştırıcıları (`useTranslation`, `useTranslations`, `formatMessage`, ``, ``, …) için geçerlidir. ### `no-dynamic-field-access` Bir sözlükten okuduğunuz alanın statik olarak bilinmesini gerektirir. Derleyici, kullanıldığını görmediği alanları kaldırır. Hesaplanmış bir erişim onun için görünmezdir, bu nedenle okuma işlemi çalışma zamanında `undefined` döndürebilir. ```typescript // ✗ Bildirildi const content = useIntlayer("home"); content[fieldName]; const t = useTranslations("home"); t(messageKey); // ✓ Sorunsuz content.title; content["title"]; content.items[0]; t("hero.title"); ``` ### `enforce-adapter-import` Orijinal paket yerine `@intlayer/*` uyumluluk bağdaştırıcısını tercih eder. Orijinal paket yalnızca paketleyici takma adı yapılandırıldığında Intlayer'a çözümlenir; bağdaştırıcı her zaman çözümlenir. `--fix` ile otomatik düzeltilebilir. ```typescript // ✗ Bildirildi import { useTranslation } from "react-i18next"; import { getTranslations } from "next-intl/server"; // ✓ Sorunsuz import { useTranslation } from "@intlayer/react-i18next"; import { getTranslations } from "@intlayer/next-intl/server"; ``` ### `no-unused-content` **Varsayılan olarak kapalıdır.** Projenizdeki hiçbir yerin okumadığı içeriği ve birden fazla yerde bildirilen sözlük anahtarlarını bildirir. ```typescript fileName="src/home.content.ts" export default { key: "home", // ✗ Projede hiçbir çağıran "home" istemediğinde bildirilir content: { title: t({ tr: "Başlık", en: "Title" }), // ✗ `hero` alanını hiçbir şey okumadığında bildirilir hero: { subtitle: t({ tr: "Alt Başlık", en: "Subtitle" }), }, }, }; ``` Diğer kuralların aksine, bu kural yalnızca önündeki dosyadan karar veremez — bir alan yalnızca tüm projeye göre kullanılmamış sayılır. Bir lint çalıştırmasının ilk içerik bildiriminde Intlayer yapılandırmanızı yükler, bu yapılandırmanın bildirdiği kaynak dosyaları (`build.traversePattern`, `compiler.transformPattern`) tarar ve `@intlayer/lsp` ile VS Code uzantısındaki "kullanılmayan" üstü çizili metni destekleyen aynı kullanım çözümleyicisini çalıştırır. Sonuç `cacheTtl` milisaniye boyunca önbelleğe alınır, böylece tarama dosya başına değil çalıştırma başına bir kez gerçekleşir. **Seçenekler** ```javascript fileName="eslint.config.mjs" codeFormat="esm" { "intlayer/no-unused-content": [ "warn", { // Hiçbir şeyin başvurmadığı sözlük anahtarlarını bildirin. Varsayılan: true reportUnusedDictionaries: true, // Hiçbir şeyin okumadığı içerik alanlarını bildirin. Varsayılan: true reportUnusedFields: true, // Birden fazla yerde bildirilen anahtarları bildirin. Varsayılan: true reportDuplicateKeys: true, // Asla bildirilmeyecek alan yolları için düzenli ifadeler. ignoreFields: ["^meta"], // Taramanın başlayacağı proje kökü. Varsayılan: ESLint çalışma dizini baseDir: process.cwd(), // Bir proje taramasının yeniden kullanılma süresi (ms). Varsayılan: 30000 cacheTtl: 30000, }, ], } ``` Uzun süre çalışan bir düzenleyici sunucusundan lint işlemi yaparken ve düzenlemelerinizin daha erken yansımasını istediğinizde `cacheTtl` değerini düşürün; tek bir lint çalıştırması bir monorepodaki birkaç Intlayer projesini kapsadığında `baseDir` değerini ayarlayın. > **Sessiz kalmaya meyillidir.** Buradaki yanlış bir pozitif sonuç bir çeviriyi silebilir; bu nedenle sözlük analizin izleyemeyeceği bir şekilde kullanıldığında hiçbir şey bildirilmez: içerik nesnesinin bir bütün olarak aktarılması, ondan bağlanan bir çevirici işlevi (`const t = useTranslations("home")`), doğrudan içe aktarma yoluyla ulaşılan bir bildirim (`useDictionary(myDictionary)`), başka bir sözlükten bir `nest()` veya bir yayma (spread) operatörü ile kapsamlı olmaktan çıkarılan bir alan listesi. Tek dosyalı bileşenler (`.vue`, `.svelte`, `.astro`), komut dosyası blokları burada ayrıştırılmadığı için bahsettikleri sözlüklerin her alanını kullanıyor sayılır. `reportDuplicateKeys`, derlemenin `.intlayer/` altına yazdığı birleştirilmemiş sözlükleri okur, bu nedenle proje en az bir kez derlenene kadar sessiz kalır. Bir anahtarı paylaşan iki bildirim birleştirilir ve bu meşru bir kalıptır — bu raporlama mekanizması, her iki tarafta tanımlanan bir alanın sessizce iki değerden yalnızca birini koruması nedeniyle mevcuttur. Çözümleyici, ESM olarak dağıtılan `@intlayer/lsp` paketinden yüklenir. Bu nedenle kural, bir ES modülünü `require()` edebilen bir Node sürümüne ihtiyaç duyar — Node 20.19+ veya 22.12+. Daha eski sürümlerde lint çalıştırmasını başarısız kılmak yerine hiçbir şey bildirmez. ## Çerçeveler (Frameworks) Her kural, Vue, Svelte ve Angular şablonları dahil olmak üzere tüm Intlayer entegrasyonlarında çalışır. ESLint'e yalnızca her dosya türünü hangi ayrıştırıcının okuyacağını belirtmeniz gerekir. | Çerçeve | Dosyalar | Ayrıştırıcı (Parser) | | ------------------------- | ----------------- | --------------------------------- | | 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 Şablonları | `.component.html` | `@angular-eslint/template-parser` | | Astro | `.astro` | `astro-eslint-parser` | ```javascript fileName="eslint.config.mjs" codeFormat="esm" import intlayer from "eslint-plugin-intlayer"; import tseslint from "typescript-eslint"; import vueParser from "vue-eslint-parser"; import svelteParser from "svelte-eslint-parser"; import angularTemplateParser from "@angular-eslint/template-parser"; export default [ ...intlayer.configs.recommended, { files: ["**/*.{ts,tsx,jsx}"], languageOptions: { parser: tseslint.parser }, }, { files: ["**/*.vue"], languageOptions: { parser: vueParser, parserOptions: { parser: tseslint.parser }, }, }, { files: ["**/*.svelte"], languageOptions: { parser: svelteParser, parserOptions: { parser: tseslint.parser }, }, }, { files: ["**/*.component.html"], languageOptions: { parser: angularTemplateParser }, }, ]; ``` Yalnızca projenizin ihtiyaç duyduğu ayrıştırıcıları yükleyin. > **Bilinen sınırlama.** Vue ve Angular şablonlarında `{{ content[key] }}` gibi bir ifade `no-dynamic-field-access` tarafından kontrol edilmez. Script bloğunda yazılan dinamik okumalar normal şekilde yakalanır.