Astro x Vercel で実現する、超シンプルな「国判定」ロジック
グローバルSaaSを開発する際、「日本からのアクセスなら日本語、それ以外なら英語をデフォルトにする」という要件は必須です。
本記事では、Vercelの独自ヘッダーを活用した、爆速の言語振り分けテクニックを解説していきます。
従来手法とVercel Edge方式の比較
核心となるヘッダー: x-vercel-ip-country
Vercelは、リクエストを受け取った際、リクエスト元の国コードを自動的にヘッダー x-vercel-ip-country に付与します。
実装コード(Astro SSRモード)
src/pages/index.astro の frontmatter 部分で判定ロジックを完結させます。
typescript
---
/**
* Server-side language detection using Vercel Edge Headers
* @see <https://vercel.com/docs/edge-network/headers>
*/
const headers = Astro.request.headers;
// 1. Vercelが付与する国コードを取得 ("JP", "US", "SG" 等)
const ipCountry = headers.get("x-vercel-ip-country");
// 2. フォールバック: ブラウザの言語設定を確認
const acceptLanguage = headers.get("accept-language") || "";
const prefersJapanese = acceptLanguage.toLowerCase().startsWith("ja");
// 3. 判定ロジック(日本なら日本語、それ以外は英語をデフォルトに)
let initialLang: "ja" | "en" = "en";
if (ipCountry === "JP") {
initialLang = "ja";
} else if (!ipCountry && prefersJapanese) {
// ローカル開発環境などヘッダーが存在しない場合の救済措置
initialLang = "ja";
}
---
クライアントサイドへの受け渡し(Hydration対策)
サーバー側で決定した initialLang を、ReactやVanilla JSで参照できるように window オブジェクトへ注入します。これにより、クライアントサイドでの再判定による「画面のガタつき」を防ぎます。
html
<!doctype html>
<html lang={initialLang}>
<head>
<meta charset="UTF-8" />
<title>Global SaaS App</title>
</head>
<body>
<!-- サーバー変数をインラインスクリプトで安全に受け渡す -->
<script is:inline define:vars={{ initialLang }}>
window.__INITIAL_LANG__ = initialLang;
</script>
<script>
// クライアントサイドのJSで即座に参照
const currentLang = window.__INITIAL_LANG__ || "en";
console.log(`Current Language: ${currentLang}`);
</script>
</body>
</html>
この手法のメリット
- パフォーマンス: 外部へのHTTPリクエストが発生しないため、TTFB(Time to First Byte)に悪影響を与えません。
- 信頼性: Vercelのエッジネットワークで判定されるため、プロキシ経由でない限り非常に正確です。
- 保守性: 特殊なライブラリに依存せず、標準のWeb標準(Headers API)のみで完結します。
まとめ
「海外ユーザーには英語、国内には日本語」という出し分けに対応するシンプルな手法を紹介しました。x-vercel-ip-country を活用することで、最高速のUXを最小コストで実現しましょう。