[{"data":1,"prerenderedAt":1208},["ShallowReactive",2],{"navigation_docs":3,"-eslint-plugin-install-and-rules":302,"-eslint-plugin-install-and-rules-surround":1205},[4,18,32,53,74,103,120,133,147,156],{"title":5,"path":6,"stem":7,"children":8,"page":17},"Introduction","\u002Fintroduction","1.introduction",[9,13],{"title":10,"path":11,"stem":12},"Why the-i18n-kit","\u002Fintroduction\u002Fwhy","1.introduction\u002F1.why",{"title":14,"path":15,"stem":16},"Architecture","\u002Fintroduction\u002Farchitecture","1.introduction\u002F2.architecture",false,{"title":19,"icon":20,"path":21,"stem":22,"children":23,"page":17},"ESLint Plugin","i-lucide-shield-check","\u002Feslint-plugin","10.eslint-plugin",[24,28],{"title":25,"path":26,"stem":27},"Install and Rules","\u002Feslint-plugin\u002Finstall-and-rules","10.eslint-plugin\u002F1.install-and-rules",{"title":29,"path":30,"stem":31},"Layer-Aware Missing Keys","\u002Feslint-plugin\u002Flayer-aware","10.eslint-plugin\u002F2.layer-aware",{"title":33,"path":34,"stem":35,"children":36,"page":17},"Getting Started","\u002Fgetting-started","2.getting-started",[37,41,45,49],{"title":38,"path":39,"stem":40},"Set Up the MCP Server","\u002Fgetting-started\u002Fagent-setup","2.getting-started\u002F1.agent-setup",{"title":42,"path":43,"stem":44},"From an Unconfigured Repository to a Translated One","\u002Fgetting-started\u002Fcold-start","2.getting-started\u002F2.cold-start",{"title":46,"path":47,"stem":48},"Agent Contract","\u002Fgetting-started\u002Fagent-contract","2.getting-started\u002F3.agent-contract",{"title":50,"path":51,"stem":52},"Harness Integrations","\u002Fgetting-started\u002Fharness-integrations","2.getting-started\u002F4.harness-integrations",{"title":54,"path":55,"stem":56,"children":57,"page":17},"Monorepos","\u002Fmonorepos","3.monorepos",[58,62,66,70],{"title":59,"path":60,"stem":61},"Layers and the Consumer Graph","\u002Fmonorepos\u002Flayers-and-consumer-graph","3.monorepos\u002F1.layers-and-consumer-graph",{"title":63,"path":64,"stem":65},"Shared Layers and Duplicates","\u002Fmonorepos\u002Fduplicates-and-shared-layers","3.monorepos\u002F2.duplicates-and-shared-layers",{"title":67,"path":68,"stem":69},"Misplaced Usages","\u002Fmonorepos\u002Fmisplaced-usages","3.monorepos\u002F3.misplaced-usages",{"title":71,"path":72,"stem":73},"Orphan Detection","\u002Fmonorepos\u002Forphan-detection","3.monorepos\u002F4.orphan-detection",{"title":75,"path":76,"stem":77,"children":78,"page":17},"Frameworks","\u002Fframeworks","4.frameworks",[79,83,87,91,95,99],{"title":80,"path":81,"stem":82},"Detection","\u002Fframeworks\u002Fdetection","4.frameworks\u002F1.detection",{"title":84,"path":85,"stem":86},"Nuxt","\u002Fframeworks\u002Fnuxt","4.frameworks\u002F2.nuxt",{"title":88,"path":89,"stem":90},"Laravel","\u002Fframeworks\u002Flaravel","4.frameworks\u002F3.laravel",{"title":92,"path":93,"stem":94},"Vue","\u002Fframeworks\u002Fvue","4.frameworks\u002F4.vue",{"title":96,"path":97,"stem":98},"React \u002F Next.js","\u002Fframeworks\u002Freact-next","4.frameworks\u002F5.react-next",{"title":100,"path":101,"stem":102},"Generic","\u002Fframeworks\u002Fgeneric","4.frameworks\u002F6.generic",{"title":104,"path":105,"stem":106,"children":107,"page":17},"Configuration","\u002Fconfiguration","5.configuration",[108,112,116],{"title":109,"path":110,"stem":111},"Where Configuration Lives","\u002Fconfiguration\u002Fwhere-config-lives","5.configuration\u002F1.where-config-lives",{"title":113,"path":114,"stem":115},"Precedence and Locale References","\u002Fconfiguration\u002Fprecedence-and-locale-refs","5.configuration\u002F2.precedence-and-locale-refs",{"title":117,"path":118,"stem":119},"Configuration Fields","\u002Fconfiguration\u002Freference","5.configuration\u002F4.reference",{"title":121,"path":122,"stem":123,"children":124,"page":17},"Nuxt Module","\u002Fnuxt-module","6.nuxt-module",[125,129],{"title":126,"path":127,"stem":128},"Install and Setup","\u002Fnuxt-module\u002Finstall","6.nuxt-module\u002F1.install",{"title":130,"path":131,"stem":132},"The Artifact and Options","\u002Fnuxt-module\u002Fartifact-and-options","6.nuxt-module\u002F2.artifact-and-options",{"title":134,"icon":135,"path":136,"stem":137,"children":138,"page":17},"CI\u002FCD","i-lucide-git-pull-request","\u002Fci-cd","7.ci-cd",[139,143],{"title":140,"path":141,"stem":142},"GitHub Actions","\u002Fci-cd\u002Fgithub-actions","7.ci-cd\u002F1.github-actions",{"title":144,"path":145,"stem":146},"GitLab CI","\u002Fci-cd\u002Fgitlab-ci","7.ci-cd\u002F2.gitlab-ci",{"title":148,"path":149,"stem":150,"children":151,"page":17},"Concepts","\u002Fconcepts","8.concepts",[152],{"title":153,"path":154,"stem":155},"Translation Modes","\u002Fconcepts\u002Ftranslation-modes","8.concepts\u002F1.translation-modes",{"title":157,"path":158,"stem":159,"children":160,"page":-1},"Reference","\u002Freference","9.reference",[161,163,229,294,298],{"title":157,"path":158,"stem":162},"9.reference\u002Findex",{"title":164,"path":165,"stem":166,"children":167,"page":-1},"CLI Commands","\u002Freference\u002Fcli","9.reference\u002F1.cli\u002Findex",[168,169,173,177,181,185,189,193,197,201,205,209,213,217,221,225],{"title":164,"path":165,"stem":166},{"title":170,"path":171,"stem":172},"check","\u002Freference\u002Fcli\u002Fcheck","9.reference\u002F1.cli\u002Fcheck",{"title":174,"path":175,"stem":176},"discover","\u002Freference\u002Fcli\u002Fdiscover","9.reference\u002F1.cli\u002Fdiscover",{"title":178,"path":179,"stem":180},"find-duplicates","\u002Freference\u002Fcli\u002Ffind-duplicates","9.reference\u002F1.cli\u002Ffind-duplicates",{"title":182,"path":183,"stem":184},"get","\u002Freference\u002Fcli\u002Fget","9.reference\u002F1.cli\u002Fget",{"title":186,"path":187,"stem":188},"init","\u002Freference\u002Fcli\u002Finit","9.reference\u002F1.cli\u002Finit",{"title":190,"path":191,"stem":192},"missing","\u002Freference\u002Fcli\u002Fmissing","9.reference\u002F1.cli\u002Fmissing",{"title":194,"path":195,"stem":196},"move","\u002Freference\u002Fcli\u002Fmove","9.reference\u002F1.cli\u002Fmove",{"title":198,"path":199,"stem":200},"orphans","\u002Freference\u002Fcli\u002Forphans","9.reference\u002F1.cli\u002Forphans",{"title":202,"path":203,"stem":204},"remove","\u002Freference\u002Fcli\u002Fremove","9.reference\u002F1.cli\u002Fremove",{"title":206,"path":207,"stem":208},"scaffold","\u002Freference\u002Fcli\u002Fscaffold","9.reference\u002F1.cli\u002Fscaffold",{"title":210,"path":211,"stem":212},"search","\u002Freference\u002Fcli\u002Fsearch","9.reference\u002F1.cli\u002Fsearch",{"title":214,"path":215,"stem":216},"status","\u002Freference\u002Fcli\u002Fstatus","9.reference\u002F1.cli\u002Fstatus",{"title":218,"path":219,"stem":220},"translate","\u002Freference\u002Fcli\u002Ftranslate","9.reference\u002F1.cli\u002Ftranslate",{"title":222,"path":223,"stem":224},"translate-key","\u002Freference\u002Fcli\u002Ftranslate-key","9.reference\u002F1.cli\u002Ftranslate-key",{"title":226,"path":227,"stem":228},"write","\u002Freference\u002Fcli\u002Fwrite","9.reference\u002F1.cli\u002Fwrite",{"title":230,"path":231,"stem":232,"children":233,"page":-1},"MCP Tools","\u002Freference\u002Fmcp","9.reference\u002F2.mcp\u002Findex",[234,235,238,242,246,250,254,258,262,266,270,274,278,282,286,290],{"title":230,"path":231,"stem":232},{"title":174,"path":236,"stem":237},"\u002Freference\u002Fmcp\u002Fdiscover","9.reference\u002F2.mcp\u002Fdiscover",{"title":239,"path":240,"stem":241},"find_duplicate_keys","\u002Freference\u002Fmcp\u002Ffind_duplicate_keys","9.reference\u002F2.mcp\u002Ffind_duplicate_keys",{"title":243,"path":244,"stem":245},"find_orphan_keys","\u002Freference\u002Fmcp\u002Ffind_orphan_keys","9.reference\u002F2.mcp\u002Ffind_orphan_keys",{"title":247,"path":248,"stem":249},"find_undefined_keys","\u002Freference\u002Fmcp\u002Ffind_undefined_keys","9.reference\u002F2.mcp\u002Ffind_undefined_keys",{"title":251,"path":252,"stem":253},"get_missing_translations","\u002Freference\u002Fmcp\u002Fget_missing_translations","9.reference\u002F2.mcp\u002Fget_missing_translations",{"title":255,"path":256,"stem":257},"get_translation_status","\u002Freference\u002Fmcp\u002Fget_translation_status","9.reference\u002F2.mcp\u002Fget_translation_status",{"title":259,"path":260,"stem":261},"get_translations","\u002Freference\u002Fmcp\u002Fget_translations","9.reference\u002F2.mcp\u002Fget_translations",{"title":263,"path":264,"stem":265},"list_namespaces","\u002Freference\u002Fmcp\u002Flist_namespaces","9.reference\u002F2.mcp\u002Flist_namespaces",{"title":267,"path":268,"stem":269},"move_translation_key","\u002Freference\u002Fmcp\u002Fmove_translation_key","9.reference\u002F2.mcp\u002Fmove_translation_key",{"title":271,"path":272,"stem":273},"remove_translations","\u002Freference\u002Fmcp\u002Fremove_translations","9.reference\u002F2.mcp\u002Fremove_translations",{"title":275,"path":276,"stem":277},"scaffold_locale","\u002Freference\u002Fmcp\u002Fscaffold_locale","9.reference\u002F2.mcp\u002Fscaffold_locale",{"title":279,"path":280,"stem":281},"search_translations","\u002Freference\u002Fmcp\u002Fsearch_translations","9.reference\u002F2.mcp\u002Fsearch_translations",{"title":283,"path":284,"stem":285},"translate_key","\u002Freference\u002Fmcp\u002Ftranslate_key","9.reference\u002F2.mcp\u002Ftranslate_key",{"title":287,"path":288,"stem":289},"translate_missing","\u002Freference\u002Fmcp\u002Ftranslate_missing","9.reference\u002F2.mcp\u002Ftranslate_missing",{"title":291,"path":292,"stem":293},"write_translations","\u002Freference\u002Fmcp\u002Fwrite_translations","9.reference\u002F2.mcp\u002Fwrite_translations",{"title":295,"path":296,"stem":297},"GitHub Action","\u002Freference\u002Faction","9.reference\u002F3.action",{"title":299,"path":300,"stem":301},"Programmatic API","\u002Freference\u002Fprogrammatic-api","9.reference\u002F4.programmatic-api",{"id":303,"title":25,"body":304,"description":322,"extension":1199,"links":1200,"meta":1201,"navigation":401,"path":26,"seo":1202,"stem":27,"__hash__":1204},"docs\u002F10.eslint-plugin\u002F1.install-and-rules.md",{"type":305,"value":306,"toc":1192},"minimark",[307,311,316,345,365,443,480,530,533,603,615,748,761,793,797,804,902,909,913,926,929,947,980,1078,1089,1094,1097,1171,1184,1188],[308,309,310],"p",{},"Two rules, both about one contract: every i18n call must leave the orphan scanner\nenough to bound which keys it can produce. The scan keeps every safety net either\nway — the rules change how much work those nets do, not whether they exist.",[312,313,315],"h2",{"id":314},"install","Install",[317,318,323],"pre",{"className":319,"code":320,"language":321,"meta":322,"style":322},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm add -D @the-i18n-kit\u002Feslint-plugin-vue\n","bash","",[324,325,326],"code",{"__ignoreMap":322},[327,328,331,335,339,342],"span",{"class":329,"line":330},"line",1,[327,332,334],{"class":333},"sBMFI","pnpm",[327,336,338],{"class":337},"sfazB"," add",[327,340,341],{"class":337}," -D",[327,343,344],{"class":337}," @the-i18n-kit\u002Feslint-plugin-vue\n",[308,346,347,348,351,352,355,356,359,360,364],{},"ESLint ",[324,349,350],{},"^9.10.0"," (flat config only) and Node 18 or newer. One optional peer,\n",[324,353,354],{},"@intlify\u002Feslint-plugin-vue-i18n"," (",[324,357,358],{},"^3.0.0 || ^4.0.0","), is needed only for the\n",[361,362,363],"a",{"href":30},"layer-aware factory",".",[317,366,371],{"className":367,"code":368,"filename":369,"language":370,"meta":322,"style":322},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import i18nKit from '@the-i18n-kit\u002Feslint-plugin-vue'\n\nexport default [\n  ...i18nKit.configs.recommended,\n]\n","eslint.config.mjs","js",[324,372,373,396,403,415,437],{"__ignoreMap":322},[327,374,375,379,383,386,390,393],{"class":329,"line":330},[327,376,378],{"class":377},"s7zQu","import",[327,380,382],{"class":381},"sTEyZ"," i18nKit ",[327,384,385],{"class":377},"from",[327,387,389],{"class":388},"sMK4o"," '",[327,391,392],{"class":337},"@the-i18n-kit\u002Feslint-plugin-vue",[327,394,395],{"class":388},"'\n",[327,397,399],{"class":329,"line":398},2,[327,400,402],{"emptyLinePlaceholder":401},true,"\n",[327,404,406,409,412],{"class":329,"line":405},3,[327,407,408],{"class":377},"export",[327,410,411],{"class":377}," default",[327,413,414],{"class":381}," [\n",[327,416,418,421,424,426,429,431,434],{"class":329,"line":417},4,[327,419,420],{"class":388},"  ...",[327,422,423],{"class":381},"i18nKit",[327,425,364],{"class":388},[327,427,428],{"class":381},"configs",[327,430,364],{"class":388},[327,432,433],{"class":381},"recommended",[327,435,436],{"class":388},",\n",[327,438,440],{"class":329,"line":439},5,[327,441,442],{"class":381},"]\n",[308,444,445,446,449,450,453,454,436,457,460,461,464,465,468,469,460,472,475,476,479],{},"Despite the ",[324,447,448],{},"-vue"," in the name, both presets lint ",[324,451,452],{},"**\u002F*.vue",", ",[324,455,456],{},"**\u002F*.ts",[324,458,459],{},"**\u002F*.js"," and ",[324,462,463],{},"**\u002F*.mjs"," — and ",[324,466,467],{},"layerAware()"," adds ",[324,470,471],{},".tsx",[324,473,474],{},".jsx"," — because\nvue-i18n calls live in composables and stores as much as in components. They\nregister the plugin under the ",[324,477,478],{},"@the-i18n-kit\u002Fvue"," prefix and differ in one\nseverity:",[481,482,483,502],"table",{},[484,485,486],"thead",{},[487,488,489,493,497],"tr",{},[490,491,492],"th",{},"Rule",[490,494,495],{},[324,496,433],{},[490,498,499],{},[324,500,501],{},"strict",[503,504,505,518],"tbody",{},[487,506,507,513,516],{},[508,509,510],"td",{},[324,511,512],{},"literal-key-prefix",[508,514,515],{},"error",[508,517,515],{},[487,519,520,525,528],{},[508,521,522],{},[324,523,524],{},"runtime-key-needs-declared-namespace",[508,526,527],{},"warn",[508,529,515],{},[308,531,532],{},"Overriding a severity is plain flat-config precedence — a later entry wins:",[317,534,536],{"className":367,"code":535,"filename":369,"language":370,"meta":322,"style":322},"export default [\n  ...i18nKit.configs.recommended,\n  { rules: { '@the-i18n-kit\u002Fvue\u002Fruntime-key-needs-declared-namespace': 'error' } },\n]\n",[324,537,538,546,562,599],{"__ignoreMap":322},[327,539,540,542,544],{"class":329,"line":330},[327,541,408],{"class":377},[327,543,411],{"class":377},[327,545,414],{"class":381},[327,547,548,550,552,554,556,558,560],{"class":329,"line":398},[327,549,420],{"class":388},[327,551,423],{"class":381},[327,553,364],{"class":388},[327,555,428],{"class":381},[327,557,364],{"class":388},[327,559,433],{"class":381},[327,561,436],{"class":388},[327,563,564,567,571,574,577,579,582,585,587,589,591,593,596],{"class":329,"line":405},[327,565,566],{"class":388},"  {",[327,568,570],{"class":569},"swJcz"," rules",[327,572,573],{"class":388},":",[327,575,576],{"class":388}," {",[327,578,389],{"class":388},[327,580,581],{"class":569},"@the-i18n-kit\u002Fvue\u002Fruntime-key-needs-declared-namespace",[327,583,584],{"class":388},"'",[327,586,573],{"class":388},[327,588,389],{"class":388},[327,590,515],{"class":337},[327,592,584],{"class":388},[327,594,595],{"class":388}," }",[327,597,598],{"class":388}," },\n",[327,600,601],{"class":329,"line":417},[327,602,442],{"class":381},[308,604,605,606,609,610,614],{},"On Nuxt with ",[324,607,608],{},"@nuxt\u002Feslint",", contribute the preset and a\n",[361,611,612],{"href":30},[324,613,467],{}," call to the generated config\ninstead of writing one:",[317,616,621],{"className":617,"code":618,"filename":619,"language":620,"meta":322,"style":322},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { i18nKitEslintAddon } from '@the-i18n-kit\u002Feslint-plugin-vue\u002Fnuxt'\n\nexport default defineNuxtConfig({\n  modules: ['@nuxt\u002Feslint'],\n  hooks: {\n    'eslint:config:addons': addons => addons.push(i18nKitEslintAddon()),\n  },\n})\n","nuxt.config.ts","ts",[324,622,623,644,648,664,685,695,733,739],{"__ignoreMap":322},[327,624,625,627,629,632,634,637,639,642],{"class":329,"line":330},[327,626,378],{"class":377},[327,628,576],{"class":388},[327,630,631],{"class":381}," i18nKitEslintAddon",[327,633,595],{"class":388},[327,635,636],{"class":377}," from",[327,638,389],{"class":388},[327,640,641],{"class":337},"@the-i18n-kit\u002Feslint-plugin-vue\u002Fnuxt",[327,643,395],{"class":388},[327,645,646],{"class":329,"line":398},[327,647,402],{"emptyLinePlaceholder":401},[327,649,650,652,654,658,661],{"class":329,"line":405},[327,651,408],{"class":377},[327,653,411],{"class":377},[327,655,657],{"class":656},"s2Zo4"," defineNuxtConfig",[327,659,660],{"class":381},"(",[327,662,663],{"class":388},"{\n",[327,665,666,669,671,674,676,678,680,683],{"class":329,"line":417},[327,667,668],{"class":569},"  modules",[327,670,573],{"class":388},[327,672,673],{"class":381}," [",[327,675,584],{"class":388},[327,677,608],{"class":337},[327,679,584],{"class":388},[327,681,682],{"class":381},"]",[327,684,436],{"class":388},[327,686,687,690,692],{"class":329,"line":439},[327,688,689],{"class":569},"  hooks",[327,691,573],{"class":388},[327,693,694],{"class":388}," {\n",[327,696,698,701,704,706,708,712,716,718,720,723,725,728,731],{"class":329,"line":697},6,[327,699,700],{"class":388},"    '",[327,702,703],{"class":569},"eslint:config:addons",[327,705,584],{"class":388},[327,707,573],{"class":388},[327,709,711],{"class":710},"sHdIc"," addons",[327,713,715],{"class":714},"spNyl"," =>",[327,717,711],{"class":381},[327,719,364],{"class":388},[327,721,722],{"class":656},"push",[327,724,660],{"class":381},[327,726,727],{"class":656},"i18nKitEslintAddon",[327,729,730],{"class":381},"())",[327,732,436],{"class":388},[327,734,736],{"class":329,"line":735},7,[327,737,738],{"class":388},"  },\n",[327,740,742,745],{"class":329,"line":741},8,[327,743,744],{"class":388},"}",[327,746,747],{"class":381},")\n",[308,749,750,751,753,754,756,757,760],{},"Run with ",[324,752,433],{}," first, annotate the wire-driven calls as described below,\nthen promote to ",[324,755,515],{}," once the remaining warnings are decisions rather than a\nbacklog. For a one-off exception, a standard ",[324,758,759],{},"eslint-disable"," comment is the\nescape hatch.",[308,762,763,764,453,767,460,770,773,774,453,777,780,781,784,785,788,789,792],{},"Both rules recognize a call the way the scanner does: ",[324,765,766],{},"$t",[324,768,769],{},"$te",[324,771,772],{},"$tc","\nanywhere; a bare ",[324,775,776],{},"t",[324,778,779],{},"te"," or ",[324,782,783],{},"tc"," only where it resolves to a vue-i18n binding.\n",[324,786,787],{},"\u003Ctemplate>"," expressions in ",[324,790,791],{},".vue"," files are checked like script code.",[312,794,795],{"id":512},[324,796,512],{},[308,798,799,800,803],{},"Error in both presets. A dynamic key — a template literal with expressions, or a\n",[324,801,802],{},"+"," concatenation — must begin with a literal segment containing a dot.",[317,805,807],{"className":617,"code":806,"language":620,"meta":322,"style":322},"t(`${section}.title`)                  \u002F\u002F fires: nothing to anchor on\nt(prefix + '.title')                   \u002F\u002F fires\nt(`bookings.status.${status}`)         \u002F\u002F passes\nt('bookings.status.' + status)         \u002F\u002F passes\n",[324,808,809,836,857,882],{"__ignoreMap":322},[327,810,811,813,815,818,821,823,826,829,832],{"class":329,"line":330},[327,812,776],{"class":656},[327,814,660],{"class":381},[327,816,817],{"class":388},"`${",[327,819,820],{"class":381},"section",[327,822,744],{"class":388},[327,824,825],{"class":337},".title",[327,827,828],{"class":388},"`",[327,830,831],{"class":381},")                  ",[327,833,835],{"class":834},"sHwdD","\u002F\u002F fires: nothing to anchor on\n",[327,837,838,840,843,845,847,849,851,854],{"class":329,"line":398},[327,839,776],{"class":656},[327,841,842],{"class":381},"(prefix ",[327,844,802],{"class":388},[327,846,389],{"class":388},[327,848,825],{"class":337},[327,850,584],{"class":388},[327,852,853],{"class":381},")                   ",[327,855,856],{"class":834},"\u002F\u002F fires\n",[327,858,859,861,863,865,868,871,873,876,879],{"class":329,"line":405},[327,860,776],{"class":656},[327,862,660],{"class":381},[327,864,828],{"class":388},[327,866,867],{"class":337},"bookings.status.",[327,869,870],{"class":388},"${",[327,872,214],{"class":381},[327,874,875],{"class":388},"}`",[327,877,878],{"class":381},")         ",[327,880,881],{"class":834},"\u002F\u002F passes\n",[327,883,884,886,888,890,892,894,897,900],{"class":329,"line":417},[327,885,776],{"class":656},[327,887,660],{"class":381},[327,889,584],{"class":388},[327,891,867],{"class":337},[327,893,584],{"class":388},[327,895,896],{"class":388}," +",[327,898,899],{"class":381}," status)         ",[327,901,881],{"class":834},[308,903,904,905,908],{},"A key starting with a variable leaves the scanner two options: over-protect every\n",[324,906,907],{},"*.title"," key in the catalog, or delete live ones. Plain literals never fire.\nWhere a literal prefix is impossible, look full keys up from a local map of\nliterals instead.",[312,910,911],{"id":524},[324,912,524],{},[308,914,915,916,918,919,921,922,925],{},"Warn in ",[324,917,433],{},", error in ",[324,920,501],{},". It fires when the key is entirely\nruntime data — ",[324,923,924],{},"t(view.name_key)",", where the names arrive from a backend and no\nfrontend scan can see which keys the call keeps alive.",[308,927,928],{},"It demands two things, both checkable:",[930,931,932,940],"ol",{},[933,934,935,936,939],"li",{},"An ",[324,937,938],{},"i18n-namespace:"," comment on the call's line or the line above, naming the\npattern the keys draw from.",[933,941,942,943,946],{},"That exact pattern declared under ",[324,944,945],{},"declaredNamespaces"," in the kit config — the\nplace the scanner reads.",[317,948,951],{"className":617,"code":949,"filename":950,"language":620,"meta":322,"style":322},"\u002F\u002F i18n-namespace: views.defaults.**\nconst label = t(view.name_key)\n","components\u002FViewCard.vue",[324,952,953,958],{"__ignoreMap":322},[327,954,955],{"class":329,"line":330},[327,956,957],{"class":834},"\u002F\u002F i18n-namespace: views.defaults.**\n",[327,959,960,963,966,969,972,975,977],{"class":329,"line":398},[327,961,962],{"class":714},"const",[327,964,965],{"class":381}," label ",[327,967,968],{"class":388},"=",[327,970,971],{"class":656}," t",[327,973,974],{"class":381},"(view",[327,976,364],{"class":388},[327,978,979],{"class":381},"name_key)\n",[317,981,984],{"className":617,"code":982,"filename":983,"language":620,"meta":322,"style":322},"import { defineI18nKitConfig } from '@the-i18n-kit\u002Fcli\u002Fconfig'\n\nexport default defineI18nKitConfig({\n  declaredNamespaces: [\n    { pattern: 'views.defaults.**', reason: 'sent by bookings-api as name_key' },\n  ],\n})\n","i18n-kit.config.ts",[324,985,986,1006,1010,1022,1031,1065,1072],{"__ignoreMap":322},[327,987,988,990,992,995,997,999,1001,1004],{"class":329,"line":330},[327,989,378],{"class":377},[327,991,576],{"class":388},[327,993,994],{"class":381}," defineI18nKitConfig",[327,996,595],{"class":388},[327,998,636],{"class":377},[327,1000,389],{"class":388},[327,1002,1003],{"class":337},"@the-i18n-kit\u002Fcli\u002Fconfig",[327,1005,395],{"class":388},[327,1007,1008],{"class":329,"line":398},[327,1009,402],{"emptyLinePlaceholder":401},[327,1011,1012,1014,1016,1018,1020],{"class":329,"line":405},[327,1013,408],{"class":377},[327,1015,411],{"class":377},[327,1017,994],{"class":656},[327,1019,660],{"class":381},[327,1021,663],{"class":388},[327,1023,1024,1027,1029],{"class":329,"line":417},[327,1025,1026],{"class":569},"  declaredNamespaces",[327,1028,573],{"class":388},[327,1030,414],{"class":381},[327,1032,1033,1036,1039,1041,1043,1046,1048,1051,1054,1056,1058,1061,1063],{"class":329,"line":439},[327,1034,1035],{"class":388},"    {",[327,1037,1038],{"class":569}," pattern",[327,1040,573],{"class":388},[327,1042,389],{"class":388},[327,1044,1045],{"class":337},"views.defaults.**",[327,1047,584],{"class":388},[327,1049,1050],{"class":388},",",[327,1052,1053],{"class":569}," reason",[327,1055,573],{"class":388},[327,1057,389],{"class":388},[327,1059,1060],{"class":337},"sent by bookings-api as name_key",[327,1062,584],{"class":388},[327,1064,598],{"class":388},[327,1066,1067,1070],{"class":329,"line":697},[327,1068,1069],{"class":381},"  ]",[327,1071,436],{"class":388},[327,1073,1074,1076],{"class":329,"line":735},[327,1075,744],{"class":388},[327,1077,747],{"class":381},[308,1079,1080,1081,1084,1085,364],{},"An annotation naming a pattern the config does not declare is reported as drift,\nwith the config path in the message; so is a runtime key with no kit config above\nthe file, since there is nowhere to declare the namespace. A pattern from any\nlayer's ",[324,1082,1083],{},"orphanScan.ignorePatterns"," is accepted too, and the config is re-read\nwhen it changes, so a declaration you just added stops the report without an\neditor restart. What a declaration protects is reported by\n",[361,1086,1087],{"href":72},[324,1088,198],{},[1090,1091,1093],"h3",{"id":1092},"what-never-fires","What Never Fires",[308,1095,1096],{},"The scanner's own leniencies, restated — what the candidate net already protects,\nthe rule does not question:",[481,1098,1099,1109],{},[484,1100,1101],{},[487,1102,1103,1106],{},[490,1104,1105],{},"Shape",[490,1107,1108],{},"Why it is safe",[503,1110,1111,1128,1142,1158],{},[487,1112,1113,1122],{},[508,1114,1115,1118,1119],{},[324,1116,1117],{},"const KEY = 'bookings.title'"," … ",[324,1120,1121],{},"t(KEY)",[508,1123,1124,1125,1127],{},"A same-file ",[324,1126,962],{}," holding a string literal",[487,1129,1130,1137],{},[508,1131,1132,1118,1135],{},[324,1133,1134],{},"const KEY = `bookings.${id}`",[324,1136,1121],{},[508,1138,1124,1139,1141],{},[324,1140,962],{}," holding a dotted-prefix template",[487,1143,1144,1152],{},[508,1145,1146,1118,1149],{},[324,1147,1148],{},"const LABELS = { a: 'x.a' }",[324,1150,1151],{},"t(LABELS[state])",[508,1153,1154,1155,1157],{},"A lookup into a same-file ",[324,1156,962],{}," map of literals",[487,1159,1160,1168],{},[508,1161,1162,453,1165],{},[324,1163,1164],{},"te(x)",[324,1166,1167],{},"$te(x)",[508,1169,1170],{},"An existence check commits to nothing",[308,1172,1173,1174,1176,1177,780,1180,1183],{},"Only ",[324,1175,962],{}," bindings count: a ",[324,1178,1179],{},"let",[324,1181,1182],{},"var"," can hold anything by the time the\ncall runs, and a conditional expression is runtime data if either branch is.\nRefactoring a protected shape into an unprotected one is exactly when this rule\nfires and should.",[1185,1186,1187],"note",{},"The rules are Vue-only: the vue-i18n call family in plain Vue or Nuxt, no React\ncall family. React projects keep the CLI's full scan coverage in CI. The plugin\nlints code, not catalogs — duplicate values, unused keys and completeness stay\nwith the CLI.",[1189,1190,1191],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":322,"searchDepth":405,"depth":405,"links":1193},[1194,1195,1196],{"id":314,"depth":398,"text":315},{"id":512,"depth":398,"text":512},{"id":524,"depth":398,"text":524,"children":1197},[1198],{"id":1092,"depth":405,"text":1093},"md",null,{},{"description":1203,"title":25},"How to install @the-i18n-kit\u002Feslint-plugin-vue, which preset to spread, what each rule fires on, and how the i18n-namespace annotation ties a call to the kit config.","B1Z7jBsf-hIBq1E4XLoImL9EmmZZ22kjCWTONdH9ntA",[1206,1207],{"title":14,"path":15,"stem":16,"description":322,"children":-1},{"title":29,"path":30,"stem":31,"description":322,"children":-1},1789062605941]