Key Translator
A VS Code extension that translates content in YAML, JSON, or JSONC files, displaying a read-only preview without modifying the original file.
Features
- 🌍 Translate files: Translates specified keys in YAML, JSON, or JSONC files
- 👀 Read-only preview: Shows translation in a side-by-side view without modifying the original
- 💾 Smart caching: Two-level cache system for fast repeated translations
- 🔄 Multiple providers: Supports macOS Shortcuts, OpenAI, Google Translate, and Tencent Translate
- 📝 Format preservation: Maintains original formatting, comments, and YAML structure
- 🎯 Selective translation: Skip Jinja templates and code blocks automatically
Installation
- Install the extension from VS Code Marketplace (or install
.vsix manually)
- Choose your translation provider in settings
Quick Start
- Install the extension.
- Configure the provider:
- For macOS (Default): Ensure the Shortcuts app is set up with a translation shortcut. You can use the pre-made one.
- For OpenAI/Google/Tencent: Set your API key in the VS Code settings.
- Set languages: Configure your
keyTranslator.sourceLanguage and keyTranslator.targetLanguage.
- Define keys: Specify which keys to translate in
keyTranslator.keysToTranslate (e.g., ["name", "description"]).
- Run translation: Open a YAML/JSON file and click the 🌍 Translate File button in the editor toolbar.
Setup
Option 1: macOS Shortcuts (Default - Free)
This provider runs translations locally on your machine and is completely free.
Easy Install: You can get a pre-configured shortcut from this link: https://www.icloud.com/shortcuts/028921c9c833428ab08d3556fd9aef22. After adding it, you may need to edit the "Translate Text" action to select your desired target language. The default name is KeyTranslate.
If you prefer to create the shortcut manually, follow these steps:
- Open the Shortcuts app on your Mac (macOS 12+ is required).
- Create a new Shortcut. You can name it anything, for example
KeyTranslate.
- Add the following actions in this specific order:
- Get Dictionary from Input: Set this to get the dictionary from
Shortcut Input. This action parses the data sent by the extension.
- Get Value for Key: Set this to get the value for the key
text from the Dictionary provided by the previous step.
- Translate Text: Set this to translate the
Value from the previous step. Choose the language you want to translate to (e.g., "Chinese, Simplified").
- Save the shortcut with a consistent name (e.g.,
KeyTranslate). The final output of the shortcut should automatically be the result of the "Translate Text" action.
- In your VS Code settings, configure the provider and your new shortcut's name:
{
"keyTranslator.provider": "macos_shortcuts",
"keyTranslator.macos.shortcutsName": "KeyTranslate"
}
Option 2: OpenAI
- Get an API key from an OpenAI-compatible provider
- In VS Code settings:
{
"keyTranslator.provider": "openai",
"keyTranslator.openai.apiKey": "sk-…",
"keyTranslator.openai.model": "gpt-3.5-turbo",
// Optional: for custom OpenAI-compatible endpoints
"keyTranslator.openai.apiUrl": "http://localhost:8080/v1/chat/completions"
}
Option 3: Google Translate
- Get an API key from Google Cloud Console
- In VS Code settings:
{
"keyTranslator.provider": "google",
"keyTranslator.google.apiKey": "YOUR_API_KEY"
}
Option 4: Tencent Translate
- Get a Secret ID and Secret Key from the Tencent Cloud CAM console
- In VS Code settings:
{
"keyTranslator.provider": "tencent",
"keyTranslator.tencent.secretId": "YOUR_SECRET_ID",
"keyTranslator.tencent.secretKey": "YOUR_SECRET_KEY"
}
Usage
- Open any YAML (
.yml), JSON (.json), or JSONC (.jsonc) file
- Click the 🌍 Translate File button in the editor toolbar
- View the translated preview in the side panel
- Use additional buttons to:
- Copy translation to clipboard
- Open Diff view to compare original and translated
- Refresh translation
Example: Translation Preview
Here's an example of the extension in action, showing how it handles a YAML file with embedded Jinja templates. The extension intelligently skips the template expressions (highlighted in the preview) while translating the surrounding text content.

Configuration
Basic Settings
{
// Translation provider
"keyTranslator.provider": "macos_shortcuts",
// Keys to translate (case-sensitive)
"keyTranslator.keysToTranslate": ["description", "name"],
// Key matching mode: "exact" | "contains" | "regex"
"keyTranslator.keyMatchMode": "exact",
// Source and target languages (full name or language code)
"keyTranslator.sourceLanguage": "English",
"keyTranslator.targetLanguage": "Chinese",
// Translate comments (# ...)
"keyTranslator.translateComments": false,
// Patterns to skip translation
"keyTranslator.skipPatterns": ["{{", "{%", "}}", "%}", "${"]
}
Cache Settings
{
// Enable caching
"keyTranslator.cache.enabled": true,
// Cache scope: "global" (all workspaces) | "workspace" (current workspace only)
"keyTranslator.cache.scope": "global",
// Maximum cache entries (LRU eviction)
"keyTranslator.cache.maxEntries": 10000
}
Provider Options
{
// Maximum texts per batch request
"keyTranslator.providerOptions.maxBatchSize": 50,
// Maximum concurrent requests
"keyTranslator.providerOptions.concurrency": 3,
// Retry attempts for failed requests
"keyTranslator.providerOptions.retries": 3,
// Request timeout (milliseconds)
"keyTranslator.providerOptions.timeoutMs": 20000
}
Advanced: Prompt Customization
For LLM-based providers like OpenAI, you can customize the translation prompts.
{{from}} and {{to}} are replaced with the source/target languages.
{{text}} is replaced with the content to be translated.
{
"keyTranslator.promptSettings.systemPrompt": "You are a professional {{to}} native translator...",
"keyTranslator.promptSettings.userPromptSingle": "Translate to {{to}}:\n\n{{text}}",
"keyTranslator.promptSettings.userPromptMulti": "Translate the `text` fields... Input: {{text}}"
}
Note: These are example customizations. The extension provides sensible defaults, so you only need to customize these if you want to change the default behavior.
How It Works
- Parse YAML: Uses the
yaml library to parse YAML with CST (Concrete Syntax Tree)
- Match keys: Finds all values for specified keys (respects nesting, arrays, etc.)
- Check cache: Looks up translations in local cache (phrase-level and file-level)
- Translate: Sends uncached texts to translation provider in batches
- Apply replacements: Replaces original text while preserving formatting
- Show preview: Displays translated content in a virtual document
Features in Detail
The extension preserves:
- ✅ Original indentation
- ✅ Comments (including inline comments)
- ✅ Quote styles (single, double, or none)
- ✅ Block scalars (
| and >)
- ✅ YAML anchors and aliases
- ✅ All other YAML structures
Smart Skipping
Automatically skips translating content that contains certain patterns. By default, it skips:
- Jinja templates:
{{ var }}, {% if %}
- Code expressions:
${variable}
- Empty or null values
You can customize the patterns to skip in the settings with keyTranslator.skipPatterns.
Skipped items are logged in the Output panel.
Two-Level Cache
- Phrase cache: Normalizes and caches individual translations across all files
- File fingerprint: Tracks file changes using SHA-1 hash to reuse entire translation
Commands
Key Translator: Translate File - Translate current file
Key Translator: Copy Translation to Clipboard - Copy preview content
Key Translator: Open Diff with Original - Show side-by-side diff
Key Translator: Refresh Translation - Re-translate (bypasses cache)
Known Limitations
- Template handling: Complex Jinja/template mixing is skipped by default
- Custom YAML tags: Non-standard YAML tags may not be fully supported
- Very large files: Files with 1000+ translatable nodes may be slow
- macOS only: Shortcuts provider only works on macOS 12+
Troubleshooting
"Shortcuts CLI not available"
- Ensure you're on macOS 12 (Monterey) or later
- Open Shortcuts.app at least once to initialize
- Try running
shortcuts list in Terminal
"Translation failed"
- Check Output panel (View → Output → Key Translator) for details
- Verify API keys are correct (for OpenAI/Google)
- Check internet connection
- Try reducing
maxBatchSize if hitting rate limits
"Nothing translated"
- Verify your YAML file contains keys matching
keysToTranslate
- Check if content contains template markers (will be skipped)
- Try changing
keyMatchMode to "contains"
command 'keyTranslator.translateFile' not found
If you see this error after installing a packaged .vsix file, it's likely due to a bundling issue with the jsonc-parser dependency.
Solution for Developers:
This is resolved by ensuring esbuild uses the correct module version. The build script in package.json has been updated with the --main-fields=module,main flag to fix this. If you are building the extension from source, ensure this flag is present in the esbuild-base script.
Privacy & Data
- ✅ No telemetry or analytics
- ✅ All cache stored locally in VS Code storage
- ✅ API keys stored in VS Code settings (encrypted by VS Code)
- ⚠️ Text sent to external APIs (OpenAI/Google/Tencent) per provider
- ✅ macOS Shortcuts runs locally (no external API)
Contributing
Found a bug or have a feature request? Please open an issue on GitHub!
Developer Guide
Build Instructions
Prerequisites
- Node.js 16+ and pnpm
- VS Code 1.80+
Setup
# Clone this repository and navigate into it
# Install dependencies
pnpm install
Local Development & Pre-commit Hooks
This project uses Husky to manage Git hooks, ensuring code quality and security before it gets committed. All checks are run automatically when you use git commit.
On git commit:
- Linting & Formatting:
eslint (including eslint-plugin-security for code patterns) and prettier are run on staged files via lint-staged.
- Secret Scanning:
secretlint scans for any accidentally committed API keys, passwords, or other secrets.
- TypeScript Compilation: The entire project is checked for type errors with
tsc.
- Tests: The full test suite is run with
pnpm test.
- Dependency Audit:
pnpm audit checks for known vulnerabilities in project dependencies.
If any of these checks fail, the commit will be aborted.
Development
# Compile TypeScript in watch mode
pnpm run watch
# Run tests
pnpm test
Testing in VS Code
- Press
F5 to open the Extension Development Host window.
- In the new window, open a YAML, JSON, or JSONC file.
- Run the translation command to test the extension.
Package & Publish
Note on pnpm, esbuild, and vsce:
When packaging the extension, dependencies are bundled using esbuild. A critical detail is that some dependencies, like jsonc-parser, require a specific module format to be bundled correctly.
Solution:
To resolve this, we use two main strategies:
- The
esbuild command in package.json includes the --main-fields=module,main flag. This tells esbuild to prefer the ESM version of dependencies, which avoids bundling issues.
- We use the
--no-dependencies flag with vsce, as all dependencies are already included in the esbuild bundle.
# Package the extension into a .vsix file
pnpm run package
# Publish to the marketplace (requires PAT)
pnpm run publish
License
Apache License 2.0 - see LICENSE.txt file
Changelog
See CHANGELOG.md