Next.js Internationalization (i18n) مع next-i18next و Intlayer
كل من next-i18next و Intlayer هما إطاران مفتوحا المصدر للتدويل (i18n) مصممان لتطبيقات Next.js. يتم استخدامهما على نطاق واسع لإدارة الترجمات، والتعريب، وتبديل اللغة في مشاريع البرمجيات.
تتضمن كلا الحلقتين ثلاث مفاهيم رئيسية:
إعلان المحتوى: الطريقة لتعريف المحتوى القابل للترجمة في تطبيقك.
- يسمى resource في حالة i18next، إعلان المحتوى هو كائن JSON منظم يحتوي على أزواج مفتاح-قيمة للترجمات في لغة واحدة أو أكثر. راجع وثائق i18next لمزيد من المعلومات.
- يسمى content declaration file في حالة Intlayer، يمكن أن يكون إعلان المحتوى ملف JSON أو JS أو TS يقوم بتصدير البيانات المنسقة. راجع وثائق Intlayer لمزيد من المعلومات.
الأدوات المساعدة: أدوات لبناء وتفسير إعلانات المحتوى في التطبيق، مثل getI18n()، useCurrentLocale()، أو useChangeLocale() لـ next-i18next، و useIntlayer() أو useLocale() لـ Intlayer.
الإضافات والبرامج الوسيطة: ميزات لإدارة إعادة توجيه URL، وتحسين التجميع، والمزيد، مثل next-i18next/middleware لـ next-i18next أو intlayerMiddleware لـ Intlayer.
Intlayer مقابل i18next: الفرق الرئيسي
لاستكشاف الفروقات بين i18next و Intlayer، تحقق من منشور المدونة الخاص بنا next-i18next vs. next-intl vs. Intlayer.
كيفية توليد قواميس next-i18next مع Intlayer
لماذا تستخدم Intlayer مع next-i18next؟
تقدم ملفات إعلان محتوى Intlayer عمومًا تجربة مطور أفضل. إنها أكثر مرونة وقابلية للصيانة بفضل ميزتين رئيسيتين:
المكان المرن: يمكن وضع ملف إعلان المحتوى Intlayer في أي مكان في شجرة ملفات التطبيق، مما يبسط إدارة المكونات المكررة أو المحذوفة دون ترك إعلانات محتوى غير مستخدمة.
أمثلة لهيكل الملفات:
bash.└── src └── components └── MyComponent ├── index.content.ts # ملف إعلان المحتوى └── index.tsx
الترجمات المركزية: تحفظ Intlayer جميع الترجمات في ملف واحد، مما يضمن عدم وجود ترجمة مفقودة. عند استخدام TypeScript، يتم اكتشاف الترجمات المفقودة تلقائيًا والإبلاغ عنها كأخطاء.
التثبيت
npm install intlayer i18next next-i18next i18next-resources-to-backend
تكوين Intlayer لتصدير قواميس i18next
لا يضمن تصدير موارد i18next توافق 1:1 مع الإطارات الأخرى. يُوصى بالالتزام بتكوين قائم على Intlayer لتقليل المشكلات.
لتصدير موارد i18next، قم بتكوين Intlayer في ملف intlayer.config.ts. أمثلة على التكوينات:
import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = { internationalization: { locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], defaultLocale: Locales.ENGLISH, }, content: { dictionaryOutput: ["i18next"], i18nextResourcesDir: "./i18next/resources", },};export default config;
هنا استمرارية وتصحيح الأجزاء المتبقية من المستند الخاص بك:
استيراد القواميس إلى تكوين i18next الخاص بك
لاستيراد الموارد المولدة إلى تكوين i18next الخاص بك، استخدم i18next-resources-to-backend. فيما يلي أمثلة:
import i18next from "i18next";import resourcesToBackend from "i18next-resources-to-backend";i18next.use( resourcesToBackend( (language: string, namespace: string) => import(`../i18next/resources/${language}/${namespace}.json`) ));
إعلان المحتوى
أمثلة على ملفات إعلان المحتوى بصيغ مختلفة:
import { t, type DeclarationContent } from "intlayer";const content = { key: "my-content", content: { myTranslatedContent: t({ en: "Hello World", fr: "Bonjour le monde", es: "Hola Mundo", }), },} satisfies DeclarationContent;export default content;
بناء موارد next-i18next
لبناء موارد next-i18next، قم بتشغيل الأمر التالي:
npx run intlayer build
سيؤدي ذلك إلى توليد الموارد في دليل ./i18next/resources. الإخراج المتوقع:
.└── i18next └── resources └── ar └── my-content.json └── fr └── my-content.json └── es └── my-content.json
ملحوظة: يتوافق مساحة أسماء i18next مع مفتاح إعلان Intlayer.
تنفيذ مكون Next.js
بمجرد تكوينها، نفذ مكون Next.js لإعادة بناء موارد i18next الخاصة بك كلما تم تحديث ملفات إعلان محتوى Intlayer.
import { withIntlayer } from "next-intlayer/server";/** @type {import('next').NextConfig} */const nextConfig = {};export default withIntlayer(nextConfig);
استخدام المحتوى في مكونات Next.js
بعد تنفيذ مكون Next.js، يمكنك استخدام المحتوى في مكوناتك:
import type { FC } from "react";import { useTranslation } from "react-i18next";const IndexPage: FC = () => { const { t } = useTranslation(); return ( <div> <h1>{t("my-content.title")}</h1> <p>{t("my-content.description")}</p> </div> );};export default IndexPage;
إذا كان لديك فكرة لتحسين هذه الوثيقة، فلا تتردد في المساهمة من خلال تقديم طلب سحب على GitHub.
رابط GitHub للمدونة