Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

HTMLRewriter でウェブサイトをローカライズする

最終更新 Markdown で表示Agent セットアップ

このチュートリアルでは、アプリケーション向けの国際化・ローカライズエンジン(一般に i18nl10n と呼ばれます)の例を作り、サイトのコンテンツを配信し、訪問者の所在地に応じて自動で翻訳します。

このチュートリアルでは、Cloudflare Workers ランタイムに組み込まれた HTMLRewriter クラスを使います。Cloudflare のグローバルネットワーク上で HTML の解析と書き換えができます。これにより、Workers アプリケーションを効率よく、透過的にカスタマイズできます。

日本語、ドイツ語、英語にローカライズされたサイトの例

続ける前に

すべてのフレームワークガイドは、Git の基本的な理解があることを前提としています。Git を初めて使う場合は、この Git ハンドブックの要約 で、ローカルマシンへの Git のセットアップ方法を確認してください。

SSH でクローンする場合は、GitHub に対して push または pull する各コンピューターで SSH キーを生成 する必要があります。

詳細は GitHub のドキュメントGit のドキュメント を参照してください。

前提条件

このチュートリアルは、既存のウェブサイトを使う前提です。手順を簡単にするため、HTML5 UP の無料 HTML5 テンプレートを使います。このサイトを土台に、Workers プラットフォームの HTMLRewriter で i18n レイヤーを重ね、ユーザーの言語に応じてサイトを自動翻訳します。

自分のバージョンをデプロイしたい場合は、ソースを GitHub で確認できます。デプロイ手順はプロジェクトの README にあります。

新しいアプリケーションを作成する

create-cloudflare を使って新しいアプリケーションを作成します。Cloudflare 向けのアプリケーション作成・デプロイ用 CLI です。

npm create cloudflare@latest -- i18n-example

セットアップでは、次の選択肢を選びます。

  • What would you like to start with? では Framework Starter を選びます。
  • Which development framework do you want to use? では React を選びます。
  • Do you want to deploy your application? では No を選びます。

生成された i18n-example プロジェクトには、publicsrc の 2 つのフォルダーがあります。React アプリケーションのファイルが入っています。

cd i18n-example
ls
public src package.json

生成されたプロジェクトを少し直します。まず public ディレクトリの中身を、デモのスクリーンショットにある HTML5 UP テンプレートのデフォルト HTML に置き換えます。このプロジェクトの リリース(ZIP ファイル)をダウンロードし、public フォルダーを自分のプロジェクトにコピーして始めます。

次に、functions ディレクトリと index.js ファイルを作成します。アプリケーションのロジックはここに書きます。

mkdir functions
cd functions
touch index.js

さらに、このプロジェクトでは不要なため src/ ディレクトリを削除します。静的 HTML を更新したら、functions フォルダー内の index.js に集中できます。

data-i18n-key を理解する

Workers ランタイムの HTMLRewriter クラスを使うと、HTML を解析し、ページの各要素をクエリして変換する JavaScript を書けます。

このチュートリアルの例サイトは、public ディレクトリにある基本的な 1 ページの HTML プロジェクトです。テキスト Example Siteh1 要素と、異なるテキストの複数の p 要素があります。

上記の要素が Chrome DevTools に表示されたデモコード

このページの特徴は、HTML の data 属性 です。複数の要素に定義されたカスタム属性です。h1 タグと多くの p タグにある data-i18n-key は、対応する国際化キーがあることを示します。このキーで、テキストの翻訳を探します。

<!-- source clipped from i18n-example site -->

<div class="inner">
	<h1 data-i18n-key="headline">Example Site</h1>
	<p data-i18n-key="subtitle">This is my example site. Depending o...</p>
	<p data-i18n-key="disclaimer">Disclaimer: the initial translations...</p>
</div>

HTMLRewriter で、./public/index.html 内の HTML を解析します。data-i18n-key 属性が見つかったら、その値で strings オブジェクトから一致する翻訳を取得します。HTMLRewriter では、要素をクエリして data 属性を探すといった処理ができます。名前のとおり、翻訳した文字列を HTML に直接挿入して、要素を書き換えることもできます。

このプロジェクトのもう 1 つの機能は、受信リクエストの Accept-Language ヘッダーに基づきます。リクエストごとに翻訳言語を設定できるので、世界中のユーザーに、その地域向けに翻訳されたページを表示できます。

HTML Rewriter API を使う

functions/index.js ファイルから始めます。このチュートリアルのアプリケーションは、すべてこのファイルに置きます。

このファイルの先頭に、Pages Function を動かすデフォルトのコードを追加します。

export function onRequest(context) {
	return new Response("Hello, world!");
}

重要な処理は onRequest 関数にあります。サイトを翻訳するには、env.ASSETS.fetch(request) で HTML レスポンスを取得します。これで Pages プロジェクトの静的アセットを取得できます。取得したレスポンスを、新しい HTMLRewriter インスタンスに渡します。

HTMLRewriter を生成するとき、on 関数でハンドラーを付けられます。このチュートリアルでは [data-i18n-key] セレクターを使います。高度な使い方は HTMLRewriter のドキュメント を参照してください。このセレクターで、data-i18n-key 属性を持つ要素をすべて探します。これらの要素は翻訳が必要です。

一致した要素は、翻訳ロジックを持つ ElementHandler クラスのインスタンスに渡されます。作成した HTMLRewritertransform 関数は response を受け取り、クライアントに返せます。

export async function onRequest(context) {
	const { request, env } = context;
	const response = await env.ASSETS.fetch(request);
	return new HTMLRewriter()
		.on("[data-i18n-key]", new ElementHandler(countryStrings))
		.transform(response);
}

HTML を変換する

ElementHandler は、HTMLRewriter インスタンスが解析したすべての要素を受け取ります。表現力のある API なので、各要素の情報をクエリできます。

data-i18n-key を理解する では、ウェブサイトの UI 向けに対応する翻訳文字列を探すカスタム data 属性 data-i18n-key を説明しています。ElementHandler では element 関数を定義できます。各要素の解析時に呼ばれます。element 関数内で、getAttribute を使ってカスタム data 属性をクエリできます。

class ElementHandler {
	element(element) {
		const i18nKey = element.getAttribute("data-i18n-key");
	}
}

i18nKey が取れたら、対応する翻訳文字列を探せます。次に、data-i18n-key の値に対応するキーと値のペアを持つ strings オブジェクトを用意します。まずは 1 つの例として、ドイツ語の string "Beispielseite""Example Site")を headline に定義し、element 関数で取得します。

const strings = {
	headline: "Beispielseite",
};

class ElementHandler {
	element(element) {
		const i18nKey = element.getAttribute("data-i18n-key");
		const string = strings[i18nKey];
	}
}

翻訳した string を、setInnerContent 関数で元の要素に挿入します。

const strings = {
	headline: "Beispielseite",
};

class ElementHandler {
	element(element) {
		const i18nKey = element.getAttribute("data-i18n-key");
		const string = strings[i18nKey];
		if (string) {
			element.setInnerContent(string);
		}
	}
}

想定どおりか確認するには、Wrangler 組み込みのプレビュー機能を使います。wrangler pages dev ./public を実行すると、プロジェクトのライブプレビューが開きます。コードを変更するたびにプレビューが更新されます。

この翻訳機能を拡張して、受信リクエストの Accept-Language ヘッダーに基づく言語別の翻訳を提供できます。このヘッダーを解析し、解析した言語を ElementHandler に渡すと、strings に定義がある場合、ユーザーの使用言語で翻訳文字列を取得できます。

実装手順は次のとおりです。

  1. strings オブジェクトを更新し、キーと値のペアをもう 1 層追加します。文字列は strings[country][key] の形式で探します。
  2. 解析中に使えるよう、countryStrings オブジェクトを ElementHandler に渡します。
  3. 受信リクエストから Accept-Language ヘッダーを取得し、解析して、解析した言語を ElementHandler に渡します。

Accept-Language ヘッダーを解析するには、accept-language-parser npm パッケージをインストールします。

npm i accept-language-parser

コードにインポートしたら、Accept-Language ヘッダーに基づいてクライアントに最も適した言語を解析し、ElementHandler に渡します。ドイツと日本向けのサンプル翻訳(Google 翻訳を使用)を含めた、プロジェクトの最終コードは次のとおりです。

import parser from "accept-language-parser";

// do not set to true in production!
const DEBUG = false;

const strings = {
	de: {
		title: "Beispielseite",
		headline: "Beispielseite",
		subtitle:
			"Dies ist meine Beispielseite. Abhängig davon, wo auf der Welt Sie diese Site besuchen, wird dieser Text in die entsprechende Sprache übersetzt.",
		disclaimer:
			"Haftungsausschluss: Die anfänglichen Übersetzungen stammen von Google Translate, daher sind sie möglicherweise nicht perfekt!",
		tutorial:
			"Das Tutorial für dieses Projekt finden Sie in der Cloudflare Workers-Dokumentation.",
		copyright: "Design von HTML5 UP.",
	},
	ja: {
		title: "サンプルサイト",
		headline: "サンプルサイト",
		subtitle:
			"これは私の例のサイトです。 このサイトにアクセスする世界の場所に応じて、このテキストは対応する言語に翻訳されます。",
		disclaimer:
			"免責事項:最初の翻訳はGoogle翻訳からのものですので、完璧ではないかもしれません!",
		tutorial:
			"Cloudflare Workersのドキュメントでこのプロジェクトのチュートリアルを見つけてください。",
		copyright: "HTML5 UPによる設計。",
	},
};

class ElementHandler {
	constructor(countryStrings) {
		this.countryStrings = countryStrings;
	}

	element(element) {
		const i18nKey = element.getAttribute("data-i18n-key");
		if (i18nKey) {
			const translation = this.countryStrings[i18nKey];
			if (translation) {
				element.setInnerContent(translation);
			}
		}
	}
}

export async function onRequest(context) {
	const { request, env } = context;
	try {
		let options = {};
		if (DEBUG) {
			options = {
				cacheControl: {
					bypassCache: true,
				},
			};
		}
		const languageHeader = request.headers.get("Accept-Language");
		const language = parser.pick(["de", "ja"], languageHeader);
		const countryStrings = strings[language] || {};

		const response = await env.ASSETS.fetch(request);
		return new HTMLRewriter()
			.on("[data-i18n-key]", new ElementHandler(countryStrings))
			.transform(response);
	} catch (e) {
		if (DEBUG) {
			return new Response(e.message || e.toString(), {
				status: 404,
			});
		} else {
			return env.ASSETS.fetch(request);
		}
	}
}

デプロイする

Cloudflare Pages 上に作った i18n ツールは完成です。ドメインへデプロイします。

アプリケーションを *.pages.dev サブドメインにデプロイするには、配信する静的アセットのディレクトリを指定します。プロジェクトの Wrangler ファイルで pages_build_output_dir を設定し、値を ./public にします。

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "i18n-example",
	"pages_build_output_dir": "./public",
	// Set this to today's date
	"compatibility_date": "2026-09-20"
}
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "i18n-example"
pages_build_output_dir = "./public"
# Set this to today's date
compatibility_date = "2026-09-20"

次に、プロジェクトの package.json にデプロイ用スクリプトを設定します。値が wrangler pages deploy の deploy スクリプトを追加します。

"scripts": {
  "dev": "wrangler pages dev",
  "deploy": "wrangler pages deploy"
}

wranglerdeploy コマンドで、Cloudflare のネットワークにデプロイします。

npm run deploy
日本語、ドイツ語、英語にローカライズされたサイトの例

関連リソース

このチュートリアルでは、HTMLRewriter を使って i18n ツールを作り、デプロイしました。このアプリケーションのソースコード全体は、GitHub のリポジトリ を参照してください。

自分のプロジェクトを作りたい場合は、既存の Quickstart テンプレート の一覧を確認してください。

役に立ちましたか?