تعلم كيفية تطبيق التدويل (i18n) بسلاسة في تطبيقات Next.js للوصول إلى جمهور عالمي. يغطي التوجيه وترجمة المحتوى وأفضل الممارسات.
تدويل Next.js: بناء تطبيقات متعددة اللغات لجمهور عالمي
في عالم اليوم المترابط، لم يعد بناء التطبيقات التي تلبي احتياجات جمهور عالمي ترفًا - بل أصبح ضرورة. يوفر Next.js، وهو إطار عمل قوي لـ React، ميزات قوية لتطبيق التدويل (i18n)، مما يسمح لك بإنشاء تطبيقات متعددة اللغات تقدم تجربة محلية للمستخدمين في جميع أنحاء العالم. سيرشدك هذا الدليل الشامل عبر المفاهيم والتقنيات وأفضل الممارسات الأساسية لبناء تطبيقات Next.js مدوّلة.
فهم التدويل والتوطين
قبل الغوص في تفاصيل تدويل Next.js، دعنا نوضح المصطلحات الرئيسية:
- التدويل (i18n): عملية تصميم وتطوير تطبيق بحيث يمكن تكييفه بسهولة مع مختلف اللغات والمناطق دون الحاجة إلى تغييرات هندسية. يتضمن ذلك تجريد النصوص والتنسيقات والعناصر الأخرى الخاصة باللغة.
- التوطين (l10n): عملية تكييف تطبيق للغة ومنطقة معينة. يشمل ذلك ترجمة النصوص، وتعديل تنسيقات التاريخ والوقت، ورموز العملات، والمزيد.
بشكل أساسي، يقوم التدويل (i18n) بإعداد تطبيقك للتوطين. من خلال فصل العناصر المعتمدة على اللغة عن الكود الأساسي، فإنك تجعل من السهل توطين التطبيق لأسواق مختلفة.
لماذا يجب تطبيق التدويل في Next.js؟
يوفر تطبيق التدويل في تطبيق Next.js الخاص بك العديد من الفوائد:
- توسيع نطاق الوصول: الوصول إلى جمهور أوسع من خلال توفير المحتوى بلغتهم المفضلة.
- تحسين تجربة المستخدم: تقديم تجربة أكثر تخصيصًا وجاذبية للمستخدمين في مناطق مختلفة.
- تحسين محركات البحث (SEO): تحسين أداء موقعك في محركات البحث (SEO) من خلال توفير محتوى موطّن يستهدف مناطق جغرافية محددة.
- زيادة التحويلات: زيادة معدلات التحويل من خلال تقديم المعلومات بلغة المستخدم الأصلية، مما يعزز الثقة والفهم.
- حضور عالمي للعلامة التجارية: تأسيس حضور أقوى للعلامة التجارية على مستوى العالم من خلال إظهار الالتزام بالشمولية وتلبية احتياجات الجماهير المتنوعة.
ميزات وإعدادات تدويل 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;
الشرح:
locales
: مصفوفة تحتوي على رموز اللغات (مثل'en'
للإنجليزية،'es'
للإسبانية،'fr'
للفرنسية) التي يدعمها تطبيقك. تأكد من اتباع رموز اللغات ISO 639-1 للاتساق.defaultLocale
: اللغة الافتراضية التي سيستخدمها تطبيقك. هذه هي اللغة التي يتم عرضها إذا لم يتم تحديد لغة أخرى في عنوان URL أو اكتشافها من إعدادات متصفح المستخدم. اختر لغة تمثل جمهورك المستهدف الأساسي.localeDetection
: قيمة منطقية (boolean) تتحكم في ما إذا كان Next.js يكتشف تلقائيًا لغة المستخدم المفضلة بناءً على إعدادات متصفحه. إذا تم تعيينها علىtrue
، فسيحاول Next.js إعادة توجيه المستخدم إلى إصدار اللغة المناسب من موقعك.domains
(اختياري): مصفوفة تسمح لك بربط اللغات بنطاقات محددة. هذا مفيد إذا كان لديك نطاقات منفصلة للغات مختلفة (على سبيل المثال،example.com
للإنجليزية،example.es
للإسبانية).
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
الخصائص الرئيسية التالية:
locale
: اللغة المحددة حاليًا (على سبيل المثال، 'en', 'es', 'fr').locales
: مصفوفة بجميع اللغات المدعومة المحددة فيnext.config.js
.defaultLocale
: اللغة الافتراضية المحددة فيnext.config.js
.asPath
: المسار كما هو معروض في المتصفح، بما في ذلك بادئة اللغة (على سبيل المثال،/es/about
).pathname
: المسار بدون بادئة اللغة (على سبيل المثال،/about
).
استراتيجيات ترجمة المحتوى
بمجرد إعداد تطبيق Next.js الخاص بك للتدويل، ستحتاج إلى تنفيذ استراتيجيات لترجمة المحتوى الخاص بك. إليك العديد من الأساليب الشائعة:
1. استخدام نظام إدارة ترجمة مخصص (TMS)
بالنسبة للمشاريع واسعة النطاق التي تحتوي على العديد من اللغات، يوصى بشدة باستخدام نظام إدارة الترجمة (TMS). تشمل الخيارات الشائعة ما يلي:
- Phrase: نظام TMS قائم على السحابة مع تكاملات لمنصات مختلفة، بما في ذلك Next.js. يقدم ميزات تعاونية وسير عمل آلي.
- Localize: نظام TMS آخر قائم على السحابة يدعم مجموعة واسعة من تنسيقات الملفات ويوفر ميزات إدارة الترجمة.
- Crowdin: نظام TMS قوي وشائع جدًا في مجتمع المصادر المفتوحة، ويتكامل بشكل جيد مع Next.js، مما يسمح للفرق بترجمة المحتوى بكفاءة.
الفوائد:
- إدارة مركزية للترجمة.
- ميزات التعاون للمترجمين.
- أتمتة سير عمل الترجمة.
- التكامل مع سير عمل التطوير الخاص بك.
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
: مكتبة شائعة مصممة خصيصًا لـ Next.js. تتكامل بشكل جيد مع إطار العمل وتوفر ميزات مثل العرض من جانب الخادم (SSR) والترجمة من جانب العميل.react-i18next
: مكتبة تدويل للأغراض العامة لـ React. يمكنك استخدامها في تطبيقات Next.js الخاصة بك، على الرغم من أنها قد تتطلب تكوينًا أكثر مقارنة بـnext-i18next
.
مثال مع 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,
},
};
}
الشرح:
getStaticPaths
: تكرر هذه الدالة عبر منشورات مدونتك وتنشئ مسارًا لكل منشور وكل لغة. يحتوي كائنparams
على معلمات المسار (على سبيل المثال، slug منشور المدونة).locale
: يوفر هذا المعلم اللغة الحالية، مما يتيح لك جلب المحتوى المترجم للغة المحددة.fallback
: يحدد كيفية تعامل Next.js مع المسارات غير المحددة فيgetStaticPaths
.fallback: false
ينشئ صفحات 404 للمسارات غير المحددة.fallback: 'blocking'
يعرض الصفحات مسبقًا عند الطلب.
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
سيساعدك اتباع أفضل الممارسات هذه على بناء تطبيقات متعددة اللغات قوية وقابلة للصيانة وسهلة الاستخدام:
- التخطيط المبكر: فكر في التدويل منذ بداية مشروعك. من الأسهل بكثير تنفيذه مقدمًا بدلاً من تعديله لاحقًا.
- فصل المحتوى عن الكود: قم بتخزين جميع النصوص القابلة للترجمة في ملفات منفصلة (مثل ملفات JSON أو نظام TMS) وتجنب ترميز النصوص مباشرة في مكوناتك.
- استخدام نظام إدارة الترجمة (TMS): بالنسبة للمشاريع الكبيرة، يمكن لنظام TMS تبسيط عملية الترجمة وتحسين التعاون.
- الاختبار الشامل: اختبر تطبيقك بجميع اللغات المدعومة لضمان دقة الترجمات والتنسيق الصحيح والعرض السليم عبر المتصفحات والأجهزة المختلفة. اختبر على أجهزة حقيقية، وليس فقط على المحاكيات.
- مراعاة اللغات من اليمين إلى اليسار (RTL): إذا كنت تدعم لغات مثل العربية أو العبرية، فتأكد من أن تصميمك وتخطيطك يستوعبان اتجاه النص من اليمين إلى اليسار. لا يتعامل Next.js مع هذا تلقائيًا، لذا يلزم استخدام CSS أو حلول أخرى.
- التعامل مع تنسيق التاريخ والوقت: استخدم المكتبات أو الدوال المضمنة لتنسيق التواريخ والأوقات وفقًا للغة المستخدم. Moment.js و date-fns هما مكتبتان شائعتان مفيدتان.
- إدارة تنسيق الأرقام والعملات: قم بتنسيق الأرقام ورموز العملات بشكل صحيح بناءً على لغة المستخدم.
- تحسين محركات البحث (SEO): استخدم علامات التعريف (meta tags) الخاصة باللغة (
hreflang
) لمساعدة محركات البحث على فهرسة المحتوى الخاص بك بشكل صحيح. قم بتضمين رموز اللغات في عناوين URL الخاصة بك. - إعطاء الأولوية لتجربة المستخدم: وفر طريقة واضحة وبديهية للمستخدمين للتبديل بين اللغات. فكر في تقديم اكتشاف تلقائي للغة بناءً على إعدادات المتصفح.
- البقاء على اطلاع: حافظ على تحديث إصدار Next.js ومكتبات i18n الخاصة بك للاستفادة من أحدث الميزات والتصحيحات الأمنية.
- مراعاة إمكانية الوصول (a11y): تأكد من أن المحتوى المترجم الخاص بك متاح للمستخدمين ذوي الإعاقة. قدم نصًا بديلاً للصور واستخدم سمات ARIA المناسبة. استخدم قارئات الشاشة للاختبار.
اعتبارات تحسين محركات البحث (SEO) للمواقع المدوّلة
يعد تحسين موقعك المدوّل لمحركات البحث أمرًا ضروريًا لجذب حركة المرور العضوية من جميع أنحاء العالم. إليك بعض أفضل ممارسات SEO الرئيسية:
- علامات
hreflang
: قم بتطبيق علاماتhreflang
في<head>
لملف HTML الخاص بك لإخبار محركات البحث عن اللغة والتنوعات الإقليمية لمحتواك. هذا أمر بالغ الأهمية لـ SEO. على سبيل المثال:<link rel="alternate" hreflang="en" href="https://example.com/en/" />
و<link rel="alternate" hreflang="es" href="https://example.com/es/" />
- عناوين URL خاصة باللغة: استخدم رموز اللغات في عناوين URL الخاصة بك (على سبيل المثال،
/en/about
,/es/acerca-de
). يشير هذا بوضوح إلى لغة المحتوى لكل من المستخدمين ومحركات البحث. - المحتوى الموطّن: قم بترجمة المحتوى الخاص بك بدقة وبشكل طبيعي. يجب مراجعة الترجمات الآلية بواسطة متحدث أصلي.
- أوصاف وعناوين Meta الموطّنة: اكتب أوصاف وعناوين meta فريدة وجذابة لكل لغة لتحسين معدلات النقر في نتائج البحث.
- خرائط مواقع XML: قم بإنشاء وإرسال خرائط مواقع XML تتضمن جميع تنوعات اللغات لصفحاتك.
- الربط الداخلي: استخدم روابط داخلية مناسبة بين إصدارات اللغات المختلفة لمحتواك.
- بحث الكلمات الرئيسية الخاص بكل بلد: قم بإجراء بحث عن الكلمات الرئيسية في كل لغة لتحديد المصطلحات التي يبحث عنها المستخدمون في كل منطقة.
مثال: بناء مدونة بسيطة متعددة اللغات
دعنا ننشئ مثالًا مبسطًا لمدونة متعددة اللغات باستخدام 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 (
);
}
export default HomePage;
يعرض هذا المثال المبسط المبادئ الأساسية لتدويل Next.js. يمكنك التوسع في هذا الإطار الأساسي لتضمين ميزات أكثر تعقيدًا، مثل المسارات الديناميكية والتكامل مع أنظمة إدارة الترجمة. فكر في تحسين الروابط أعلاه باستخدام مكون Link
وإضافة السمة locale
المناسبة.
6. تشغيل التطبيق
شغّل التطبيق باستخدام:
npm run dev
الآن يمكنك الوصول إلى مدونتك على http://localhost:3000
(الإنجليزية)، و http://localhost:3000/es
(الإسبانية)، و http://localhost:3000/fr
(الفرنسية). يجب أن ترى العنوان ومحتوى منشور المدونة مترجمين بناءً على اللغة المحددة.
الخاتمة
يوفر Next.js مجموعة شاملة من الميزات لتطبيق التدويل في تطبيقات الويب الخاصة بك. باتباع المبادئ والتقنيات الموضحة في هذا الدليل، يمكنك إنشاء تطبيقات متعددة اللغات تقدم تجارب موطّنة للمستخدمين في جميع أنحاء العالم. تذكر أن تخطط لاستراتيجية التدويل الخاصة بك مبكرًا، واختر طريقة الترجمة المناسبة لاحتياجاتك، وأعط الأولوية لتجربة المستخدم. بالتخطيط والتنفيذ الدقيقين، يمكنك بناء تطبيقات تلقى صدى لدى جمهور عالمي وتفتح فرصًا جديدة للنمو. سيضمن التعلم المستمر ومواكبة أحدث الإصدارات وأفضل الممارسات أنك تستخدم أدواتك وتقنياتك بفعالية.
مع تقدم التكنولوجيا، توقع رؤية المزيد من ميزات التدويل المتقدمة. ستبقى القدرة على الوصول إلى المستخدمين عبر الثقافات والمجموعات اللغوية المختلفة أولوية رئيسية لمطوري التطبيقات في جميع أنحاء العالم. لذلك، فإن إتقان أساسيات التدويل هو مهارة قيمة ستعزز قيمتك في مشهد التطوير العالمي اليوم.