العربية

تعلم كيفية تطبيق التدويل (i18n) بسلاسة في تطبيقات Next.js للوصول إلى جمهور عالمي. يغطي التوجيه وترجمة المحتوى وأفضل الممارسات.

تدويل Next.js: بناء تطبيقات متعددة اللغات لجمهور عالمي

في عالم اليوم المترابط، لم يعد بناء التطبيقات التي تلبي احتياجات جمهور عالمي ترفًا - بل أصبح ضرورة. يوفر Next.js، وهو إطار عمل قوي لـ React، ميزات قوية لتطبيق التدويل (i18n)، مما يسمح لك بإنشاء تطبيقات متعددة اللغات تقدم تجربة محلية للمستخدمين في جميع أنحاء العالم. سيرشدك هذا الدليل الشامل عبر المفاهيم والتقنيات وأفضل الممارسات الأساسية لبناء تطبيقات Next.js مدوّلة.

فهم التدويل والتوطين

قبل الغوص في تفاصيل تدويل Next.js، دعنا نوضح المصطلحات الرئيسية:

بشكل أساسي، يقوم التدويل (i18n) بإعداد تطبيقك للتوطين. من خلال فصل العناصر المعتمدة على اللغة عن الكود الأساسي، فإنك تجعل من السهل توطين التطبيق لأسواق مختلفة.

لماذا يجب تطبيق التدويل في Next.js؟

يوفر تطبيق التدويل في تطبيق Next.js الخاص بك العديد من الفوائد:

ميزات وإعدادات تدويل Next.js

يقدم Next.js دعمًا مدمجًا للتدويل من خلال ميزات التوجيه وإدارة المحتوى. فيما يلي تفصيل للميزات المهمة:

1. إعداد التدويل في next.config.js

يوجد التكوين الأساسي للتدويل داخل ملف next.config.js. إليك مثال:


/** @type {import('next').NextConfig} */
const nextConfig = {
  i18n: {
    locales: ['en', 'es', 'fr'], // مصفوفة من اللغات المدعومة (رموز اللغات)
    defaultLocale: 'en', // اللغة الافتراضية المراد استخدامها
    localeDetection: true, // تفعيل/تعطيل الكشف التلقائي عن اللغة بناءً على إعدادات المتصفح (اختياري)
    //  domains: [
    //  {
    //    domain: 'example.com',
    //    defaultLocale: 'en',
    //  },
    //  {
    //    domain: 'example.es',
    //    defaultLocale: 'es',
    //  },
    //  ],
  },
}

module.exports = nextConfig;

الشرح:

2. التوجيه باستخدام بادئات اللغة (Locale Prefixes)

يقوم Next.js تلقائيًا بإضافة بادئة اللغة إلى المسارات. على سبيل المثال، إذا كان لديك صفحة على /about واللغة هي 'es' (الإسبانية)، فسيصبح عنوان URL هو /es/about. يمكّن هذا من وجود إصدارات لغات مختلفة من الصفحات ويسمح لمحركات البحث بفهرسة المحتوى لكل لغة. يتولى إطار العمل إعادة التوجيه والتوجيه نيابة عنك.

3. استخدام خطاف useRouter

يوفر خطاف (hook) useRouter من next/router الوصول إلى اللغة الحالية ومعلومات التوجيه الأخرى.


import { useRouter } from 'next/router';

function MyComponent() {
  const router = useRouter();
  const { locale, locales, defaultLocale } = router;

  return (
    

Current locale: {locale}

Available locales: {locales.join(', ')}

Default locale: {defaultLocale}

); } export default MyComponent;

يقدم كائن router الخصائص الرئيسية التالية:

استراتيجيات ترجمة المحتوى

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

1. استخدام نظام إدارة ترجمة مخصص (TMS)

بالنسبة للمشاريع واسعة النطاق التي تحتوي على العديد من اللغات، يوصى بشدة باستخدام نظام إدارة الترجمة (TMS). تشمل الخيارات الشائعة ما يلي:

الفوائد:

2. إنشاء ملفات ترجمة JSON

بالنسبة للمشاريع الأصغر، يعد استخدام ملفات JSON لتخزين الترجمات طريقة بسيطة وفعالة.

مثال على بنية المجلدات:


/src
├── locales
│   ├── en.json
│   └── es.json
├── components
│   └── MyComponent.js
└── pages
    └── index.js

مثال en.json:


{
  "greeting": "Hello, world!",
  "welcomeMessage": "Welcome to our website."
}

مثال es.json:


{
  "greeting": "¡Hola, mundo!",
  "welcomeMessage": "Bienvenido a nuestro sitio web."
}

مثال MyComponent.js:


import { useRouter } from 'next/router';
import en from '../locales/en.json';
import es from '../locales/es.json';

function MyComponent() {
  const { locale } = useRouter();
  const t = locale === 'es' ? es : en;

  return (
    

{t.greeting}

{t.welcomeMessage}

); } export default MyComponent;

يوفر هذا النهج المرونة وهو مباشر للمشاريع الصغيرة. من السهل عمومًا تحديثه وصيانته.

3. استخدام مكتبة ترجمة

تعمل العديد من مكتبات JavaScript على تبسيط ترجمة المحتوى داخل مكونات React الخاصة بك.

مثال مع next-i18next (التثبيت: npm install next-i18next i18next react-i18next):

أنشئ ملف تكوين i18n (على سبيل المثال، i18n.js في مجلدك الجذر):


// i18n.js
import { createServerSideHelpers } from 'next-i18next'
import { i18n } from './next-i18next.config'

export function initI18next(req, res, namespaces = ['common']) {
  const helpers = createServerSideHelpers(
    req, 
    res, 
    i18n, 
    namespaces
  )

  return helpers
}

export { appWithTranslation } from 'next-i18next'
export { i18n }

أنشئ تكوين Next.js الخاص بك لـ next-i18next.


// next-i18next.config.js
const { i18n } = require('./next-i18next.config');

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'es', 'fr'],
  },
  // other configuration
}

module.exports = nextConfig

أضف التكوين واستيراد الترجمة إلى ملف _app.js الخاص بك:


import { appWithTranslation } from 'next-i18next';
import '../styles/globals.css';

function MyApp({ Component, pageProps }) {
  return ;
}

export default appWithTranslation(MyApp);

أنشئ مجلدًا واملأه باللغات الخاصة بترجماتك.


/public
└── locales
    ├── en
    │   └── common.json
    ├── es
    │   └── common.json
    └── fr
        └── common.json

مثال en/common.json:


{
  "greeting": "Hello, world!",
  "welcomeMessage": "Welcome to our website."
}

استخدام الترجمة في مكون:


import { useTranslation } from 'next-i18next';

function MyComponent() {
  const { t } = useTranslation('common');

  return (
    

{t('greeting')}

{t('welcomeMessage')}

); } export default MyComponent;

يستخدم هذا المثال خطاف useTranslation لاسترداد الترجمات بناءً على اللغة الحالية.

التعامل مع المسارات الديناميكية والتوليد الساكن للمواقع (SSG)

يصبح التدويل أكثر تعقيدًا عند التعامل مع المسارات الديناميكية (مثل منشورات المدونات وصفحات المنتجات) والتوليد الساكن للمواقع (SSG).

1. المسارات الديناميكية (مثلًا /blog/[slug])

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


export async function getStaticPaths() {
  const paths = [];
  const locales = ['en', 'es', 'fr'];
  const posts = await fetchPosts(); // جلب بيانات منشورات المدونة

  posts.forEach(post => {
    locales.forEach(locale => {
      paths.push({
        params: {
          slug: post.slug,
        },
        locale,
      });
    });
  });

  return {
    paths,
    fallback: false, // أو 'blocking' إذا كنت تريد إظهار حالة التحميل
  };
}

export async function getStaticProps({ params, locale }) {
  const post = await getPostBySlug(params.slug, locale);

  return {
    props: {
      post,
    },
  };
}

الشرح:

2. التوليد الساكن للمواقع (SSG) مع getStaticProps

في getStaticProps، يمكنك جلب المحتوى المترجم بناءً على معلم locale.


export async function getStaticProps({ params, locale }) {
  // جلب المحتوى بناءً على اللغة والمعلمات
  const { post } = await getPostBySlug(params.slug, locale);

  return {
    props: {
      post,
    },
  };
}

يجب أن تجلب دالة getPostBySlug المحتوى المترجم للـ slug واللغة المحددين، والذي يمكن استرداده من ملفات الترجمة الخاصة بك، أو قاعدة البيانات، أو نظام إدارة المحتوى (CMS).

3. العرض من جانب الخادم (SSR) مع getServerSideProps

للمحتوى الذي يجب جلبه في وقت الطلب، استخدم getServerSideProps. هذا مفيد إذا كان المحتوى يتغير بشكل متكرر أو مخصص لكل مستخدم.


export async function getServerSideProps({ params, locale, req, res }) {
  // جلب البيانات بناءً على اللغة والمعلمات (على سبيل المثال، من قاعدة بيانات)
  const data = await fetchData(params.slug, locale);

  return {
    props: {
      data,
    },
  };
}

أفضل الممارسات لتدويل Next.js

سيساعدك اتباع أفضل الممارسات هذه على بناء تطبيقات متعددة اللغات قوية وقابلة للصيانة وسهلة الاستخدام:

اعتبارات تحسين محركات البحث (SEO) للمواقع المدوّلة

يعد تحسين موقعك المدوّل لمحركات البحث أمرًا ضروريًا لجذب حركة المرور العضوية من جميع أنحاء العالم. إليك بعض أفضل ممارسات SEO الرئيسية:

مثال: بناء مدونة بسيطة متعددة اللغات

دعنا ننشئ مثالًا مبسطًا لمدونة متعددة اللغات باستخدام Next.js. سيوفر هذا توضيحًا أكثر واقعية لكيفية تطبيق المفاهيم التي تمت مناقشتها أعلاه.

1. إعداد المشروع

أنشئ مشروع Next.js جديدًا:


npx create-next-app my-multi-lang-blog
cd my-multi-lang-blog

2. تكوين i18n (next.config.js)


/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  i18n: {
    locales: ['en', 'es', 'fr'],
    defaultLocale: 'en',
  },
}

module.exports = nextConfig

3. إنشاء ملفات الترجمة

أنشئ مجلد locales في الدليل الجذر وأضف ملفات JSON التالية:

locales/en.json:


{
  "title": "Welcome to My Blog",
  "postTitle": "My First Post",
  "postContent": "This is the content of my first blog post."
}

locales/es.json:


{
  "title": "Bienvenido a mi Blog",
  "postTitle": "Mi Primer Post",
  "postContent": "Este es el contenido de mi primer publicación de blog."
}

locales/fr.json:


{
  "title": "Bienvenue sur Mon Blog",
  "postTitle": "Mon Premier Article",
  "postContent": "Ceci est le contenu de mon premier article de blog."
}

4. إنشاء مكون منشور المدونة (e.g., components/BlogPost.js)


import { useRouter } from 'next/router';
import en from '../locales/en.json';
import es from '../locales/es.json';
import fr from '../locales/fr.json';

function BlogPost() {
  const router = useRouter();
  const { locale } = router;

  let translations;
  switch (locale) {
    case 'es':
      translations = es;
      break;
    case 'fr':
      translations = fr;
      break;
    default:
      translations = en;
  }

  return (
    

{translations.postTitle}

{translations.postContent}

); } export default BlogPost;

5. إنشاء الصفحة الرئيسية (pages/index.js)


import { useRouter } from 'next/router';
import BlogPost from '../components/BlogPost';
import en from '../locales/en.json';
import es from '../locales/es.json';
import fr from '../locales/fr.json';

function HomePage() {
  const router = useRouter();
  const { locale, locales } = router;

  let translations;
  switch (locale) {
    case 'es':
      translations = es;
      break;
    case 'fr':
      translations = fr;
      break;
    default:
      translations = en;
  }

  return (
    

{translations.title}

{locales.map((l) => ( {l.toUpperCase()} ))}
); } export default HomePage;

يعرض هذا المثال المبسط المبادئ الأساسية لتدويل Next.js. يمكنك التوسع في هذا الإطار الأساسي لتضمين ميزات أكثر تعقيدًا، مثل المسارات الديناميكية والتكامل مع أنظمة إدارة الترجمة. فكر في تحسين الروابط أعلاه باستخدام مكون Link وإضافة السمة locale المناسبة.

6. تشغيل التطبيق

شغّل التطبيق باستخدام:


npm run dev

الآن يمكنك الوصول إلى مدونتك على http://localhost:3000 (الإنجليزية)، و http://localhost:3000/es (الإسبانية)، و http://localhost:3000/fr (الفرنسية). يجب أن ترى العنوان ومحتوى منشور المدونة مترجمين بناءً على اللغة المحددة.

الخاتمة

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

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