yapyak
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseyapyak compiles into the module that renders it. The source string is the key. On save, the yapyak plugin extracts every call, writes an empty stub to each locale file, and fills the stub through a translator when one is configured.
t('Save changes')t()Read the reference for the project's framework before writing setup or component code:
| Framework | Reference |
|---|---|
| React with Vite | references/react.md |
| React Router | references/react-router.md |
| TanStack Start | references/tanstack-start.md |
| Vue with Vite | references/vue.md |
| Nuxt | references/nuxt.md |
| Svelte with Vite | references/svelte.md |
| SvelteKit | references/sveltekit.md |
| Astro | references/astro.md |
Every diagnostic, its cause, and its fix: references/diagnostics.md
YAPnnnnyapyak 会将 编译到渲染它的模块中。源字符串就是键。保存时,yapyak 插件会提取所有 调用,在每个 locale 文件中写入空桩,并在配置了翻译器时通过翻译器填充该桩。
t('Save changes')t()在编写配置或组件代码前,请阅读项目所用框架的参考文档:
| 框架 | 参考文档 |
|---|---|
| 使用 Vite 的 React | references/react.md |
| React Router | references/react-router.md |
| TanStack Start | references/tanstack-start.md |
| 使用 Vite 的 Vue | references/vue.md |
| Nuxt | references/nuxt.md |
| 使用 Vite 的 Svelte | references/svelte.md |
| SvelteKit | references/sveltekit.md |
| Astro | references/astro.md |
所有 诊断、原因和修复方法:references/diagnostics.md
YAPnnnnInstall
安装
Requirements: Node.js 22.22+, Vite 8+. Frameworks: React 19+, Vue 3.4+, Svelte 5+, Astro 7+, Nuxt 4.1+, React Router 7.9+, SvelteKit 3+, TanStack Start 1.168+.
| Framework | Install | Build config | Processor |
|---|---|---|---|
| React | | | |
| React Router | add | | |
| TanStack Start | add | | |
| Vue | | | |
| Nuxt | | | |
| Svelte | | | |
| SvelteKit | add | | |
| Astro | | | |
Steps, in order:
- Install the packages. Add a translator package when the project translates with a model: ,
@yapyak/anthropic,@yapyak/openai,@yapyak/gemini, or@yapyak/ollama.@yapyak/claude-code - Register the plugin in the build config, after the framework plugin. is a named export of
yapyak.@yapyak/vite - Create at the project root with the processor for the framework:
yapyak.config.ts
ts
import { defineConfig } from 'yapyak/config';
import { react } from '@yapyak/react/processor';
export default defineConfig({
processors: [react()]
});- Add and
.yapyak/types.d.tstoyapyak.config.tsininclude. Nuxt adds the types on its own.tsconfig.json - Add the first target locale: . This creates
npx yapyak add svand regenerates thelocales/sv.jsontype.Locale - Add to
.yapyak/. It holds the orphan cache; the locale files are the committed source of truth..gitignore
Register one processor per framework in the project. The built-in parser reads , , , , , , , and without one.
.ts.tsx.js.jsx.mts.mjs.cts.cjs要求:Node.js 22.22+、Vite 8+。框架:React 19+、Vue 3.4+、Svelte 5+、Astro 7+、Nuxt 4.1+、React Router 7.9+、SvelteKit 3+、TanStack Start 1.168+。
| 框架 | 安装 | 构建配置 | 处理器 |
|---|---|---|---|
| React | | | |
| React Router | 添加 | | |
| TanStack Start | 添加 | | |
| Vue | | | |
| Nuxt | | | |
| Svelte | | | |
| SvelteKit | 添加 | | |
| Astro | | | |
按顺序执行以下步骤:
- 安装软件包。如果项目使用模型进行翻译,请添加翻译器软件包:、
@yapyak/anthropic、@yapyak/openai、@yapyak/gemini或@yapyak/ollama。@yapyak/claude-code - 在构建配置中注册插件,并将其放在框架插件之后。是
yapyak的具名导出。@yapyak/vite - 在项目根目录创建 ,并为框架设置处理器:
yapyak.config.ts
ts
import { defineConfig } from 'yapyak/config';
import { react } from '@yapyak/react/processor';
export default defineConfig({
processors: [react()]
});- 在 的
tsconfig.json中添加include和.yapyak/types.d.ts。Nuxt 会自动添加这些类型。yapyak.config.ts - 添加第一个目标 locale:。这会创建
npx yapyak add sv并重新生成locales/sv.json类型。Locale - 将 添加到
.yapyak/。该目录保存孤儿缓存;locale 文件才是应提交到版本控制的事实来源。.gitignore
在项目中为每个框架注册一个处理器。内置解析器无需处理器即可读取 、、、、、、 和 。
.ts.tsx.js.jsx.mts.mjs.cts.cjsWriting text
编写文本
Wrap every user-facing string in from . Write the sentence in the source language exactly as the reader sees it; it is the key.
t()yapyakts
// ✓ The sentence is the key
t('Save changes');
// ✗ A synthetic key has no source string to translate
t('common.buttons.save');Call inside the component or function that renders the text. A module-scope call evaluates once and never follows the active locale ().
t()YAP0055ts
// ✓ Reads the active locale on every render
function SaveButton() {
return t('Save changes');
}
// ✗ Evaluates once when the module loads
const label = t('Save changes');Write the source as a static string literal and the params as an inline object literal. The compiler reads neither from a variable.
ts
// ✓ Static source, inline params
t('Hi {name}', { name });
// ✗ Template literal (YAP0002)
t(`Hi ${name}`);
// ✗ Variable source
t(label);
// ✗ Params in a variable (YAP0006)
t('Hi {name}', params);Never concatenate around → put the moving part in a placeholder.
t()ts
// ✓ One message, one placeholder
t('{count} items in your cart', { count });
// ✗ Word order differs per language
t('You have') + ' ' + count + ' ' + t('items');Call in attribute positions too: , , . The attribute name is part of the call-site context the translator receives.
t()aria-label={t('Pause')}:title="t('Settings')"placeholder={t('Search')}使用 中的 包裹所有面向用户的字符串。请按照读者看到的样子,在源语言中准确书写该句子;它就是键。
yapyakt()ts
// ✓ The sentence is the key
t('Save changes');
// ✗ A synthetic key has no source string to translate
t('common.buttons.save');请在渲染文本的组件或函数内部调用 。模块作用域中的调用只求值一次,且不会跟随当前 locale 变化()。
t()YAP0055ts
// ✓ Reads the active locale on every render
function SaveButton() {
return t('Save changes');
}
// ✗ Evaluates once when the module loads
const label = t('Save changes');源文本必须写成静态字符串字面量,参数必须写成内联对象字面量。编译器无法从变量中读取这两者。
ts
// ✓ Static source, inline params
t('Hi {name}', { name });
// ✗ Template literal (YAP0002)
t(`Hi ${name}`);
// ✗ Variable source
t(label);
// ✗ Params in a variable (YAP0006)
t('Hi {name}', params);切勿在 周围拼接字符串 → 请将变化的部分放入占位符。
t()ts
// ✓ One message, one placeholder
t('{count} items in your cart', { count });
// ✗ Word order differs per language
t('You have') + ' ' + count + ' ' + t('items');属性位置也应调用 :、、。属性名也是翻译器接收到的调用位置上下文的一部分。
t()aria-label={t('Pause')}:title="t('Settings')"placeholder={t('Search')}Placeholders
占位符
Write in the source and pass the value under the same name. TypeScript derives the required keys from the source string.
{name}| Form | Example | Value type |
|---|---|---|
| Plain | | |
| Number | | |
| Date | | |
| Time | | |
| Plural | | |
| Ordinal | | |
| Select | | |
Name a placeholder with letters, digits, and underscores, starting with a letter or underscore (). Non-ASCII letters are allowed.
YAP0052Rules for , , and :
pluralselectordinalselect- Write an branch (
other).YAP0008 - Write inside a plural branch for the formatted count.
# - Write ,
=0for an exact value; exact matches are tried before categories.=1 - Name plural branches with the CLDR keywords ,
zero,one,two,few,many(other).YAP0046 - Write only the branches the source language uses, and
onefor English; the translator adds the branches each target locale needs.other - Nest freely: a branch is a full message and holds placeholders, plurals, and selects.
- Split a message that has become unreadable into two calls and let the component pick.
t() - Type a value as a union literal so every legal value has a branch.
select
Format a list with outside the message and pass the result in as a placeholder. Format relative time with outside the message.
format.list()format.relativeTime()在源文本中写入 ,并使用同名参数传入值。TypeScript 会从源字符串推导出必需的键。
{name}| 形式 | 示例 | 值类型 |
|---|---|---|
| 普通 | | |
| 数字 | | |
| 日期 | | |
| 时间 | | |
| 复数 | | |
| 序数 | | |
| 选择 | | |
占位符名称可包含字母、数字和下划线,且必须以字母或下划线开头()。允许使用非 ASCII 字母。
YAP0052pluralselectordinalselect- 必须编写 分支(
other)。YAP0008 - 在复数分支中使用 表示格式化后的计数。
# - 使用 、
=0表示精确值;系统会先尝试精确匹配,再尝试类别匹配。=1 - 复数分支必须使用 CLDR 关键词 、
zero、one、two、few、many(other)。YAP0046 - 仅编写源语言使用的分支;英语只需 和
one,翻译器会为每个目标 locale 添加所需的分支。other - 可以自由嵌套;一个分支是一条完整消息,可以包含占位符、复数和 select。
- 如果一条消息变得难以阅读,请将其拆成两个 调用,再由组件选择使用哪一条。
t() - 将 select 值声明为联合字面量类型,确保每个合法值都有对应分支。
请在消息外部使用 格式化列表,再将结果作为占位符传入。相对时间也应使用 在消息外部格式化。
format.list()format.relativeTime()Homonyms
同源异义
Split two calls with the same source and different meanings with :
t.as(context, source)ts
t.as('action', 'Open');
t.as('status', 'Open');- Write the context as a short literal label (,
action,status,noun), never a variable (verb).YAP0017 - Use for every occurrence of that source in the source file. Mixing
t.as()andt('Open')in one file is an error (t.as('action', 'Open')).YAP0018 - Use plain when the source has one meaning. A lone context is an error (
t()).YAP0019
如果同一源字符串对应不同含义,请使用 区分两次调用:
t.as(context, source)ts
t.as('action', 'Open');
t.as('status', 'Open');- 上下文必须写成简短的字面量标签(、
action、status、noun),不能使用变量(verb)。YAP0017 - 源文件中的每次该源字符串调用都要使用 。在同一文件中混用
t.as()和t('Open')会报错(t.as('action', 'Open'))。YAP0018 - 当源字符串只有一种含义时,使用普通的 。仅使用上下文会报错(
t())。YAP0019
Forced locale
强制 locale
- Write for the translation in a forced locale regardless of the active one. The locale argument is typed against
t.in(locale, source).Locale - Chain or
t.in('sv').as('action', 'Open')when both apply.t.as('action').in('sv', 'Open') - Complete the chain in one expression. A chain stored in a variable is an error ().
YAP0020
- 使用 获取指定 locale 的翻译,而不考虑当前 locale。locale 参数的类型限定为
t.in(locale, source)。Locale - 当两种行为同时适用时,可以链接调用 或
t.in('sv').as('action', 'Open')。t.as('action').in('sv', 'Open') - 必须在一个表达式中完成整个链式调用。将链式调用存储到变量中会报错()。
YAP0020
Rich text
富文本
Write tags inside the source and bind each tag to a handler in from the framework's adapter package.
<RichText>ts
t('Read our <link>privacy policy</link> for details.');
t('Line one<br/>line two');| Tag | Form | Handler |
|---|---|---|
| Pair | | Receives the wrapped children |
| Void | | Receives nothing |
- Start a tag name with a letter and continue with letters or digits.
- Name a tag by meaning (,
link,strong), never by HTML element; the element belongs in the handler.price - Bind a handler for every tag in the source.
- Never write attributes on a tag → put the in the handler.
href - Walk the structure with from
parseRichText(value), which returnsyapyak, whenRichTextNode[]does not fit.<RichText>
Take the handler shape from the framework's reference file.
在源文本中写入标签,并通过框架适配器包中的 为每个标签绑定处理器。
<RichText>ts
t('Read our <link>privacy policy</link> for details.');
t('Line one<br/>line two');| 标签 | 形式 | 处理器 |
|---|---|---|
| 成对标签 | | 接收被包裹的子节点 |
| 空元素标签 | | 不接收内容 |
- 标签名必须以字母开头,后续只能包含字母或数字。
- 按含义命名标签(、
link、strong),不要按 HTML 元素命名;具体元素应由处理器决定。price - 源文本中的每个标签都必须绑定处理器。
- 切勿在标签上编写属性 → 请将 等内容放入处理器。
href - 如果 不适合当前场景,可以使用
<RichText>中的yapyak遍历结构,该函数返回parseRichText(value)。RichTextNode[]
请根据框架参考文件确定处理器结构。
Formatting outside messages
消息外格式化
Format values outside a message with from . Every call reads the active locale.
formatyapyak| Method | Backed by | Note |
|---|---|---|
| | |
| | |
| | Run each item through |
| | Negative is past; |
| | |
| Returns a |
- Use for a value outside a message and an ICU sub-format for a value inside one.
format.* - Type a currency code as from
Currency; narrow user input withyapyak.isCurrency(value) - Label a locale switcher with , never with a
format.in(value).displayName(value, 'language')call per language.t() - An unsupported currency, unit, time zone, or display-name code renders a fallback instead of throwing and reports ,
YAP0035,YAP0036, orYAP0037.YAP0056
使用 中的 在消息外部格式化值。每次调用都会读取当前 locale。
yapyakformat| 方法 | 底层实现 | 说明 |
|---|---|---|
| | |
| | 支持 |
| | 先将每个条目传入 |
| | 负数表示过去; |
| | |
| 返回限定到强制 locale 的 |
- 消息外部的值使用 ,消息内部的值使用 ICU 子格式。
format.* - 使用 中的
yapyak类型约束货币代码;使用Currency收窄用户输入。isCurrency(value) - 使用 为 locale 切换器添加标签,不要为每种语言分别调用
format.in(value).displayName(value, 'language')。t() - 不支持的货币、单位、时区或显示名称代码不会抛出异常,而是渲染回退内容,并报告 、
YAP0035、YAP0036或YAP0037。YAP0056
The active locale
当前 locale
A locale is the BCP 47 tag of a file in : for , for . Write tags as (). The type is the union of the files on disk and refreshes on .
localesDirsvlocales/sv.jsonen-GBlocales/en-GB.jsonlowercase-Titlecase-UPPERCASEzh-Hant-TWLocaleyapyak addThe active locale resolves in this order, first value wins: a persisted choice, a detected locale when is on, then .
detectUserLocaledefaultLocaleExport from | Use |
|---|---|
| The active locale, outside components |
| Switch and persist; ignored with a warning for an unknown value ( |
| Every added locale, for a switcher |
| The locale when no persisted or detected locale matches |
| Type guard for a canonical string |
| Normalizes casing, returns |
| |
| |
Read and switch the locale inside a component through the framework binding; never call or there.
getLocale()setLocale()| Framework | Binding |
|---|---|
| React | |
| Vue, Nuxt | |
| Svelte, SvelteKit | |
| Astro | |
Narrow a string from a URL, a form, or a cookie with or before .
isLocale()parseLocale()setLocale()locale 是 中某个文件的 BCP 47 标签,例如 对应 , 对应 。标签应写成 形式()。 类型是磁盘上所有 locale 文件的联合类型,并在执行 时刷新。
localesDirlocales/sv.jsonsvlocales/en-GB.jsonen-GBlowercase-Titlecase-UPPERCASEzh-Hant-TWLocaleyapyak add当前 locale 按以下顺序解析,第一个匹配值生效:已持久化的选择、启用 时检测到的 locale,最后是 。
detectUserLocaledefaultLocale从 | 用途 |
|---|---|
| 在组件外部获取当前 locale |
| 切换并持久化 locale;传入未知值时会忽略并发出警告( |
| 获取所有已添加的 locale,用于构建切换器 |
| 当持久化或检测到的 locale 均不匹配时使用的 locale |
| 判断字符串是否为规范形式的类型守卫 |
| 规范化大小写,返回 |
| 返回 |
| 返回 |
请通过框架绑定在组件内部读取和切换 locale;切勿在其中调用 或 。
getLocale()setLocale()| 框架 | 绑定方式 |
|---|---|
| React | |
| Vue、Nuxt | |
| Svelte、SvelteKit | |
| Astro | 在 frontmatter 中使用 |
对来自 URL、表单或 cookie 的字符串,请先使用 或 收窄类型,再调用 。
isLocale()parseLocale()setLocale()yapyak.config.ts
yapyak.config.tsyapyak.config.ts
yapyak.config.tsEvery field is optional. Export the result of from .
defineConfigyapyak/config| Field | Default | Sets |
|---|---|---|
| | The language the source strings are written in. Set it only when it differs from |
| | The locale when no persisted or detected locale matches |
| | The directory of locale files, relative to the project root |
| | Directories, globs, or |
| tests, | Files to skip; replaces the default. Extend with |
| | One per framework |
| none | The translator that fills stubs |
| | New strings in one save above which the save loop writes stubs but skips the translator. |
| | Keep the translation when a source string is edited in place |
| | Where the active locale is stored between page loads |
| | Match |
| | Keep |
| Processor | Option | Use |
|---|---|---|
| | React Server Components: only |
| | Another global |
| none |
每个字段都是可选的。请从 导出 的结果。
yapyak/configdefineConfig| 字段 | 默认值 | 作用 |
|---|---|---|
| | 编写源字符串所使用的语言。仅当它与 |
| | 当持久化或检测到的 locale 均不匹配时使用的 locale |
| | 相对于项目根目录的 locale 文件目录 |
| | 要扫描的目录、glob 或 |
| tests、 | 要跳过的文件;会替换默认配置。可通过 |
| | 每个框架配置一个处理器 |
| 无 | 用于填充桩的翻译器 |
| | 单次保存新增的字符串超过此值时,保存循环会写入桩但跳过翻译器。 |
| 未配置翻译器时为 | 原地编辑源字符串时是否保留翻译 |
| | 页面加载之间当前 locale 的存储位置 |
| | 首次访问时,在服务器端匹配 |
| | 每次变化时,使 |
| 处理器 | 选项 | 用途 |
|---|---|---|
| | React Server Components:只有 |
| | 项目中已存在另一个全局 |
| 无 |
Persistence
持久化
| Value | Options | Fits |
|---|---|---|
| Kiosk, development build, locale carried by another system. A reload returns to | |
| | SSR apps. The adapter reads the cookie per request; |
| | Client-only apps. Under SSR the first render uses |
| | Locale in the path ( |
- Under , switch by navigating.
'url'is a no-op and reportssetLocale().YAP0026 - Set on the cookie in production only; on plain HTTP the browser refuses the write.
secure: true
| 值 | 选项 | 适用场景 |
|---|---|---|
| 信息亭、开发构建,或 locale 由其他系统携带。重新加载后会回到 | |
| | SSR 应用。适配器会按请求读取 cookie;在服务器端调用 |
| | 仅客户端应用。在 SSR 下,首次渲染使用 |
| | locale 位于路径( |
- 在 模式下,通过导航切换 locale。
'url'不执行任何操作,并报告setLocale()。YAP0026 - 仅在生产环境中将 cookie 的 设置为
secure;通过纯 HTTP 访问时,浏览器会拒绝写入。true
Fixed-locale builds
固定 locale 构建
- Set in the build config, never in
fixedLocale. Everyyapyak.config.tscompiles to the literal of that locale and the runtime disappears from the bundle.t() - Drive a CI matrix from an environment variable. With the variable unset, the build is a normal multi-locale build.
- Pass an added locale; the build throws otherwise.
| Framework | Where |
|---|---|
| Vite (React, Vue, Svelte, React Router, SvelteKit, TanStack Start) | |
| Astro | |
| Nuxt | |
- 在构建配置中设置 ,不要在
fixedLocale中设置。每个yapyak.config.ts都会编译为该 locale 的字面量,运行时也会从 bundle 中移除。t() - 通过环境变量驱动 CI 矩阵。未设置该变量时,构建仍会生成常规的多 locale 版本。
- 必须传入已添加的 locale,否则构建会抛出异常。
| 框架 | 配置位置 |
|---|---|
| Vite(React、Vue、Svelte、React Router、SvelteKit、TanStack Start) | 在 |
| Astro | 在 |
| Nuxt | 在 |
Locale files
Locale 文件
One JSON file per target locale in . The source language has no file. Entries nest under the source file's path, then the source string:
localesDirjson
{
"src/components/save-button.tsx": {
"Save changes": "Spara ändringar"
}
}A homonym nests its contexts under the source:
json
{
"src/components/dialog.tsx": {
"Open": {
"action": "Öppna",
"status": "Öppen"
}
}
}- An empty string is an empty stub. The runtime renders the source string for it.
- Hand-edit a value to correct or replace a translation. The running app updates through HMR.
- Keep every placeholder, tag, and ICU structure of the source in the translation (,
YAP0010,YAP0011,YAP0012,YAP0038,YAP0045,YAP0050). Placeholder names stay fixed; their position in the sentence is free.YAP0051 - Never edit a key → change the source string in the component; the compiler rewrites the key.
- Never add an entry by hand → write the call; the save loop or
t()creates the stub.yapyak translate - Renames and moves of source files restore translations from the orphan cache in on the next save. Deleting
.yapyak/orphans.jsonloses nothing committed..yapyak/ - Orphans stay in the locale file until removes them.
yapyak clean --write
Fill empty stubs by hand only when the project has no translator or the user asks for it.
在 中为每个目标 locale 创建一个 JSON 文件。源语言没有对应文件。条目先按源文件路径嵌套,再按源字符串嵌套:
localesDirjson
{
"src/components/save-button.tsx": {
"Save changes": "Spara ändringar"
}
}同源异义会将不同上下文嵌套在源字符串下:
json
{
"src/components/dialog.tsx": {
"Open": {
"action": "Öppna",
"status": "Öppen"
}
}
}- 空字符串表示空桩,运行时会为其渲染源字符串。
- 可以手动编辑某个值来修正或替换翻译,运行中的应用会通过 HMR 更新。
- 翻译必须保留源文本中的所有占位符、标签和 ICU 结构(、
YAP0010、YAP0011、YAP0012、YAP0038、YAP0045、YAP0050)。占位符名称必须保持不变,但可以在句子中调整位置。YAP0051 - 切勿编辑键 → 请修改组件中的源字符串,编译器会重写键。
- 切勿手动添加条目 → 请编写 调用,保存循环或
t()会创建桩。yapyak translate - 重命名或移动源文件后,下次保存时会从 中的孤儿缓存恢复翻译。删除
.yapyak/orphans.json不会丢失任何已提交的内容。.yapyak/ - 孤儿条目会保留在 locale 文件中,直到执行 将其移除。
yapyak clean --write
仅当项目没有翻译器或用户明确要求时,才手动填充空桩。
Translators
翻译器
A translator fills empty stubs on save and in . Requests go from the developer's machine to the provider. Set one in :
yapyak translateyapyak.config.tsts
import { defineConfig } from 'yapyak/config';
import { anthropic } from '@yapyak/anthropic';
export default defineConfig({
translator: anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
glossary: { cart: { sv: 'kundvagn' } },
voice: 'Concise and friendly'
})
});| Package | Factory | Key | Defaults that differ |
|---|---|---|---|
| | | |
| | | Extras |
| | | |
| | none | |
| | the signed-in | |
| Shared option | Default | Sets |
|---|---|---|
| per provider | Model identifier |
| none | One or two sentences of tone guidance |
| | |
| | |
| | Existing translations sent per request as style reference |
| | Sampling temperature |
| per provider | Output token cap |
| | Per-request timeout in milliseconds |
| | Retries on 408, 429, 5xx, and network failures |
| | Source strings per request |
| | Parallel requests |
| | Extra HTTP headers |
| per provider | API URL |
- The context is sent at every
t.as()level.context - A voice or glossary change affects new translations only. Run or
yapyak translate --forceto propagate it.yapyak retranslate "<source>" - Pick the translator by environment when CI has no signed-in CLI: .
process.env.CI ? anthropic({ apiKey: process.env.ANTHROPIC_API_KEY }) : claudeCode()
A custom translator is from :
createTranslator({ id, translate })yapyak/translator- returns one object per item, in item order, keyed by every target locale.
translate({ items, signal, sourceLocale, targetLocales }) - Forward to the request.
signal - Throw ,
TranslatorAuthError,TranslatorRateLimitError,TranslatorTimeoutError,TranslatorNetworkError,TranslatorSafetyError, orTranslatorInvalidResponseErrorfromTranslatorTruncatedError.yapyak/translator - Retry inside the callback. yapyak runs it once.
翻译器会在保存时和执行 时填充空桩。请求会从开发者机器发送到提供商。在 中设置翻译器:
yapyak translateyapyak.config.tsts
import { defineConfig } from 'yapyak/config';
import { anthropic } from '@yapyak/anthropic';
export default defineConfig({
translator: anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
glossary: { cart: { sv: 'kundvagn' } },
voice: 'Concise and friendly'
})
});| 软件包 | 工厂函数 | 密钥 | 不同的默认值 |
|---|---|---|---|
| | | |
| | | 额外提供 |
| | | |
| | 无 | |
| | 已登录的 | |
| 通用选项 | 默认值 | 作用 |
|---|---|---|
| 由提供商决定 | 模型标识符 |
| 无 | 一到两句语气指导 |
| | |
| | |
| | 每次请求发送的现有翻译,用作风格参考 |
| | 采样温度 |
| 由提供商决定 | 输出 token 上限 |
| | 单次请求超时时间,单位为毫秒 |
| | 遇到 408、429、5xx 和网络故障时重试 |
| | 每次请求中的源字符串数量 |
| | 并行请求数量 |
| | 额外的 HTTP 标头 |
| 由提供商决定 | API URL |
- 无论 级别如何,都会发送
context的上下文。t.as() - 语气或术语表的变更仅影响新翻译。运行 或
yapyak translate --force可传播变更。yapyak retranslate "<source>" - 当 CI 中没有已登录的 CLI 时,可根据环境选择翻译器:。
process.env.CI ? anthropic({ apiKey: process.env.ANTHROPIC_API_KEY }) : claudeCode()
自定义翻译器使用 中的 :
yapyak/translatorcreateTranslator({ id, translate })- 需按项目顺序为每个条目返回一个对象,并以每个目标 locale 为键。
translate({ items, signal, sourceLocale, targetLocales }) - 将 传递给请求。
signal - 从 抛出
yapyak/translator、TranslatorAuthError、TranslatorRateLimitError、TranslatorTimeoutError、TranslatorNetworkError、TranslatorSafetyError或TranslatorInvalidResponseError。TranslatorTruncatedError - 在回调内部重试,yapyak 只会调用该回调一次。
CLI
CLI
Run through the package manager: , , . Every command except walks the source files first, so a call added without the dev server running is still found.
npx yapyak <command>pnpm yapyak <command>bunx yapyak <command>infot()| Command | Does | Exit code |
|---|---|---|
| Creates the locale file, fills it through the translator, regenerates the | non-zero on an unrecognized tag |
| Fills empty stubs. | |
| Re-translates one source string; the flags compose | |
| Coverage per locale | |
| Missing translations, compile-time diagnostics, ICU mismatches | |
| Lists orphans; | |
| Snapshot keyed by locale, then path, then source | non-zero on an unknown tag |
| Versions for a bug report | |
Boolean flags accept : . and strip color.
=--write=falseNO_COLORCICI order: with the provider key in the environment, then , then the build. never calls the translator.
yapyak translateyapyak checkcheck通过包管理器运行:、、。除 外的每个命令都会先遍历源文件,因此即使未运行开发服务器,也能找到新增的 调用。
npx yapyak <command>pnpm yapyak <command>bunx yapyak <command>infot()| 命令 | 作用 | 退出码 |
|---|---|---|
| 创建 locale 文件,通过翻译器填充内容,并重新生成 | 遇到无法识别的标签时返回非零值 |
| 填充空桩。 | 未配置翻译器时返回 |
| 重新翻译一条源字符串;各参数可组合使用 | 没有匹配项时返回 |
| 显示各 locale 的覆盖率 | 缺少翻译时返回 |
| 检查缺失的翻译、编译时诊断和 ICU 不匹配 | 发现任何问题时返回 |
| 列出孤儿条目; | |
| 导出快照,依次按 locale、路径和源字符串作为键 | 遇到未知标签时返回非零值 |
| 输出用于问题报告的版本信息 | |
布尔参数支持使用 :例如 。 和 会禁用颜色输出。
=--write=falseNO_COLORCICI 中的执行顺序:先运行 并在环境中提供提供商密钥,然后运行 ,最后执行构建。 不会调用翻译器。
yapyak translateyapyak checkcheckWorking in a project
在项目中工作
- Write the call in the component. With the dev server running, the save writes the stub and the translator fills it. Without it, the CLI finds the call.
t() - Run before finishing. Fix every reported
npx yapyak checkwith references/diagnostics.md.YAPnnnn - Run when
npx yapyak translatereports missing translations and the project has a translator. Fill the stubs by hand when it has none.check - Commit the locale files with the code. They are the source of truth; is a cache.
.yapyak/ - Run after removing components, and
npx yapyak cleanonce the list is right.--write
Diagnostics an agent most often triggers:
| Code | Cause | Fix |
|---|---|---|
| Template literal source | |
| Params do not match the placeholders | Match the keys to the |
| Params in a variable | Inline object literal |
| No | Add |
| | |
| Chain stored in a variable | Complete |
| Branch name is not a CLDR keyword | |
| | Move the call into the function that renders it |
| | Register the SSR adapter from the framework reference |
- 在组件中编写 调用。开发服务器正在运行时,保存操作会写入桩,并由翻译器填充;开发服务器未运行时,CLI 会找到该调用。
t() - 完成前运行 。根据 references/diagnostics.md 修复所有报告的
npx yapyak check问题。YAPnnnn - 当 报告缺少翻译且项目配置了翻译器时,运行
check;没有翻译器时,请手动填充桩。npx yapyak translate - 将 locale 文件与代码一起提交。locale 文件是事实来源,只是缓存。
.yapyak/ - 删除组件后运行 ,确认列表无误后再执行
npx yapyak clean。--write
Agent 最常触发的诊断:
| 代码 | 原因 | 修复方法 |
|---|---|---|
| 源文本使用模板字符串 | |
| 参数与占位符不匹配 | 使键与源文本中的 |
| 参数位于变量中 | 改用内联对象字面量 |
| 缺少 | 添加 |
| 同一文件中的同一源文本同时使用 | 每次出现都使用 |
| 链式调用存储在变量中 | 内联完成 |
| 分支名称不是 CLDR 关键词 | 使用 |
| 在模块作用域中调用 | 将调用移入渲染文本的函数中 |
| 服务器端调用 | 根据框架参考文档注册 SSR 适配器 |