トラブルシューティング
ここに掲載しているのは、実際に誰かが遭遇した障害パターンばかりです。それぞれ、症状、発生する理由、対処法をまとめています。原因のほとんどは、次の3つのいずれかです。フレーズがプロジェクトに存在しない、SDKが初期化されていない、またはプレースホルダーの記述が使用するコンテキストに合っていない。
何も翻訳されない — すべてのフレーズが原文の言語のまま表示される
すべてが原文テキストで表示される場合、SDK の初期化に失敗している可能性が非常に高いです。SDK は(UI を決して壊さないよう)設計上エラーを表に出さずに処理するため、手がかりになるのはブラウザーのコンソールだけです。まずそこを確認してください。主な原因を可能性の高い順に示します。
- CORS。SDKの最初のリクエストは
authorize-projectです。APIがアプリのオリジンを許可リストに登録していないと、ブラウザーがそのリクエストをブロックし、初期化はその時点で失敗します。オリジンとは正確にはスキーム + ホスト + ポートの組み合わせであり、localhost:5173とlocalhost:5174は別のオリジンであることに注意してください。通常のポートが使用中の場合、開発サーバーはポートが変わることがあります。実際に開発で使うすべてのポートを許可リストに登録してください。 - 認証情報が間違っています。プロジェクト ID や API キーが未入力、または入力ミスの場合も、同じ認可呼び出しが失敗します。コンソールに失敗したリクエストと URL が表示されます。
- 現在表示しているのはベースロケールです。ベースロケールでは「翻訳」そのものが原文なので、見た目は何も変わりません。テストするには、ターゲットロケールに切り替えてください。
# The SDK's first call is an authorize-project request.
# If the browser blocks it, NOTHING translates. Check the console for:
Access to fetch at 'https://your-api/api/authorize-project/...'
from origin 'http://localhost:5173' has been blocked by CORS policy
# Fix: allowlist the app's EXACT origin (scheme + host + port) on the API.
CORS_ALLOWED_ORIGINS=http://localhost:5173,https://app.example.com 1つのフレーズだけ翻訳されない(他は翻訳される)
コード内のフレーズが検索キーになります。つまりフレーズがキーです。1 つのフレーズだけがソーステキストのまま表示され、周囲のフレーズは翻訳される場合、そのキーはプロジェクトのカタログに存在しません。
- 一度も登録されていません。登録はトークン検出によって行われ、実行できるのは書き込みキーだけです。アプリが読み取り専用キーで動作している間にフレーズが作られた場合、そのフレーズはどこにも送信されていません。開発環境で書き込みキーを使ってその画面を一度実行するか、ダッシュボードでフレーズを追加してください。
- テキストが変更されました。単語、句読点、あるいは空白でも、編集すると新しいフレーズとして扱われ、翻訳はまだ存在しません。以前の翻訳は古いキーのもとに残っています。特にコンテンツブロックで起こりやすい問題です。
<Translate>ブロックはマークアップからトークン化されるため、ブロックのテキストや構造を編集すると検索対象が変わり、新しい形式が登録・翻訳されるまで、ブロックは気づかないうちに原文にフォールバックします。 - 機械翻訳がまだ追いついていません。登録直後のフレーズは、翻訳が反映されるまで少し時間がかかることがあります。また、プロジェクトのターゲットリストにないロケールには、翻訳が作成されることはありません。ダッシュボードでフレーズを確認してください。登録されていますか?このロケールに翻訳されていますか?
フレーズが見つからなくてもエラーにならないのはなぜですか?
仕様です。本番環境の翻訳システムは、読めるソーステキストに縮退するべきで、ページが壊れるようなことがあってはなりません。そのため、未登録のフレーズはソースのまま表示され、SDK は何も通知しません。その裏返しとして、読み取り専用キーでは、フレーズが欠けていても何も表示されません。ログは出力されず、登録もされず、ユーザーが英語表示を目にして初めて気づくことになります。これを防ぐ運用がキーの分離です。書き込みキーで開発して、UI が表示するすべてのフレーズを検出させ、その後に読み取り専用で公開します。
# Development — write key: new phrases are discovered,
# registered, and machine-translated as you build.
VITE_LANGSYS_API_KEY=write-key
# Production — read-only key: fetches the finished catalog only.
# Unregistered phrases silently render their source text.
VITE_LANGSYS_API_KEY=read-only-key プレースホルダーがそのまま表示される — 「Hi %name%」や「Hi {name}」
t()の呼び出しでは、プレースホルダーは波括弧1つの{name}で、補間はパラメーターを渡したときにのみ実行されます:t('Hello, {name}!', 'Greetings', { name })。- React、Vue、Svelte のマークアップ内の
<Translate>/<Phrase>では、プレースホルダーを%name%形式で記述してください。波括弧だけの{name}は、SDK が処理する前にフレームワークのコンパイラが式として解釈してしまいます。一方、%name%はコンパイル後も残り、SDK がキャプチャ時に{name}へ正規化します。テンプレート構文と衝突しない通常の HTML では、そのまま{name}で問題ありません。 - パラメーターが表示されない場合
paramsが渡されていないと、テンプレートはそのまま表示されます。表示されているのは、文字どおりの%name%です。
ロケールを何度か切り替えると、最初は動作するのに途中でおかしくなる
SDK を更新してください。この領域で実際に修正されたバグ: 初期/SSR ロケールに戻ると以前のカタログが有効なままになる問題(langsys-js-typescript 0.2.2 で修正)と、コンテンツブロックの Translate/Phrase を使用する側が、サーバーで初期化されたカタログで無限にハングすることがある問題(0.2.3 で修正)。古いロケールの文字列が表示されたり、ブロックがいつまでも解決されなかったりする場合は、ご自身のコードをデバッグする前に、インストール済みのバージョンをベース SDK の変更履歴と照らし合わせてください。
サーバーサイド:ページが縮退動作せず500エラーになる
PHP SDKのクライアントは認証情報なしで構築するとエラーをスローします。そのため、LANGSYS_API_KEYが空のLaravel(または素のPHP)アプリは、翻訳が実行される前にコンテナの解決時点で失敗します。認証情報を設定してください(認証情報なしで起動する必要があるアプリの場合は、デモアプリのようにスタンドインのクライアントをバインドします)。認証情報が設定されていれば、実行時のAPI障害では正常に縮退動作します。APIに到達できない場合や拒否された場合は原文を表示して例外を報告するだけで、ページ全体が停止することはありません。
サーバーサイド: 最初のリクエストだけハングし、その後はすべて高速になる
PHP SDK の HTTP タイムアウトは 30 秒です。アイドル状態から復帰した API インスタンスでは、最初の呼び出しでこの時間に近づくことがあります。そのリクエストは、時間がかかっても完了する(カタログキャッシュがウォームアップされ、以降はすべてキャッシュから返されます)か、タイムアウトして原文が表示されるかのどちらかです。しばらく使わなかった後の最初のページ読み込みが遅い場合は、これが原因です。原因は API のウォームアップであり、お客様の連携に問題があるわけではありません。
サーバーサイド:書き込みキーでレンダリングしたのに、フレーズがダッシュボードに表示されない
検出されたフレーズはリクエスト処理中にキューに追加され、レスポンスの送信後に送信されます。これはLaravelのターミネーブルミドルウェアによる動作です。ダッシュボードの更新は、ページの読み込み中ではなく、読み込みが完了してしばらくしてから行ってください。長時間稼働するワーカーランタイム(Octane、FrankenPHP、RoadRunner)では、SDKが提供する統合機能を使用していることを確認してください。通常のPHPのシャットダウンフックは、ワーカーのリクエスト間では実行されません。
サーバーレンダリング:あるリクエストの翻訳が別のリクエストに混入する
JSベースSDKは一度に1つのロケールのカタログしか保持できません。モジュールレベルのシングルトンだからです。Nodeサーバーが同時リクエストに対して異なるロケールをレンダリングすると、競合が発生します。リクエストごとにカタログを取得してクライアントの初期値に設定するか(パターンはNext.js、Nuxt、SvelteKitの各ガイドを参照)、プロセスごとに1つのロケールで運用してください。
解決しませんか? コンソールの出力(またはサーバーログ)と失敗したリクエストを添えて、SDKのリポジトリで Issue を作成してください — typescript、react、vue、svelte、php、laravel。または [email protected] までご連絡ください。