Chuyển đến nội dung chính

Cấu hình

Rosetta hoạt động mà không cần cấu hình (zero-config) — nó tự động phát hiện các tệp ngôn ngữ (locale), định dạng và ngôn ngữ đích từ dự án của bạn. Để kiểm soát nhiều hơn, hãy tạo i18n-rosetta.config.json trong thư mục gốc của dự án, hoặc chạy:

npx i18n-rosetta init

Tham chiếu cấu hình đầy đủ

i18n-rosetta.config.json
{
"version": 3,
"inputLocale": "en",
"localesDir": "./locales",
"contentDir": null,
"translatableFields": null,
"format": "auto",
"model": "google/gemini-3.5-flash",
"defaultMethod": "llm",
"batchSize": 80,
"jsonConcurrency": 200,
"contentConcurrency": 48,
"fallbackPrefix": "[EN] ",
"apiKeyEnvVar": "OPENROUTER_API_KEY",
"baseUrl": "",
"pairs": {},
"languages": {},
"lint": {
"srcDir": null,
"ignore": ["node_modules", ".next", "dist"],
"minLength": 2
},
"seo": {
"urlPattern": "/:locale/:path",
"pages": null
},
"typegen": {
"output": null,
"autoGenerate": false
}
}

:::note typegen chưa được triển khai Khối cấu hình typegen được trình tải cấu hình nhận diện và giữ nguyên, nhưng tính năng tạo kiểu TypeScript (type generation) chưa được triển khai. Đây là phần giữ chỗ cho một tính năng đã được lên kế hoạch. Việc thiết lập các giá trị này sẽ không có tác dụng gì. :::

Các trường

TrườngKiểuMặc địnhMô tả
versionnumber3Phiên bản schema cấu hình. Luôn là 3.
inputLocalestring"en"Mã ngôn ngữ nguồn (BCP 47).
localesDirstring"./locales"Đường dẫn đến các tệp locale. Rosetta sẽ quét thư mục này.
contentDirstringnullThư mục nội dung Hugo. Kích hoạt tính năng dịch phần thân Markdown.
translatableFieldsstring[]nullGhi đè các trường frontmatter có thể dịch mặc định cho việc dịch nội dung. null sử dụng các giá trị mặc định có sẵn (title, description, summary).
formatstring"auto"Định dạng tệp: json, toml, yaml, hoặc auto (phát hiện từ phần mở rộng).
modelstring"google/gemini-3.5-flash"Mô hình mặc định cho các phương thức LLM. Định dạng phụ thuộc vào phương thức: OpenRouter sử dụng provider/model (ví dụ: google/gemini-3.5-flash); các nhà cung cấp trực tiếp sử dụng tên trần (ví dụ: gpt-4o, gemini-2.5-flash).
defaultMethodstring"llm"Phương thức dịch mặc định: llm, llm-coached, google-translate, deepl, microsoft-translator, libretranslate, openai, anthropic, gemini, api. Bị ghi đè bởi cờ CLI --method.
batchSizenumber80Số lượng khóa (keys) trên mỗi lô dịch. Cao hơn = ít lệnh gọi API hơn, nhưng prompt lớn hơn.
jsonConcurrencynumber200Số lượng bản dịch locale song song tối đa cho việc đồng bộ khóa JSON. Bị ghi đè bởi cờ CLI --json-concurrency.
contentConcurrencynumber48Số lượng lệnh gọi API song song tối đa cho việc dịch nội dung (Markdown/MDX). Bị ghi đè bởi cờ CLI --content-concurrency.
fallbackPrefixstring"[EN] "Tiền tố đánh dấu được sử dụng bởi auditverify để phát hiện các giá trị chưa dịch cũ từ các lần chạy trước. Rosetta không ghi tiền tố này — nó chỉ đọc để phát hiện.
apiKeyEnvVarstring"OPENROUTER_API_KEY"Tên biến môi trường cho API key. Ghi đè cho các tên biến môi trường tùy chỉnh.
baseUrlstring""Base URL để tạo các artifact SEO (hreflang, sitemaps, JSON-LD).
pairsobject{}Ghi đè phương thức, mô hình và chất lượng cho từng cặp ngôn ngữ. Xem Cấu hình cặp ngôn ngữ.
languagesobject{}Ghi đè cho từng ngôn ngữ. Xem Cấu hình ngôn ngữ.
lint.srcDirstringnullThư mục nguồn để quét lint. null = tự động phát hiện từ framework.
lint.ignorestring[]["node_modules", ...]Các mẫu glob để loại trừ khỏi lint.
lint.minLengthnumber2Độ dài chuỗi tối thiểu để gắn cờ là hardcoded (được mã hóa cứng).
seo.urlPatternstring"/:locale/:path"Mẫu URL (URL pattern template) để tạo thẻ hreflang.
seo.pagesstring[]nullDanh sách trang rõ ràng cho SEO. null = tự động phát hiện từ các khóa locale.
typegen.outputstringnullĐường dẫn đầu ra cho các kiểu TypeScript được tạo. null = bị vô hiệu hóa.
typegen.autoGeneratebooleanfalseTự động tạo lại các kiểu sau mỗi lần đồng bộ.

Cấu hình cặp ngôn ngữ

Mỗi cặp nguồn→đích có thể được cấu hình độc lập:

{
"pairs": {
"en:fr": {
"method": "google-translate",
"qualityTier": "high"
},
"en:ja": {
"method": "llm",
"model": "google/gemini-2.5-pro"
},
"en:crk": {
"methodPlugin": "crk-coached-v1"
}
}
}

Các trường của cặp ngôn ngữ

TrườngKiểuMô tả
methodstringPhương thức dịch: llm, llm-coached, google-translate, deepl, microsoft-translator, libretranslate, openai, anthropic, gemini, api
methodPluginstringTên của một plugin đã cài đặt (từ .rosetta/methods/)
modelstringGhi đè mô hình mặc định cho cặp này
endpointstringURL endpoint của API từ xa. Bắt buộc khi methodapi.
qualityTierstringBậc hiển thị (Display tier): standard, high, research, verified

Cấu hình ngôn ngữ

Ngôn ngữ chấp nhận ba định dạng:

Mảng các mã (đơn giản nhất)

{
"languages": ["fr", "de", "ja"]
}

Mỗi ngôn ngữ nhận register (văn phong) mặc định từ bảng register tích hợp. Các ngôn ngữ không có mặc định sẽ nhận "Professional register.".

Đối tượng với các chuỗi register

Giá trị có thể là một khóa cài đặt sẵn (preset key) từ thẻ ngôn ngữ, hoặc văn bản register tùy chỉnh:

{
"languages": {
"fr": "casual-tu",
"ko": "formal-hapsyo",
"ja": "Custom: Polite Japanese for a gaming app."
}
}

Rosetta sẽ kiểm tra xem chuỗi có khớp với một khóa cài đặt sẵn trong thẻ ngôn ngữ hay không. Nếu có, toàn bộ prompt register từ thẻ sẽ được sử dụng. Nếu không, chuỗi sẽ được sử dụng nguyên bản. Xem Ngôn ngữ được hỗ trợ để biết các cài đặt sẵn hiện có.

Đối tượng với cấu hình đầy đủ

{
"languages": {
"crk": {
"name": "Plains Cree",
"register": "SRO syllabics with grammatical precision.",
"model": "google/gemini-2.5-pro",
"batchSize": 5,
"maxRetries": 5,
"script": "cans"
}
}
}

Bạn có thể kết hợp các đối tượng viết tắt và đầy đủ trong cùng một khối.

Các trường ngôn ngữ

TrườngKiểuMô tả
registerstringHướng dẫn về phong cách/giọng văn. Có thể là một khóa cài đặt sẵn (ví dụ: casual-tu, formal-hapsyo) hoặc văn bản tùy chỉnh. Xem Thẻ ngôn ngữ.
namestringTên ngôn ngữ dễ đọc (để hiển thị trạng thái)
modelstringGhi đè mô hình mặc định
batchSizenumberGhi đè kích thước lô (batch size) mặc định
maxRetriesnumberNgân sách thử lại tối đa cho các lô bị lỗi (mặc định: 3)
scriptstringMã chữ viết ISO 15924. Kích hoạt xác thực chữ viết trong cổng chất lượng (quality gate).

:::info Chuỗi kế thừa Các cài đặt được phân giải theo thứ tự sau (ưu tiên cái đầu tiên):

cấp độ cặp ngôn ngữ (pair-level)cấp độ ngôn ngữ (language-level)cấu hình toàn cục (global config)mặc định (defaults)

Ví dụ: nếu pairs["en:fr"] thiết lập model, nó sẽ ghi đè cả giá trị model ở cấp độ ngôn ngữ và toàn cục. :::

Nguồn không phải tiếng Anh

Nếu ngôn ngữ nguồn của bạn không phải là tiếng Anh:

# CLI flag (one-time)
npx i18n-rosetta sync --source fr
i18n-rosetta.config.json (permanent)
{
"inputLocale": "fr"
}

Tệp Lock

Rosetta tạo .i18n-rosetta.lock để theo dõi mã băm SHA-256 của các giá trị nguồn đã dịch. Hãy commit tệp này để tất cả các nhà phát triển cùng chia sẻ chung một cơ sở bản dịch.

Khi một giá trị nguồn thay đổi, mã băm sẽ không còn khớp nữa, và rosetta sẽ dịch lại khóa đó trong lần đồng bộ tiếp theo.

.rosettaignore

Tạo .rosettaignore trong thư mục gốc của dự án để loại trừ các tệp khỏi quá trình quét lint. Sử dụng các mẫu glob, giống như .gitignore:

.rosettaignore
src/components/legacy/**
src/utils/constants.js
**/*.test.js

Thư mục .rosetta/

Rosetta tạo một thư mục .rosetta/ trong thư mục gốc của dự án cho trạng thái nội bộ. Nhìn chung, bạn nên thêm thư mục này vào .gitignore — đây là tối ưu hóa cục bộ, không phải mã nguồn dự án:

.rosetta/
TệpMục đíchCommit?
tm.jsonBộ nhớ cache Translation Memory — lưu trữ các bản dịch trước đó được khóa bằng văn bản nguồn + locale + phương thứcKhông (cache cục bộ)
xliff/*.xliffCác tệp xuất XLIFF để dịch giả chuyên nghiệp đánh giáKhông (tạm thời)
methods/Các manifest của plugin phương thức đã cài đặtCó (cấu hình dùng chung)
backups/Các bản sao lưu trước khi bọc (được tạo bởi wrap --undo)Không (mạng lưới an toàn)

Xem Translation Memory để biết chi tiết về tm.json và cách nó tiết kiệm chi phí API.


API lập trình

Đối với các tập lệnh build và tích hợp tùy chỉnh, hãy import trực tiếp từ package:

import { GeminiMethod, runSync, resolveConfig } from 'i18n-rosetta';

// Use a method class directly
const gemini = new GeminiMethod();
const result = await gemini.translate(
['greeting', 'farewell'],
{ greeting: 'Hello', farewell: 'Goodbye' },
{ target: 'fr', name: 'French', register: 'formal', model: 'gemini-2.5-flash' },
{ cwd: process.cwd() }
);
// result = { greeting: 'Bonjour', farewell: 'Au revoir' }

Các Export có sẵn

ExportChức năng
TranslationMethodLớp cơ sở cho tất cả các phương thức
LLMMethodLớp cơ sở cho các phương thức LLM (OpenRouter)
DirectLLMMethodLớp cơ sở cho các nhà cung cấp LLM trực tiếp (OpenAI, Anthropic, Gemini)
OpenAIMethod, AnthropicMethod, GeminiMethodCác lớp nhà cung cấp LLM trực tiếp
DeepLMethod, MicrosoftTranslatorMethod, LibreTranslateMethodCác lớp MT (Dịch máy) truyền thống
GoogleTranslateMethodGoogle Cloud Translation
LLMCoachedMethodLLM được huấn luyện (OpenRouter + dữ liệu huấn luyện)
APIMethodClient API từ xa
runSync, runContentSyncPipeline đồng bộ đầy đủ
resolveConfig, resolvePairsPhân giải cấu hình
validateTranslationsCổng chất lượng (Quality gate)
loadCoachingData, findDictionaryMatchesCác tiện ích huấn luyện (Coaching utilities)

Mở rộng nhà cung cấp tùy chỉnh

Kế thừa DirectLLMMethod để thêm một nhà cung cấp LLM mới chỉ trong khoảng 40 dòng:

import { DirectLLMMethod } from 'i18n-rosetta';

class MistralMethod extends DirectLLMMethod {
constructor(options) {
super(options);
this.name = 'mistral';
}
_getApiKeyEnvVar() { return 'MISTRAL_API_KEY'; }
_getApiKeyOptionsKey() { return 'mistralApiKey'; }
_getDefaultModel() { return 'mistral-large-latest'; }
_getProviderLabel() { return 'Mistral'; }

_buildApiRequest({ prompt, systemMessage, apiKey, model, temperature }) {
return {
url: 'https://api.mistral.ai/v1/chat/completions',
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
body: {
model,
messages: [
...(systemMessage ? [{ role: 'system', content: systemMessage }] : []),
{ role: 'user', content: prompt },
],
temperature,
},
};
}

_extractResponseText(json) {
return json.choices?.[0]?.message?.content;
}

// Optional but recommended: provider-specific setup help when translation fails
getSetupHelp() {
if (!process.env.MISTRAL_API_KEY) {
return [
'',
' ┌─ Missing API Key ─────────────────────────────────────────────┐',
' │ Mistral requires an API key from https://console.mistral.ai │',
' │ Run: export MISTRAL_API_KEY=... │',
' └────────────────────────────────────────────────────────────────┘',
];
}
return [' API key is set but translation failed. Check your Mistral dashboard.'];
}
}

Bạn sẽ nhận được các tính năng dịch, huấn luyện, vòng lặp thử lại (retry loops), xác thực mô hình, các bậc chất lượng và hỗ trợ thiết lập hoàn toàn miễn phí. Chỉ có định dạng yêu cầu HTTP là đặc thù của từng nhà cung cấp. Đối với các adapter không phải LLM sử dụng fetch() thô, hãy sử dụng trình trợ giúp fetchWithRetry() dùng chung từ lib/methods/fetch-with-retry.js thay vì tự viết vòng lặp thử lại của riêng bạn.


Xem thêm