多言語対応 X (旧Twitter) リンク切り替え実装ガイド

ブラウザの言語設定に応じて、日本語ユーザーとそれ以外のユーザーで異なる X アカウントへ誘導するための実装方法について説明します。 本実装は Chrome および Safari 両方の言語設定取得仕様に対応しています。

概要

実装ロジック

ブラウザによって言語設定のプロパティ参照優先度が異なるため、以下の順序で判定を行います。

  1. navigator.languages[0]: ユーザーが設定した優先言語リストの1番目(主にChromeでユーザーの好みを正確に反映)
  2. navigator.language: ブラウザのUI言語設定(Safariや古い環境へのフォールバック)
  3. 'en': 取得できなかった場合のデフォルト

判定コード (TypeScript / JavaScript)

/**
 * ユーザーのブラウザ言語設定に基づいて適切なX(Twitter)のURLを返します。
 * 
 * - Chrome: navigator.languages[0] を優先
 * - Safari: navigator.language をフォールバックとして使用
 */
const getTwitterUrl = (): string => {
  // ブラウザの言語設定を取得
  // navigator.languages が存在する場合はその先頭、なければ navigator.language、それもなければ 'en'
  const primaryLanguage = (navigator.languages && navigator.languages[0]) || navigator.language || 'en';
  
  // 大文字小文字を区別せず "ja" で始まるかチェック
  const isJapanese = primaryLanguage.toLowerCase().startsWith('ja');

  // 言語に応じてURLを切り替え
  return isJapanese
    ? 'https://x.com/tsuchi_ya_84'  // 日本語ユーザー向け
    : 'https://x.com/Tsuchiya_84';    // その他の言語ユーザー向け
};

React / Next.js での実装例

コンポーネント内での使用例です。Next.js (App Router / Pages Router) などのSSR環境で使用する場合は、window オブジェクトや navigator オブジェクトへのアクセスがクライアントサイドでのみ行われるように注意してください。

"use client"; // Next.js App Routerの場合

import React from 'react';

export default function XLinkButton() {
  
  const handleLinkClick = () => {
    // サーバーサイド実行時のエラーを防ぐためのチェック (任意)
    if (typeof window === 'undefined') return;

    const primaryLanguage = (navigator.languages && navigator.languages[0]) || navigator.language || 'en';
    const isJapanese = primaryLanguage.toLowerCase().startsWith('ja');

    const targetUrl = isJapanese
      ? 'https://x.com/tsuchi_ya_84'
      : 'https://x.com/Tsuchiya_84';

    // 新しいタブで開く
    window.open(targetUrl, '_blank');
  };

  return (
    <button onClick={handleLinkClick}>
      X (旧Twitter) をフォローする
    </button>
  );
}

ポイント

  1. Chrome と Safari の差異吸収: navigator.languages[0] を優先することで、Chromeのように複数の言語設定を持てるブラウザで「ユーザーが一番優先している言語」を取得できます。一方で、これが未定義の場合に navigator.language を見ることで Safari 等にも対応します。

  2. 前方一致判定: startsWith('ja') を使用することで、ja (日本語) だけでなく ja-JP (日本語-日本) などのバリエーションも漏れなく日本語として扱います。