右から左(RTL)レイアウトのサポート

アラビア語やヘブライ語などの言語に合わせたレイアウトの適応

問題

アプリケーションのレイアウトは、margin-leftpadding-rightなどのCSSプロパティで構築されており、左から右(LTR)のテキスト方向を前提としています。アプリケーションがアラビア語やヘブライ語などのRTL言語に翻訳されると、レイアウト全体が逆向きに表示され、コンテンツの配置がずれて読めなくなります。

解決策

方向性のあるCSSプロパティ(left/right)から、方向に依存しない論理的な同等プロパティ(start/end)に切り替えます。現在の言語に基づいて<html>要素にdir属性を設定すると、ブラウザが自動的にレイアウトを正しく反転します。

手順

1. RTL言語を定義する

まず、サポートしている言語のうちどれがRTLであるかを知る方法が必要です。

この情報を保存するために、新しいファイルapp/i18n-config.tsを作成します(または既存のファイルを更新します)。

// i18n-config.ts

export const locales = ['en', 'es', 'ar', 'he']; // ar=Arabic, he=Hebrew
export const defaultLocale = 'en';
export const localeCookieName = 'NEXT_LOCALE';

export const rtlLocales = ['ar', 'he'];

2. ルートレイアウトでdir属性を設定する

app/[lang]/layout.tsxを変更して、<html>タグにdir(方向)属性を条件付きで追加します。

// app/[lang]/layout.tsx
import { rtlLocales } from '@/i18n-config';

export async function generateStaticParams() {
  return [{ lang: 'en' }, { lang: 'es' }, { lang: 'ar' }, { lang: 'he' }];
}

export default async function RootLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: { lang: string };
}) {
  // Determine if the current language is RTL
  const isRtl = rtlLocales.includes(params.lang);

  return (
    <html lang={params.lang} dir={isRtl ? 'rtl' : 'ltr'}>
      <body>
        {/* ...your providers and content... */}
        {children}
      </body>
    </html>
  );
}

<html>タグにdir="rtl"を追加することで、このページのドキュメントフロー全体が右から左であることをブラウザに伝えています。

3. CSSを論理プロパティに更新する

グローバルCSSとコンポーネントスタイルを確認します。すべての方向性プロパティを論理的な同等プロパティに置き換えます。

  • margin-leftmargin-inline-startになります
  • margin-rightmargin-inline-endになります
  • padding-leftpadding-inline-startになります
  • padding-rightpadding-inline-endになります
  • left(位置指定)はinset-inline-startになります
  • right(位置指定)はinset-inline-endになります
  • text-align: lefttext-align: startになります
  • text-align: righttext-align: endになります

例:

変更前(方向指定):

.card {
  padding-left: 16px;
  border-left: 4px solid blue;
}
.title {
  text-align: left;
}

変更後(論理指定):

.card {
  padding-inline-start: 16px;
  border-inline-start: 4px solid blue;
}
.title {
  text-align: start;
}

ユーザーが/endir="ltr")にアクセスすると、padding-inline-startが左側に適用されます。ユーザーが/ardir="rtl")にアクセスすると、ブラウザは自動的にpadding-inline-startを右側に適用し、コンポーネントのレイアウトを正しく反転させます。