Microsoft Edge 151では、LanguageDetector APIが繁体字中国語と簡体字中国語を区別できるようになりました。これまで両方ともzhとして返されていた判定結果が、繁体字はzh-Hant、簡体字はzh-Hansとして返されます。
この変更で注意したいのは、detectedLanguage === "zh"のような完全一致で中国語を判定しているコードです。Edge 151では条件に一致しなくなり、中国語向けの翻訳や画面表示が実行されない可能性があります。
Microsoftが2026年7月30日(UTC)に公開・更新した情報では、本変更は情報提供として案内されています。ただし、LanguageDetector APIの戻り値を利用しているWebサイトやブラウザー拡張機能では、コード、テスト、データ保存形式を確認しておく必要があります。(Microsoft Learn)
Edge 151のLanguageDetectorがzh-Hantとzh-Hansを返す変更
Microsoft Edge 151では、LanguageDetector APIによる中国語の判定結果が次のように変わります。
| 入力された文章 | 従来の判定結果 | Edge 151の判定結果 |
|---|---|---|
| 繁体字中国語 | zh | zh-Hant |
| 簡体字中国語 | zh | zh-Hans |
zhは中国語を表す言語コードです。一方、HantとHansは文字体系を表すサブタグです。
zh-Hant:繁体字で書かれた中国語zh-Hans:簡体字で書かれた中国語zh:文字体系を指定しない中国語
LanguageDetector APIのdetect()が返すdetectedLanguageには、BCP 47形式の言語タグが格納されます。Edge 151では、この言語タグを使って中国語の文字体系まで区別できるようになった形です。(Microsoft Learn)
既存コードに影響する理由
変更されるのはAPIの呼び出し方法ではなく、主に戻り値の内容です。そのため、API自体は動いていても、判定結果を処理する後続コードだけが正しく動かなくなることがあります。
zhとの完全一致は成立しなくなる
影響を受けやすいのが、次のような実装です。
const results = await detector.detect(text);
const bestResult = results[0];
if (bestResult.detectedLanguage === "zh") {
showChineseContent();
}
繁体字の判定結果がzh-Hant、簡体字の判定結果がzh-Hansになると、どちらも"zh"とは一致しません。
その結果、次のような不具合が起こる可能性があります。
- 中国語向けの翻訳処理が始まらない
- 中国語用フォントやCSSが適用されない
- 問い合わせを中国語担当者へ振り分けられない
- 中国語用の入力チェックが実行されない
- 分析画面で中国語の件数がゼロになる
JavaScriptの例外が発生するとは限らないため、エラーログだけでは発見しにくい点にも注意が必要です。
2文字の言語コードを前提とした処理も確認する
zh-Hantとzh-Hansはいずれもzhより長い文字列です。次のような実装がないか確認してください。
const language = detectedLanguage.slice(0, 2);
const supportedLanguages = ["ja", "en", "zh"];
if (!supportedLanguages.includes(detectedLanguage)) {
useDefaultLanguage();
}
const messages = {
ja: japaneseMessages,
en: englishMessages,
zh: chineseMessages
};
const selectedMessages = messages[detectedLanguage];
特に、許可リスト、オブジェクトのキー、正規表現、TypeScriptの型定義は影響を受けやすい箇所です。
データベースや分析基盤にも影響する
検出した言語タグをサーバーへ送信している場合は、フロントエンドだけでなくバックエンドも確認します。
代表的な確認箇所は次のとおりです。
| 確認箇所 | 起こり得る問題 |
|---|---|
| データベースの文字数制限 | 2文字固定の列に保存できない |
| バリデーション | ^[a-z]{2}$などの条件で拒否される |
| 集計処理 | zh、zh-Hant、zh-Hansが別々に集計される |
| 外部API連携 | 2文字コードしか受け付けないAPIでエラーになる |
| TypeScriptの型 | "ja" | "en" | "zh"に代入できない |
| テストのスナップショット | 期待値がzhのままで失敗する |
データベースの列がCHAR(2)になっている場合は、BCP 47形式の言語タグを保存できる長さへ変更する必要があります。
中国語を区別するかどうかで対応方法を決める
Edge 151への対応方法は、アプリが繁体字と簡体字を区別する必要があるかどうかで変わります。
繁体字と簡体字を区別したい場合
翻訳先、表示文言、検索辞書、コンテンツの振り分けなどを文字体系ごとに変えたい場合は、zh-Hantとzh-Hansをそのまま利用します。
function getChineseScript(languageTag) {
const locale = new Intl.Locale(languageTag);
if (locale.language !== "zh") {
return "not-chinese";
}
if (locale.script === "Hant") {
return "traditional";
}
if (locale.script === "Hans") {
return "simplified";
}
return "unspecified";
}
利用例は次のとおりです。
const script = getChineseScript(result.detectedLanguage);
switch (script) {
case "traditional":
showTraditionalChineseContent();
break;
case "simplified":
showSimplifiedChineseContent();
break;
case "unspecified":
showGenericChineseContent();
break;
default:
showDefaultContent();
}
文字列を直接分割する方法もありますが、BCP 47形式の言語タグを扱う場合はIntl.Localeを利用すると、言語部分と文字体系部分を明確に分けられます。
中国語かどうかだけ分かればよい場合
繁体字と簡体字を同じ処理へ流す場合は、完全一致ではなく基本言語を確認します。
変更前のコードです。
const isChinese = detectedLanguage === "zh";
変更後は次のようにします。
function isChineseLanguage(languageTag) {
try {
const locale = new Intl.Locale(languageTag);
return locale.language === "zh";
} catch {
return false;
}
}
これなら、次のタグをいずれも中国語として扱えます。
isChineseLanguage("zh"); // true
isChineseLanguage("zh-Hant"); // true
isChineseLanguage("zh-Hans"); // true
単純にlanguageTag.startsWith("zh")と判定する方法もありますが、言語タグとして解析する意図が明確なIntl.Localeの利用が分かりやすいでしょう。
外部システムがzhしか受け付けない場合
連携先のAPIや既存システムがzh-Hantとzh-Hansに対応していない場合は、連携直前にzhへ変換します。
function toLegacyLanguageCode(languageTag) {
try {
const locale = new Intl.Locale(languageTag);
if (locale.language === "zh") {
return "zh";
}
return locale.language;
} catch {
return "und";
}
}
重要なのは、LanguageDetector APIから受け取った直後にすべてzhへ戻さないことです。
アプリ内部ではzh-Hantとzh-Hansを保持し、互換性のために必要な連携部分だけをzhへ変換すると、将来的に繁体字と簡体字を使い分けたくなったときにも対応しやすくなります。
Edge 151に対応したLanguageDetectorの実装例
LanguageDetector APIを利用するときは、戻り値の変更だけでなく、APIの利用可否、モデルの準備状態、判定不能、セッションの破棄も考慮します。
async function detectLanguage(text) {
const normalizedText = text.trim();
if (!normalizedText) {
return {
status: "empty",
detectedLanguage: "und",
confidence: 0
};
}
if (!("LanguageDetector" in globalThis)) {
return {
status: "unsupported",
detectedLanguage: "und",
confidence: 0
};
}
const availability = await LanguageDetector.availability();
if (availability === "unavailable") {
return {
status: "unavailable",
detectedLanguage: "und",
confidence: 0
};
}
const detector = await LanguageDetector.create({
expectedInputLanguages: [
"ja",
"en",
"zh-Hant",
"zh-Hans"
]
});
try {
const results = await detector.detect(normalizedText);
const bestResult = results[0];
if (!bestResult || bestResult.detectedLanguage === "und") {
return {
status: "undetermined",
detectedLanguage: "und",
confidence: bestResult?.confidence ?? 0
};
}
const locale = new Intl.Locale(bestResult.detectedLanguage);
return {
status: "detected",
detectedLanguage: bestResult.detectedLanguage,
baseLanguage: locale.language,
script: locale.script || null,
confidence: bestResult.confidence
};
} finally {
detector.destroy();
}
}
呼び出し側では、用途に応じて基本言語と文字体系を使い分けます。
const result = await detectLanguage(userInput);
if (result.status !== "detected") {
showLanguageSelection();
} else if (
result.baseLanguage === "zh" &&
result.script === "Hant"
) {
showTraditionalChineseContent();
} else if (
result.baseLanguage === "zh" &&
result.script === "Hans"
) {
showSimplifiedChineseContent();
} else {
showContentForLanguage(result.baseLanguage);
}
LanguageDetector APIは端末上のモデルを使って言語を検出します。初回利用時にはモデルのダウンロードが必要になる場合があり、availability()ではunavailable、downloadable、downloading、availableなどの状態を確認できます。
また、detect()の結果は信頼度が高い順に並び、各結果にはdetectedLanguageとconfidenceが含まれます。利用後はdestroy()でセッションを破棄できます。(Microsoft Learn)
zh-Hantとzh-Hansを地域コードとして扱わない
HantとHansは文字体系を表すタグであり、国や地域を直接示すものではありません。
そのため、次のような決め打ちは避けた方が安全です。
if (detectedLanguage === "zh-Hant") {
userCountry = "TW";
}
繁体字の文章を検出できても、利用者の居住地や希望する地域設定まで確定できるわけではありません。
地域ごとに日付形式、通貨、住所、固有表現などを切り替える場合は、言語検出結果とは別に次の情報を使います。
- ユーザーが選択した表示地域
- アカウントに保存されたロケール
- ブラウザーの言語設定
- サービス側で設定した地域情報
LanguageDetectorの結果は、あくまで「入力された文章がどの言語・文字体系で書かれている可能性が高いか」を判断する材料として利用します。
短い文章だけで判定しない
Microsoftは、短いテキストや単語だけを入力した場合、言語検出結果が不正確または不安定になる可能性があると説明しています。(Microsoft Learn)
例えば、次のような入力は判定材料が少なくなります。
你好
商品
漢字だけの短い文字列では、中国語、日本語、その他の言語を区別しにくい場合があります。繁体字と簡体字のテストも、1文字や単語ではなく、ある程度の長さがある自然な文章で実施してください。
実際のサービスでは、次のような対策が有効です。
- 一定文字数未満では自動判定しない
- 信頼度が低い場合はユーザーに選択してもらう
- 判定結果だけで重要な処理を確定しない
- 入力が増えた時点で再判定する
- 手動で選択した言語を優先する
信頼度の基準値は、サービスの入力内容や誤判定時の影響によって変わります。根拠なく固定値を採用せず、実際の文章データを使って調整することが重要です。
Edge 151への更新前後で実施したいテスト
繁体字と簡体字の文章を1件ずつ確認するだけでは不十分です。既存の言語判定処理全体を対象にテストします。
| テスト内容 | 確認するポイント |
|---|---|
| 十分な長さの繁体字文章 | 最上位候補がzh-Hantになるか |
| 十分な長さの簡体字文章 | 最上位候補がzh-Hansになるか |
| 日本語の漢字を含む文章 | 中国語向け処理へ誤って進まないか |
| 繁体字と簡体字が混在した文章 | 想定外の結果でも画面が壊れないか |
| 数字や記号が中心の文章 | undや低信頼度を処理できるか |
| 1語だけの短い入力 | 自動確定せずフォールバックできるか |
| APIを利用できないブラウザー | 手動選択などの代替手段が表示されるか |
| 初回モデルダウンロード時 | 読み込み中の状態を利用者へ示せるか |
既存のzhデータ | 過去データを引き続き処理できるか |
| 外部APIへの送信 | zh-Hantとzh-Hansが拒否されないか |
古い環境からzhが渡される可能性も考え、移行期間中はzh、zh-Hant、zh-Hansの3種類を受け入れる実装にしておくと安全です。
コード以外で見落としやすい確認箇所
LanguageDetectorの呼び出し部分を直しても、次の設定や資料に古い前提が残っていることがあります。
- API仕様書の言語コード一覧
- OpenAPIやJSON Schemaの列挙値
- TypeScriptの型定義
- 単体テストの期待値
- E2Eテストの判定条件
- モックデータ
- ダッシュボードの集計条件
- ログ検索用のクエリ
- データベースの制約
- CSV出力の仕様
- 翻訳サービスへの変換表
- 運用担当者向けの手順書
特に、分析データをWHERE language = 'zh'で集計している場合は、Edge 151以降のデータが集計から漏れる可能性があります。
文字体系を分けずに中国語全体を集計するなら、zh、zh-Hant、zh-Hansを同じグループへまとめます。一方、繁体字と簡体字の利用状況を分析したい場合は、元の言語タグを保持したまま別々に集計します。
Edge 151対応で実施すること
まず、ソースコードと設定ファイルから次の文字列を検索します。
=== "zh"
== "zh"
language: "zh"
["ja", "en", "zh"]
CHAR(2)
VARCHAR(2)
^[a-z]{2}$
そのうえで、用途に応じて対応を分けます。
- 中国語かどうかだけ判定する処理は、基本言語が
zhか確認する - 繁体字と簡体字を分ける処理は、
HantとHansを確認する - 外部システムが新しいタグに非対応なら、連携境界で
zhへ変換する - データベースや型定義の文字数・列挙値を見直す
- 短文、混在文、判定不能、モデル未準備のケースをテストする
- 過去の
zhと新しいzh-Hant、zh-Hansを同時に処理できるようにする
Edge 151のLanguageDetector変更に対応するうえで重要なのは、単にzhを2つのタグへ置き換えることではありません。アプリが必要としているのが「中国語という言語の判定」なのか、「繁体字と簡体字の区別」なのかを整理し、それぞれに適した粒度で言語タグを扱うことです。
既存コードでは、まずzhとの完全一致、2文字固定のバリデーション、翻訳先の対応表、データベースの列長を確認してください。内部では新しい言語タグを保持し、古い形式が必要な外部連携だけを変換する設計にすると、互換性を保ちながらEdge 151の改善を活用できます。

コメント