これが走るパイプラインです www。conveythis。com それ自体 — 238 ページの Astro サイト、55 か国語で運営されています。私たちはそれを抽出し、見つけるのにかかったすべての障害モードを文書化し、すべてを公開しました。これはトライアルでもティーザーでもありません。購入するキーも割り当てもアカウントもありません。
Two design decisions
仕組み
2 つの決定がそれを定義します。まず、翻訳はバイト オフセットによって構築された HTML にスプライシングされ、ドキュメントは DOM — から再シリアル化されないため、重要な CSS、LCP 要素、アセット ハッシュ、および がインライン化されます width/height CLS を保持する属性はすべてそのまま引き継がれます。それは なぜ ロケール ページは、Core Web Vitals 上のソース言語に単に似ているのではなく、ソース言語と一致します。第二に、翻訳の単位はテキスト ノードではなくブロック全体です。これは、一般的なサイトのテキスト ノードの約 5 分の 1 がインライン マークアップによって分割され、フラグメントを個別に翻訳すると、順序を変更したり語形変化したりする言語の文法が壊れるためです。
The result is proved rather than asserted: eight gates and an exhaustive SEO audit over every page, including one gate that exists purely because coverage metrics are structurally blind to extraction bugs.
Verification
実際に成立するのでしょうか?
正当な質問であり、私たちの言葉を鵜呑みにするのではなく、チェック可能です。 doctranslator。com/fr このパイプラインによってフランス語ページが建設された大規模な Astro サイトです。英語のオリジナルと比較してください。マークアップは次のとおりです バイト同一:
2,743
タグは同一の順序で
2,031
クラス属性、すべて一致
+0.74%
ページの重み — フランス語は長いです
構造的に何も移動しないため、ブラウザが別の方法でレイアウトするものは何もありません。自分で確認してください — 約 10 秒かかります:
curl -s https://doctranslator.com/ | grep -o 'class="[^"]*"' > en.txt
curl -s https://doctranslator.com/fr | grep -o 'class="[^"]*"' > fr.txt
diff en.txt fr.txt && echo "markup identical — only the text changed"そしてスコア
| 英語ソース | フランス語、このツールから | A11y / ベストプラクティス / SEO | |
|---|---|---|---|
| デスクトップ | 100 | 100 | 100 / 100 / 100 |
| モバイル | 98 | 98 | 100 / 100 / 100 |
PageSpeed Insights のパフォーマンス スコア。2026 年 8 月 25 日に測定されました。どちらの戦略でも、両方のページを実行するたびにアクセシビリティ、ベスト プラクティス、SEO が 100 でした。
これらは意図的に中央値です。 Lighthouse スコアの動き: 同じ英語のモバイル ページを 5 回連続で実行すると、98、98、88、98、98 が返され、最大のコンテンツを含むペイントは 1。8 秒から 3。2 秒の間で揺れ動きました。これは、ページの品質ではなく、ネットワークと CDN の差異です。1 回測定して 91 を得た場合、— を数回実行し、マーケティング ページの数字ではなく 2 つの言語を相互に比較するのはこのためです。
And the language
Markup identity is measurable. Whether the Spanish is any good is a different question, and until 2.0 the pipeline had no answer to it — the tests checked request shapes and scaffolding, and nothing scored a translation.
node scripts/i18n/tqa.mjs --lang es --dry # sample size and cost, no API call
node scripts/i18n/tqa.mjs --lang es,fr,de # scorecard + per-locale JSON
node scripts/i18n/tqa.mjs --lang es --repeat # judge the same sample twiceIt scores a stratified sample on the MQM error typology at its conventional weights — minor 1, major 5, critical 10 — and weights the sample by how often each string appears, so the header everyone reads counts for more than a one-off footnote. Three things keep the number from being decorative:
- The judge is a different model from the translator
- Models score their own output generously. If no second provider key is configured it uses the same one and says so, in the run and in the report.
- The sample is seeded, and the variance is reported
- A seed reproduces a score exactly;
--repeatscores the same sample twice and prints the gap. A quality number nobody can re-derive, quoted without its noise, is a marketing number. - A unit the judge cannot assess is excluded, not counted as clean
- An early version printed 100.00 out of 100 from a sample where every single unit had failed to parse. It now refuses to report a score at all in that case.
Read it as a comparison — between locales, between models, before and after a prompt change — not as a grade. It is one model’s assessment of another’s work rather than a human review, and the report says so on its face.
Decision three
Terminology is not a per-sentence choice
Identical strings were always consistent — units are keyed by a hash of the source text, so a nav label translated once is reused on every page and across runs. What that cannot do is hold a term inside varying sentences: “Dashboard” in two different paragraphs is two hashes, two batches, two stateless requests, and nothing compared them.
[
{ "source": "Acme", "rule": "keep", "matchCase": true },
{ "source": "Dashboard", "rule": "translate",
"targets": { "es": "Panel de control", "de": "Übersicht" } }
]matchCase is the answer to a question we were asked directly: can it tell Apple the company from apple the fruit? A flat list of names cannot express that. Whole-word, case-sensitive rules can.
| source | spanish | なぜ |
|---|---|---|
| Apple announced a device | Apple anunció un dispositivo | capital A — protected, and now verified |
| An apple a day | Una manzana al día | lowercase — translated normally |
| Applesauce is on sale | La compota está en oferta | whole-word — never matches inside a longer word |
The same release tells the model what a string is. It used to receive the text and nothing else, so a button label and a body paragraph were indistinguishable — which made the prompt’s own instruction to keep button labels short unenforceable. A <button>, a heading, a form label and a meta description now each say so.
It deliberately does not demand the imperative for buttons: German UI prefers a verbal noun and French the infinitive, so it asks for whatever construction that language actually puts on a button. Brand names you already list are folded in automatically as case-sensitive keep rules, which also brings them under a verification gate that checks they survived. Nothing checked that before.
Locale conventions
Numbers get localized. Prices never get converted.
Writing 1,234.56 to a German reader is one of the most visible marks of a machine translation. Models are unreliable at separator conventions, so the model is told to leave numbers alone and Intl reformats them afterwards, deterministically.
| source | becomes | where |
|---|---|---|
| 1,234.56 | 1.234,56 | de |
| 1,234.56 | 1 234,56 | fr |
| $5 | 5,00 $US | fr — placement and spacing, not the amount |
| 50% | 50 % | fr — with a non-breaking space |
It formats. It never converts.
no config option for itA price is a commercial commitment, and converting one at a rate baked into a build — stale the day after it is written — is how a translation tool starts publishing wrong offers in markets nobody is watching. Every monetary amount found is written to a report instead, so a human prices each market deliberately.
A numeric-integrity gate backs that up by failing the build if a number’s value changes between source and translation. A model that quietly ships $39 where the source said $49 passes every other check: identical markup, matching placeholders, plausible length, fluent Spanish.
Deliberately left alone: version numbers, times, IP addresses, ISO dates, phone numbers and any ungrouped number — during development a greedy pattern turned 192.168.1.1 into 1.921.681,1, and that case is now a test. One result that looks like a bug and is not: Spanish does not group four-digit numbers, so 1,234.50 is correctly 1234,50 in es そして 1.234,50 in de.
Honest routing
実際に必要なのはどれですか?
静的置換とランタイム層はさまざまな問題を解決します。間違ったものを選ぶと週末がかかるので、正直な分割は次のとおりです。
静的ビルドがあり、リリースリズムに応じてコンテンツが変更され、HTML を完全に所有する必要があります。
クロード翻訳者
無料、セルフホスト、AGPL-3。0。独自の API キー、独自のファイル、アカウントなし。
GitHubで見る →コンテンツは毎日変更されたり、CMS に保存されたり、ユーザーが生成したり、ログインやチェックアウトの後ろに置かれたりします。
ConveyThis
管理されたランタイム層。フックするためのビルド手順、すべての編集での再実行、ビジュアル エディター、および人間のレビューはありません。
価格設定 → を参照してください翻訳が必要なのは、ページ — PDF、DOCX、XLSX、PPTX ではなくドキュメントです。
ドクトランスレーター
ファイル全体、レイアウト、テーブルが保存され、100+ 言語。
DocTranslator →に移動しますQuickstart
インストールしてください
リポジトリ
https://github.com/ConveyThis/claude-translator
AGPL-3。0 · ノード ≥ 20 · 1つの依存関係(parse5) · GitHubで開く →
必要なのは
- Node。js 20以降
- 静的HTMLで構築されるサイト — ソースではなくビルド出力を読み取ります
- 選択したモデルの API キー — または、ローカルで実行する場合はまったく実行しません
クロード コードのスキルとして
それをスキル ディレクトリにクローンし、Claude にサイトのローカライズを依頼します。これは、— を見つけるために実際にお金を費やす失敗モードや、これが完全に間違ったツールである場合のルールなど、バンドルされた指示に従います。
git clone https://github.com/ConveyThis/claude-translator.git \
~/.claude/skills/claude-translatorどのプロジェクトでも
1 つのコマンド。 init パイプラインをコピーします scripts/i18n/、 configを書き込み、宣言します parse5 そして導出されたものを追加します i18n/ あなたへの道 .gitignore。それなしでは何も上書きしません --force、 そして、タッチしたすべてのファイルを出力します。
cd your-project
npx claude-translator init
npm install # parse5, the only dependencyスクリプトはリポジトリ内に留まるのではなく、リポジトリ内に配置されます node_modules 意図的に — 参加したプロジェクトからのパスを解決し、読み取るのに十分な長さがあり、ライセンスを存在するため、パスを変更できます。
Npxなしでインストールする
git clone https://github.com/ConveyThis/claude-translator.git
cp -r claude-translator/scripts your-project/scripts/i18n
cp claude-translator/i18n.config.example.json your-project/i18n.config.json
cd your-project && npm install --save-dev parse5設定する
実行される最小の構成。 buildDir ジェネレーターが HTML を書き込む場所です baseUrl は正規の起源であり、末尾のスラッシュはありません。
{
"buildDir": "dist",
"baseUrl": "https://example.com",
"provider": "anthropic",
"glossary": "glossary.json",
"locales": [
{ "hreflang": "es", "pathCode": "es", "nativeLabel": "Español" },
{ "hreflang": "de", "pathCode": "de", "nativeLabel": "Deutsch" }
]
}echo "ANTHROPIC_API_KEY=your-key-here" >> .env # and gitignore it実行する
| npm run ビルド | 通常のビルド — ソース言語のみ |
| ノードスクリプト/i18n/extract。mjs | 翻訳可能なすべてのユニットを見つけます |
| ノードスクリプト/i18n/translate。mjs --lang es,fr | 記憶に翻訳する |
| ノードスクリプト/i18n/build-locales。mjs --lang all | ローカライズされたページを書きます |
| ノードスクリプト/i18n/verify。mjs --lang all | eight gates — exits non-zero on failure |
| ノードスクリプト/i18n/audit-seo。mjs | 正典、hreflang、JSON-LD、サイトマップ |
| node scripts/i18n/tqa.mjs --lang es --dry | optional — MQM quality score, cost first |
次に、ビルド ディレクトリを今日デプロイしたとおりにデプロイします — ローカライズされたページは、既存のファイルの隣にある通常のファイルです。完全なオプション、すべての失敗モード、および各設計決定の背後にある理由は、にあります README.
Models
独自のモデル — を地元のモデルも含めてご持参ください
翻訳ステップでは、小さなアダプタを介してモデルと通信し、Claude(デフォルト)、Gemini、および OpenAI 互換のエンドポイントの 3 つのデバイスが同梱されます。最後のものは、フィールド — OpenAI、Azure、Groq、DeepSeek、Mistral、OpenRouter、Together、Fireworks — のほとんどをカバーしており、Ollama、LM Studio、vLLM もカバーしています。
つまり、3 行の構成でパイプライン全体を独自のハードウェア上で実行します
{
"provider": "openai",
"apiBaseUrl": "http://localhost:11434/v1",
"model": "qwen2.5:14b"
}キーもクォータもなく、マシン — から何も残りません。これは、コンテンツが機密である場合に重要です。そのリストに含まれていないものは、2 つの関数を含むアダプター ファイルです。
Limits
無料ツールが停止する場所
6 つの本当の限界。これらはどれも機能不全に陥った機能ではありません — これらはアプローチの形状であり、スクリプトは静かに失敗するのではなく、いつヒットしたかを教えてくれます。
- クライアント側の水分補給
- アイランドとフレームワークのペイロードは、置換された HTML 経由でブラウザで再レンダリングされます。抽出器は影響を受けるページをカウントするため、フル実行後ではなく数秒で確認できます。
- ドキュメント
- リンクされた PDF、DOCX、および XLSX はソース言語に留まります — パイプラインは HTML にのみ触れます。
- 解約
- メモリはソース ハッシュによってキー入力されるため、前回の実行以降にサイトのシェアが変更されたことがわかります。解約率が高いということは、繰り返し再翻訳するためにお金を払うことを意味します。
- 翻訳の編集
- メモリ ファイル内のハッシュを見つけ、文字列を編集して再構築します。エディターもレビュアーもワークフローもありません。
- 音量
- モデルを自分で実行する場合は、独自のキー — を使用して、独自のモデル プロバイダーに直接、そのレートで支払うか、まったく支払いません。
- ネットワークの使用を変更しました
- AGPL-3。0 §13 では、変更されたコピーを他の人向けのサービスとして実行する場合、変更を公開することが義務付けられています。変更せずに実行したり、内部的に変更したりすることは制限されません。
最初の 4 つは人々が実際に殴ったもので、すべて同じ形です。何かが起こらなければなりません 後 ビルドタイム ツールでは実行できないビルド。それが管理対象製品の目的です 無料プラン カードなしで 5,000 語なので、役立つかどうかを知るのに十分です。このページで何かを使用する必要はありません。
帰属
What it puts on your pages
ローカライズされたページには、 <meta name="generator"> タグと 1 つの HTML コメント命名 ConveyThis — 約 150 バイト、リクエストなし、スクリプトなし、および リンクなし。これは、Astro、Hugo、WordPress が使用するメカニズムと同じです。2 つの構成キーがそれを削除し、リポジトリ内の何も削除したかどうかをチェックしません。
目に見えるクレジットを表示したい場合は、設定します credit.visibleLink へ true そして、ページ上の任意の場所にスロットを配置します。それについては何も求められず、見返りも何も与えられません。— それは、使用するツールをクレジットしたい人がいるために存在しますが、それ以外の理由はありません。
クレジットリンクは rel="nofollow"、 意図的に。有料だからではなく — ではないから —、ビルド スクリプトがサイトのすべてのページに追加するリンクであるため、編集上の選択ではなくツールを通じて表示されるサイト全体のリンクが Google のリンク スキーム ガイダンスの目的です。バックリンクではなく、紹介トラフィックの価値があります — そうでないと言う人はペナルティを売っています。
商業ライセンス
コードはAGPL-3。0です。独自のサイトをローカライズし、出力を送信することは制限されません — ライセンスは、書き込む HTML ではなく、ソフトウェアをカバーします。走った場合にのみ噛みつきます 変更された 他の人のためのネットワークサービスとしてコピーします。それがあなたであり、変更を公開できない場合は、に書いてください [メールアドレス].
質問
The questions people actually ask
これは本当に無料ですか?落とし穴は何ですか?
ConveyThis アカウントが必要ですか?
実行には実際にどれくらいの費用がかかりますか?
独自のモデルを使用したり、完全にオフラインで実行したりできますか?
翻訳されたページは元のページよりも遅くなりますか?
私のフレームワークで動作しますか?
水和する React コンポーネントや Astro アイランドについてはどうですか?
Can it keep my terminology consistent, and tell a brand name from an ordinary word?
I already use it. What changes when I upgrade to 2.0.0?
気に入らない翻訳を修正できますか?
ページを編集したり、新しいページを追加したりするとどうなりますか?
翻訳されたページは Google によってインデックス付けされますか?
商業的に使用できますか?AGPL-3。0 は私にとって何を意味しますか?
ConveyThis 帰属は必要ですか?
これは ConveyThis 自体とどう違うのでしょうか?
翻訳は、単に言語を知るだけでなく、複雑なプロセスです。
私たちのヒントに従って使用することによって ConveyThis 翻訳されたページは、ターゲット言語にネイティブであると感じられ、読者の共感を呼ぶでしょう。
努力が必要ですが、結果はやりがいがあります。Web サイトを翻訳している場合、ConveyThis 自動機械翻訳により時間を節約できます。
無料プランの ConveyThis から始めましょう — クレジットカードは必要ありません!
