Поддержка макетов с направлением справа налево (RTL)

Адаптация макета для языков, таких как арабский и иврит

Проблема

Макет приложения строится с помощью CSS-свойств, таких как margin-left и padding-right, которые предполагают направление текста слева направо (LTR). Когда приложение переводится на RTL-язык, например, арабский или иврит, весь макет отображается наоборот, контент смещается и становится нечитаемым.

Решение

Перейдите от направленных CSS-свойств (left/right) к их современным, независимым от направления логическим аналогам (start/end). Установите атрибут dir на элементе <html> в зависимости от текущего языка, и браузер автоматически правильно отобразит макет.

Шаги

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, чтобы условно добавлять атрибут dir (direction) к тегу <html>.

// 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>
  );
}

Добавляя dir="rtl" к тегу <html>, вы сообщаете браузеру, что весь поток документа для этой страницы должен быть справа налево.

3. Обновите CSS, чтобы использовать логические свойства

Просмотрите ваши глобальные CSS и стили компонентов. Замените все направленные свойства на их логические аналоги.

  • margin-left становится margin-inline-start
  • margin-right становится margin-inline-end
  • padding-left становится padding-inline-start
  • padding-right становится padding-inline-end
  • left (в позиционировании) становится inset-inline-start
  • right (в позиционировании) становится inset-inline-end
  • text-align: left становится text-align: start
  • text-align: right становится text-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;
}

Когда пользователь заходит на /en (dir="ltr"), padding-inline-start применяется слева. Когда пользователь заходит на /ar (dir="rtl"), браузер автоматически применяет padding-inline-start справа, корректно переворачивая ваш компонент.