انتقل إلى المحتوى الرئيسي
شرح تطبيقي

بناء مواقع ويب ثنائية اللغة (العربية/الإنجليزية) باستخدام Next.js ودعم اتجاه الكتابة من اليمين لليسار

4 دقائق قراءة

كيفية بناء مواقع ويب ثنائية اللغة (العربية/الإنجليزية) باستخدام Next.js مع تجنب الأخطاء الشائعة المتعلقة باتجاه الكتابة من اليمين لليسار.

Next.jsArabicRTLbilingual websitesUI/UXTypeScriptNext.js i18n

في الخريف الماضي، قضيت ثلاث ساعات في استكشاف سبب ظهور مُبدِّل اللغة العربية لدى أحد العملاء وكأنه يعاني من نوبة صرع عندما ظهر نص عربي في حاويات إنجليزية. والمثير حقًا؟ لم تكن المشكلة تتعلق بشيفرة مُبدِّل اللغة نفسه. المزيد عن هذه الفوضى لاحقًا.

لم يكن هذا مجرد مشروع عادي. احتاج نظام أساسي للعقارات كنت أقوم ببنائه لأحد العملاء في الإمارات العربية المتحدة إلى دعم كامل للغة ثنائية - اللغة العربية كلغة أساسية واللغة الإنجليزية كلغة ثانوية. لقد أرادوا أن يتمكن المستخدمون من التبديل بسلاسة بين اللغات، مع تصميم مناسب من اليمين إلى اليسار (RTL) للغة العربية ومن اليسار إلى اليمين (LTR) القياسي للغة الإنجليزية. سهل بما فيه الكفاية على الورق، أليس كذلك؟

الإعداد: Next.js i18n واتجاه النص

كانت الأدوات الأساسية واضحة ومباشرة:

  1. next-i18next لمعالجة الترجمة
  2. خطاف مخصص لإدارة اتجاه المستند (dir attribute)
  3. تعديلات RTL على مستوى المكون باستخدام styled-jsx

إليك كيفية هيكلة إعدادات Next.js:

js
// next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'ar'],
    defaultLocale: 'en',
  },
}

لتصميم مكونات RTL، استخدمت الفئة الزائفة :dir() في CSS بدلاً من تكرار أوراق الأنماط. حافظ هذا على نظافة قاعدة الشيفرة وتجنب مضاعفة حجم حزمة CSS:

jsx
// Header component styles
export default function Header() {
  return (
    <style jsx>{`
      :dir(rtl) .title {
        font-family: 'Almarai', sans-serif !important;
      }
    `}</style>
  )
}

أول مأزق كبير: تنسيق التاريخ

في منتصف المشروع، أدركت أن النظام الأساسي يحتاج إلى عرض التواريخ بكلتا اللغتين. افترضت أن moment.js ستتعامل مع التواريخ العربية خارج الصندوق. كنت مخطئا.

ما بدا وكأنه moment.locale('ar') بسيط تحول إلى جلسة تصحيح أخطاء استمرت 8 ساعات عندما ظهرت التواريخ العربية بتنسيق "Dhu al-Qi'dah 14, 2023" بدلاً من التنسيق المطلوب "١٤ ذو القعدة ١٤٤٤ هـ". ما الحل؟ التخلص من moment.js تمامًا واستخدام Hijri.js مع تنسيق مخصص.

اتجاه اللغة وسمات HTML

كانت علامة <html> الخاصة بالمستند بحاجة إلى التبديل بين dir="rtl" و dir="ltr" بناءً على اللغة. كان يجب أن يعمل هذا من جانب الخادم لتحسين محركات البحث (SEO) ومن جانب العميل للتبديل الديناميكي. إليك كيف أدرت الأمر:

jsx
// _document.tsx
export default function Document() {
  const locale = useRouter().locale
  const dir = locale === 'ar' ? 'rtl' : 'ltr'
  
  return (
    <Html dir={dir} lang={locale}>
      ...
    </Html>
  )
}

للتبديل الديناميكي للغة دون إعادة تحميل الصفحة، قمت بإنشاء موفر سياق قام بتحديث سمة اتجاه HTML وتعامل مع الرسوم المتحركة الانتقالية بين الصفحات. تطلب هذا تصحيح الموجّه الخاص بـ Next.js لمنع عمليات إعادة التحميل الكاملة عند تبديل اللغات.

الأكورديون الذي حطم كل شيء

في إحدى الليالي، قمت بنشر ما كان يجب أن يكون تحديثًا بسيطًا لواجهة المستخدم: إضافة قسم أكورديون للأسئلة الشائعة. عندما اختبر فريق ضمان الجودة ذلك في الوضع العربي، تحول تخطيط المحتوى بالكامل بمقدار 40 بكسل إلى اليسار. اتضح أنني نسيت أن خصوصية :dir(ltr) .class تفوق خصوصية :dir(rtl) .class في styled-jsx. ما الحل؟ التبديل إلى محددات [dir="rtl"] .class ومضاعفة حجم الخط في أدوات المطورين لاكتشاف مشكلات المحاذاة المخفية.

مثال واقعي: Reach Home Properties

كانت متطلبات ثنائية اللغة لمنصة العقارات هذه مكثفة. يتوقع عملاء الإمارات العربية المتحدة ما يلي:

  • •اللغة العربية هي اللغة الافتراضية (ولكن ليس في كل مكان - غالبًا ما تفضل مواقع حكومة الشارقة اللغة الإنجليزية أولاً)
  • •تصميم RTL يعمل داخل رسائل البريد الإلكتروني بتنسيق HTML (كان علينا إنشاء محرك قوالب بريد إلكتروني منفصل لذلك)
  • •تنسيق تاريخ عربي مناسب يراعي الاختلافات في التقويم الهجري

تعاملنا مع هذه الأمور بمزيج من العرض من جانب الخادم لتحسين محركات البحث (SEO) ومبدل لغة قام بتخزين التفضيلات في ملف تعريف الارتباط (cookie) مع مدة صلاحية 24 ساعة. تمت إعادة استخدام الحل عبر ثلاث منصات عقارية أخرى في دول مجلس التعاون الخليجي بعد هذا المشروع.

مآزق النشر

عندما انتقلنا من التطوير إلى الإنتاج، بدأ تطهير CSS في Tailwind في إزالة أدوات RTL مثل *:dir(rtl) لأنها لم تكن موجودة في أنماط محتوى التطهير لدينا. ظهر هذا على شكل أنماط RTL مفقودة فقط في إصدارات الإنتاج. تم إصلاحه عن طريق:

  1. إضافة نمط regex لـ dir(rtl) في إعدادات Tailwind
  2. إنشاء ملف CSS مشترك فقط لتجاوزات RTL
  3. الاختبار في وضع التصفح المتخفي مع حقن ملف تعريف الارتباط (cookie) لمحاكاة المستخدمين الجدد

الصلصة السرية: الاختبار كأشخاص حقيقيين

لم تلتقط الاختبارات الآلية سوى 60٪ من المشكلات المرئية. تطلب الـ 40٪ الأخرى ما يلي:

  • •وجود متحدثين أصليين للغة العربية يقومون بالاختبار في متصفحات فعلية
  • •استخدام "text-orientation: sideways" في Chrome DevTools لمحاكاة الكتابة العمودية (على الرغم من أننا لم نكن بحاجة إليها هنا)
  • •التحقق المتبادل من عرض الخط في iOS Safari مقابل Android Chrome

بالنسبة لفريق العميل في أبو ظبي، قمت ببناء بوابة اختبار لغة أظهرت مقارنات جنبًا إلى جنب للمكونات بكلتا اللغتين. لقد أحبوا وجود مكان للإبلاغ عن مشكلات المحاذاة دون غربلة مستندات ضمان الجودة المكونة من 80 صفحة.


يصبح هذا العمل أكثر تعقيدًا في كل مرة تضيف فيها لغة أخرى، ولكن تبقى الأساسيات كما هي: التحكم في اتجاه المستند، والتعامل مع اختيارات الخط بعناية، وعدم الوثوق أبدًا بمكتبات التاريخ الافتراضية للقيام بالشيء الصحيح بتنسيقات اللغة العربية.

إذا علقت يومًا ما في مشكلات RTL في Next.js أو كنت بحاجة إلى مساعدة في جعل مواقع الويب ثنائية اللغة تبدو طبيعية لمستخدمي الإمارات العربية المتحدة، فتواصل معي على sarahprofile.com/contact. ربما صرخت بالفعل في الفراغ بشأن مشكلتك بالضبط.

S

سارة

مطوّرة Full-Stack أولى ومعتمدة PMP — أبوظبي، الإمارات

أكثر من 7 سنوات في بناء تطبيقات ويب لشركات الإمارات والخليج. متخصصة في Laravel وNext.js وتطوير مواقع RTL العربية.

تعاون مع سارة