Skip to content

Translation Workflow ​

This page covers core translation operations: translate single file, translate folder, consistency check, and rollback.

Load Locale Files ​

Optional: A preparatory step before translation, automatically loads JSON files from specified directories. Below are common approaches for webpack and vite:

webpack ​

js
const enContext = require.context('./module', true, /\/en-US\.json$/)
const zhContext = require.context('./module', true, /\/zh-CN\.json$/)

const contextToModuleMap = (context) => Object.fromEntries(context.keys().map((key) => [key, context(key)]))

const enMds = contextToModuleMap(enContext)
const zhMds = contextToModuleMap(zhContext)

const getLocaleCollect = (m) => Object.values(m).reduce((o, k) => ({ ...o, ...k }), {})

const enUsCollect = getLocaleCollect(enMds)
const zhCnCollect = getLocaleCollect(zhMds)

vite ​

js
const enMds = import.meta.glob('./module/**/en-US.json', { eager: true, import: 'default' })
const zhMds = import.meta.glob('./module/**/zh-CN.json', { eager: true, import: 'default' })

const getLocaleCollect = (m) => Object.values(m).reduce((o, k) => ({ ...o, ...k }), {})

const enUsCollect = getLocaleCollect(enMds)
const zhCnCollect = getLocaleCollect(zhMds)

Translate Single File ​

hitf tf translates a single file. It extracts source language text, generates keys, writes locale files, and replaces source text with internationalization calls.

By default, it works with Chinese source code projects. Configure locales: ["en-US", "zh-CN", "ja-JP"] to extract English text and translate to zh-CN and ja-JP.

Basic Command ​

sh
hitf tf views\demo\index.vue

Supported file types:

TypeDescription
.vueVue SFC, including <template>, <script>, <script setup>
.js / .tsJavaScript and TypeScript business code
.jsx / .tsxReact JSX / TSX
.jsonJSON text values

Basic Options ​

sh
hitf tf src\views\demo\index.vue demo -d
hitf tf src\views\demo\index.vue demo -i
hitf tf src\views\demo\index.vue demo -r .hitf\reports\demo.json
hitf tf apps\main\src\views\index.vue home -p main
OptionShortDescription
-n, --name <name>-ni18n namespace key (defaults to parent directory name)
-p, --project <project>-pSpecify project when outDir is an object
-d, --dry-run-dPreview only: list extracted texts with locations; no translation or file writes
-i, --interactive-iSelect texts to translate in a tree; deselected items get ignore comments automatically and are skipped
-r, --report <file>-rWrite JSON translation report
-v, --verbose-vOutput detailed logs

Dry-run Mode ​

-d / --dry-run previews the translation plan only: no API calls, no file writes. For a single file, tf lists each extracted text with its source location (file:line:column), followed by skipped (non-extracted) strings with reasons:

sh
hitf tf src\views\demo\index.vue -d

Output example:

text
  suitable → src/views/demo/index.vue:2:21
  test → src/views/demo/index.vue:3:21

tf -d does not generate locale files or modify source code, so it is a good way to review the extraction scope before translating.

Interactive Selection ​

-i / --interactive shows a tree checkbox for choosing which texts to translate. Only selected items participate in translation and get keys; deselected items are marked as ignored in place and are skipped on subsequent extractions:

sh
hitf tf src\views\demo\index.vue demo -i

Key bindings:

KeyAction
↑ / ↓Move up / down
← / →Collapse / expand a group
SpaceToggle: leaf toggles itself; a group toggles its whole branch (◉ all / ◐ partial / ◯ none)
Ctrl+ASelect all visible leaves
Ctrl+I (also Tab)Invert visible leaves
EnterConfirm (at least 1 item must be selected)
any characterFilter by text; Backspace removes the search term

After confirmation, only selected items are translated. Deselected items trigger the message "N texts skipped (ignore comments will be added)" and ignore comments are inserted automatically (see Ignore Comments below):

  • JS / TS: /* @hitf-i18n-ignore-start */ … /* @hitf-i18n-ignore-end */
  • Vue template text: <!-- @hitf-i18n-ignore-start --> … <!-- @hitf-i18n-ignore-end -->
  • JSX: {/* @hitf-i18n-ignore-start */} … {/* @hitf-i18n-ignore-end */}
  • Vue template static attributes: <!-- @hitf-i18n-ignore:prop:<attrName> --> placed directly above the target tag
  • JSON files: no comments can be inserted; entries are recorded in .hitf/i18n-ignore.json and filtered automatically on later runs

If the interaction is interrupted (e.g. Ctrl+C), the translation is aborted with no writes.

Extraction Scope ​

Extracts user-visible or runtime-displayed text:

js
message.success('Save successfully')
toast('Copied')

const item = {
  label: 'User Name',
  title: 'User Detail',
  placeholder: 'Enter username',
  description: 'Please select a user'
}

Supports fallback text in logical expressions:

js
const text = data?.text || 'Default text'
const desc = data?.description ?? 'No description'

Also supported in Vue templates:

vue
{{ data?.text || 'Default text' }}
{{ data?.description ?? 'No description' }}

Destructuring defaults and function parameter defaults are not extracted by default, to avoid mistaking type/data structure fallbacks for UI text:

js
const { propertyName = 'User name' } = objectToDestruct
function submit(label = 'Save') {}

Vue Template ​

Text nodes are replaced with $t:

vue
<button>登录</button>
vue
<button>{{ $t('demo.login') }}</button>

Chinese next to interpolation preserves expression boundaries:

vue
<h1>留言({{ remarkList ? remarkList.length : 0 }})</h1>
vue
<h1>{{ $t('demo.leave_a_message') }}({{ remarkList ? remarkList.length : 0 }})</h1>

Attributes ​

User-visible attributes are translated:

vue
<input placeholder="请输入用户名" />
vue
<input :placeholder="$t('demo.please_enter_username')" />

Resource path attributes are not translated, to avoid breaking file references:

vue
<img src="@/assets/images/ssHome/供应商总数量1.png" alt="供应商总数量" />
vue
<img src="@/assets/images/ssHome/供应商总数量1.png" :alt="$t('demo.total_number_of_suppliers')" />

Currently skipped resource attributes include src, srcset, href, poster.

Style-related content is skipped, including class, dynamic classes, inline style, and <style> blocks:

vue
<div class="user-card" :style="{ color: 'red' }">用户详情</div>

<style lang="scss" scoped>
.user-card {}
</style>

JavaScript Strings ​

Source language strings in scripts are replaced with translation function calls:

js
const title = '登录'
js
const title = t('demo.login')

English source example:

json
{
  "translationSetting": {
    "locales": ["en-US", "zh-CN", "ja-JP"]
  }
}
vue
<button>Login</button>
vue
<button>{{ $t('demo.login') }}</button>

Chinese in regex is part of matching rules, not recommended for automatic translation:

js
const regex = /中文|English/giu

Already processed $t(...), this.$t(...), t(...) are skipped. Vue2's this.$t is still supported.

JSX ​

JSX text is replaced with {t(...)}:

jsx
<h1>留言({remarkList ? remarkList.length : 0})</h1>
jsx
<h1>{t('jsxAll.leave_a_message')}({remarkList ? remarkList.length : 0})</h1>

Long natural language should be processed as a complete unit, to avoid splitting into too many keys by commas or periods.

In JSX/TSX, className, style, event attributes, type, role, data-*, aria-* are skipped; custom display attributes can be extracted:

tsx
<Comp title="User Detail" label="User Name" />

Vue SFC's <script setup lang="jsx"> and <script setup lang="tsx"> are also parsed as JSX/TSX, supporting render functions and JSX text returned from defineComponent.

Ignore Comments ​

Use ignore comments for code you don't want processed temporarily:

js
// @hitf-i18n-ignore-next
message.success('Keep original')

/* @hitf-i18n-ignore-start */
const a = 'Keep original'
const b = 'Keep original too'
/* @hitf-i18n-ignore-end */

Vue template:

vue
<!-- @hitf-i18n-ignore-next -->
<div>保持原文</div>

Ignore entire file:

js
// @hitf-i18n-ignore-file

Directives:

DirectiveEffect
@hitf-i18n-ignore-nextIgnore the next extractable segment
@hitf-i18n-ignore-start / -endIgnore all texts in the range
@hitf-i18n-ignore-fileIgnore the entire file
@hitf-i18n-ignore:prop:<attrName>Ignore a specific static attribute in Vue templates (e.g. <!-- @hitf-i18n-ignore:prop:placeholder -->)

These comments can also be inserted automatically by -i deselection: /* */ for JS / TS, <!-- --> for Vue templates, {/* */} for JSX, and <!-- @hitf-i18n-ignore:prop:<attrName> --> above the target tag for Vue template static attributes. JSON files cannot contain comments, so deselected items are recorded in .hitf/i18n-ignore.json and filtered automatically on later runs.

Output ​

Translation typically produces two types of changes:

  1. Chinese in the original file is replaced with $t or t calls.
  2. Corresponding locale files are generated in the locale directory.

Example:

text
src\locale\module\demo\zh-CN.json
src\locale\module\demo\en-US.json

Translate Folder ​

hitf tfo recursively translates an entire folder.

Basic Command ​

sh
hitf tfo src\views

Recursively processes all .vue, .js, .ts, .jsx, .tsx, .json files.

Common Options ​

sh
# Dry-run mode
hitf tfo src\views demo -d

# Interactive confirmation
hitf tfo src\views demo -i

# Generate report
hitf tfo src\views demo -r .hitf\reports\demo.json
OptionShortDescription
-n, --name <name>-ni18n namespace key (defaults to parent directory name)
-p, --project <project>-pSpecify project when outDir is an object
-d, --dry-run-dPreview only: list extracted texts with locations; no translation or file writes
-i, --interactive-iSelect texts to translate in a tree; deselected items get ignore comments automatically and are skipped
-r, --report <file>-rWrite JSON translation report
-v, --verbose-vOutput detailed logs

Folder Preview (Tree Browse) ​

After scanning, tfo -d shows a read-only tree of the three-level plan directory > file > text (leaves are marked [tr] and are all translated by default):

sh
hitf tfo src\views demo -d

Tree keys: ↑/↓ move · ←/→ collapse/expand · type to search · Enter to finish. After closing, it prints the total number of texts to translate and skipped-string details per file. No translation is performed and no files are written.

In a non-TTY environment (scripts / CI / pipes), tfo -d skips the interactive tree and falls back to a static tree printout; the preview output is still complete.

Folder Interactive Selection ​

tfo -i uses a tree checkbox organized as directory > file > text to choose which texts to translate; deselected items get ignore comments automatically (same behavior as single-file tf -i, see Interactive Selection above):

sh
hitf tfo src\views demo -i

Exclude Files ​

Use --exclude to exclude specific files:

sh
hitf tfo src --exclude "**/*.test.js"

Batch Output ​

Translation results are written to the corresponding namespace directory under outDir:

text
src\locale\module\demo\zh-CN.json
src\locale\module\demo\en-US.json

Consistency Check ​

hitf tcheck checks whether $t(...), this.$t(...), t(...) references in source code match locale JSON files.

Basic Command ​

sh
hitf tcheck src
hitf tcheck src -r .hitf\reports\tcheck.json

Check Content ​

TypeDescription
missingKeys referenced in source but missing from all locale files
unusedKeys present in locale files but not referenced in source
inconsistentKeys missing from some locale JSON files
invalid locale filesUnparseable JSON locale files

Output Example ​

text
Translation check summary
  missing: 2
  unused: 0
  inconsistent: 0
  invalid locale files: 0
  missing hello
    src/App.vue:2:11
  missing welcome
    src/App.vue:3:9

tcheck is suitable for running after batch migration, and can be added to CI to prevent missing locale files or corrupted JSON from entering the main branch.

Rollback ​

hitf rollback undoes the last translation operation.

Basic Command ​

sh
hitf rollback              # Rollback the latest
hitf rollback -l          # List available backups
hitf rollback -n xxx       # Rollback a specific backup
hitf rollback -k 5         # Keep only 5 most recent backups

Options ​

OptionShortDescription
-l, --list-lList all available backups
-n, --name <name>-nRollback a specific backup by name
-k, --keep <count>-kKeep only N most recent backups

Use Cases ​

  1. Unsatisfactory translation results: Rollback and adjust configuration before re-translating
  2. Recovery from mistakes: Rollback to the state before translation
  3. Backup management: Clean up old backups to free space

Translation Reports ​

Both tf and tfo support -r, --report <file> to generate translation reports:

sh
hitf tf src\views\user\index.vue user -d -r .hitf\reports\user.json
hitf tfo src\views user -r .hitf\reports\user-folder.json

Reports are in JSON format, suitable for manual review, CI upload, or script processing:

json
{
  "mode": "dry-run",
  "summary": {
    "filesScanned": 1,
    "filesWithExtractions": 1,
    "replacements": 3,
    "written": 0,
    "skipped": 1,
    "failed": 0
  },
  "files": [
    {
      "file": "src/views/user/index.vue",
      "outputFile": ".hitf/lang/user/index.vue",
      "replacements": [
        {
          "text": "User Detail",
          "key": "user.user_detail",
          "context": "attribute",
          "start": 42,
          "end": 53
        }
      ]
    }
  ],
  "failedFiles": []
}

Field descriptions:

FieldDescription
modedry-run or write
summary.filesScannedNumber of files actually scanned
summary.filesWithExtractionsNumber of files with extraction results
summary.replacementsNumber of texts to be replaced or already replaced
summary.writtenNumber of files written
summary.skippedNumber of files skipped
summary.failedNumber of files failed
files[].replacementsExtracted text, key, context, and position for each file
failedFilesFiles that failed syntax validation or processing

Released under the MIT License.