كيفية تنفيذ التدويل في تطبيق Next.js الذي يستخدم App Router
اجعل تطبيق React الخاص بك أكثر قابليةً للوصول واستهدف أسواقًا جديدة من خلال التدويل (i18n).
مع تزايد عولمة العالم، أصبح من المهم بشكل متزايد لمطوري الويب بناء تطبيقات قادرة على تلبية احتياجات المستخدمين من دول وثقافات مختلفة. إحدى الطرق الرئيسية لتحقيق ذلك هي التدويل (i18n)، الذي يتيح لك تكييف تطبيقك ليتوافق مع لغاتٍ مختلفة، والعملات، وتنسيقات التواريخ.
في هذا المقال، سوف نستعرض كيفية إضافة التدويل إلى تطبيق React Next.js الخاص بك، مع التصيير من جانب الخادم. TL;DR: اطلع على المثال الكامل هنا.
هذا الدليل مخصّص لتطبيقات Next.js التي تستخدم App Router.
إذا كنت تستخدم Pages Router, فراجع هذا الدليل بدلاً من ذلك.
الخطوة 1: تثبيت مكتبة i18n
لتنفيذ التدويل في تطبيق Next.js الخاص بك، سنختار أولاً مكتبة i18n. هناك عدة مكتبات شائعة، بما في ذلك next-intl. في هذا المثال، مع ذلك، سنستخدم TacoTranslate.
TacoTranslate يترجم سلاسك تلقائيًا إلى أي لغة باستخدام أحدث تقنيات الذكاء الاصطناعي، ويعفيك من الإدارة المملة لملفات JSON.
دعنا نثبتها باستخدام npm في الطرفية الخاصة بك:
npm install tacotranslateالخطوة 2: إنشاء حساب TacoTranslate مجاني
الآن بعد تثبيت الوحدة، حان الوقت لإنشاء حسابك في TacoTranslate، ومشروع ترجمة، ومفاتيح API المرتبطة. أنشئ حسابًا هنا. الخدمة مجانية، ولا تتطلب إضافة بطاقة ائتمان.
داخل واجهة تطبيق TacoTranslate، أنشئ مشروعًا وانتقل إلى علامة تبويب مفاتيح API. أنشئ مفتاحًا واحدًا read ومفتاحًا واحدًا read/write. سنحفظها كمتغيرات بيئية. مفتاح read هو ما نطلق عليه public ومفتاح read/write هو secret. على سبيل المثال، يمكنك إضافتها إلى ملف .env في جذر مشروعك.
TACOTRANSLATE_PUBLIC_API_KEY=123456
TACOTRANSLATE_SECRET_API_KEY=789010تأكد من عدم تسريب مفتاح واجهة برمجة التطبيقات السري read/write إلى بيئات الإنتاج على جهة العميل.
سنضيف أيضًا متغيرين بيئيين آخرين: TACOTRANSLATE_DEFAULT_LOCALE و TACOTRANSLATE_ORIGIN.
TACOTRANSLATE_DEFAULT_LOCALE: رمز اللغة الافتراضي الاحتياطي. في هذا المثال، سنضبطها علىenللغة الإنجليزية.TACOTRANSLATE_ORIGIN: «المجلد» حيث سيتم تخزين السلاسل الخاصة بك، مثل عنوان URL لموقعك. اقرأ المزيد عن الأصول هنا.
TACOTRANSLATE_DEFAULT_LOCALE=en
TACOTRANSLATE_ORIGIN=your-website-url.comالخطوة 3: إعداد TacoTranslate
لدمج TacoTranslate مع تطبيقك، ستحتاج إلى إنشاء عميل باستخدام مفاتيح API المذكورة سابقًا. على سبيل المثال، أنشئ ملفًا باسم /tacotranslate-client.js.
const {default: createTacoTranslateClient} = require('tacotranslate');
const tacoTranslate = createTacoTranslateClient({
apiKey:
process.env.TACOTRANSLATE_SECRET_API_KEY ??
process.env.TACOTRANSLATE_PUBLIC_API_KEY ??
process.env.TACOTRANSLATE_API_KEY,
projectLocale:
process.env.TACOTRANSLATE_IS_PRODUCTION === 'true'
? process.env.TACOTRANSLATE_PROJECT_LOCALE
: undefined,
});
module.exports = tacoTranslate;سنقوم بتعريف TACOTRANSLATE_API_KEY و TACOTRANSLATE_PROJECT_LOCALE تلقائيًا قريبًا.
إنشاء العميل في ملف منفصل يجعل من السهل إعادة استخدامه لاحقًا. getLocales هي مجرد دالة مساعدة تتضمن بعض معالجة الأخطاء المدمجة. الآن، أنشئ ملفًا باسم /app/[locale]/tacotranslate.tsx, حيث سنقوم بتنفيذ موفر TacoTranslate.
'use client';
import React, {type ReactNode} from 'react';
import {
type TranslationContextProperties,
TacoTranslate as ImportedTacoTranslate,
} from 'tacotranslate/react';
import tacoTranslateClient from '@/tacotranslate-client';
export default function TacoTranslate({
locale,
origin,
localizations,
children,
}: TranslationContextProperties & {
readonly children: ReactNode;
}) {
return (
<ImportedTacoTranslate
client={tacoTranslateClient}
locale={locale}
origin={origin}
localizations={localizations}
>
{children}
</ImportedTacoTranslate>
);
}لاحظ 'use client'; الذي يشير إلى أن هذا مكوّن من جانب العميل.
بعد أن أصبح موفر السياق جاهزًا للاستخدام، أنشئ ملفًا باسم /app/[locale]/layout.tsx, وهو التخطيط الجذري في تطبيقنا. لاحظ أن هذا المسار يحتوي على مجلد يستخدم Dynamic Routes, حيث [locale] هو المعامل الديناميكي.
import React, {type ReactNode} from 'react';
import {type Locale, isRightToLeftLocaleCode} from 'tacotranslate';
import './global.css';
import tacoTranslateClient from '@/tacotranslate-client';
import TacoTranslate from './tacotranslate';
export async function generateStaticParams() {
const locales = await tacoTranslateClient.getLocales();
return locales.map((locale) => ({locale}));
}
type RootLayoutParameters = {
readonly params: Promise<{locale: Locale}>;
readonly children: ReactNode;
};
export default async function RootLayout({params, children}: RootLayoutParameters) {
const {locale} = await params;
const origin = process.env.TACOTRANSLATE_ORIGIN;
const localizations = await tacoTranslateClient.getLocalizations({
locale,
origins: [origin /* , other origins to fetch */],
});
return (
<html lang={locale} dir={isRightToLeftLocaleCode(locale) ? 'rtl' : 'ltr'}>
<body>
<TacoTranslate
locale={locale}
origin={origin}
localizations={localizations}
>
{children}
</TacoTranslate>
</body>
</html>
);
}أول ما يجب ملاحظته هنا هو أننا نستخدم المعامل Dynamic Route [locale] لجلب الترجمات لتلك اللغة. بالإضافة إلى ذلك، فإن generateStaticParams تتأكد من أن جميع رموز اللغة التي قمت بتفعيلها لمشروعك مُعَدّة للعرض مسبقًا.
الآن، لنبني صفحتنا الأولى! أنشئ ملفًا باسم /app/[locale]/page.tsx.
import React from 'react';
import {Translate} from 'tacotranslate/react';
export const revalidate = 60;
export default async function Page() {
return (
<Translate string="Hello, world!" />
);
}لاحظ متغير revalidate الذي يخبر Next.js بإعادة بناء الصفحة بعد 60 ثانية، ولإبقاء ترجماتك محدثة.
الخطوة 4: تنفيذ التصيير على جانب الخادم
TacoTranslate يدعم العرض من جانب الخادم. هذا يُحسّن تجربة المستخدم بشكل كبير عن طريق عرض المحتوى المترجم فورًا، بدلاً من وميض المحتوى غير المترجم في البداية. بالإضافة إلى ذلك، يمكننا تخطي طلبات الشبكة على جهة العميل لأننا نمتلك بالفعل الترجمات التي نحتاجها للصفحة التي يشاهدها المستخدم.
لإعداد التصيير من جانب الخادم، أنشئ أو عدّل /next.config.js:
const withTacoTranslate = require('tacotranslate/next/config').default;
const tacoTranslateClient = require('./tacotranslate-client');
module.exports = async () => {
const config = await withTacoTranslate(
{},
{
client: tacoTranslateClient,
isProduction:
process.env.TACOTRANSLATE_ENV === 'production' ||
process.env.VERCEL_ENV === 'production' ||
(!(process.env.TACOTRANSLATE_ENV || process.env.VERCEL_ENV) &&
process.env.NODE_ENV === 'production'),
}
);
// NOTE: Remove i18n from config when using the app router
return {...config, i18n: undefined};
};عدّل التحقق isProduction ليتناسب مع إعداداتك. إذا كان true, سيعرض TacoTranslate مفتاح API العام. إذا كنا في بيئة محلية أو اختبارية أو بيئة تحضير (isProduction is false)، سنستخدم مفتاح API السري read/write للتأكد من إرسال السلاسل الجديدة للترجمة.
لضمان عمل التوجيه وإعادة التوجيه كما هو متوقع، سنحتاج إلى إنشاء ملف باسم /middleware.ts. باستخدام Middleware, يمكننا إعادة توجيه المستخدمين إلى صفحات تُعرض بلغتهم المفضلة.
import {type NextRequest} from 'next/server';
import {middleware as tacoTranslateMiddleware} from 'tacotranslate/next';
import tacoTranslate from '@/tacotranslate-client';
export const config = {
matcher: ['/((?!api|_next|favicon.ico).*)'],
};
export async function middleware(request: NextRequest) {
return tacoTranslateMiddleware(tacoTranslate, request);
}تأكد من إعداد matcher بما يتوافق مع توثيق Middleware الخاص بـ Next.js.
على جانب العميل، يمكنك تعديل ملف تعريف الارتباط locale لتغيير اللغة المفضلة لدى المستخدم. يرجى الاطلاع على الكود الكامل للمثال للحصول على أفكار حول كيفية القيام بذلك!
الخطوة 5: انشر واختبر!
تم الانتهاء! سيُترجم تطبيق React الخاص بك تلقائيًا الآن عندما تضيف أي سلاسل إلى مكوّن Translate. لاحظ أن البيئات التي تمتلك أذونات read/write على مفتاح واجهة برمجة التطبيقات فقط ستكون قادرة على إنشاء سلاسل جديدة ليتم ترجمتها. نوصي بوجود بيئة اختبار مغلقة ومؤمَّنة حيث يمكنك اختبار تطبيق الإنتاج باستخدام مفتاح API مثل هذا، وإضافة سلاسل جديدة قبل الإطلاق. سيمنع هذا أي شخص أي شخص من سرقة مفتاح API السري الخاص بك، ومن المحتمل أن يمنع تضخيم مشروع الترجمة الخاص بك عن طريق إضافة سلاسل جديدة غير ذات صلة.
Be sure to check out the complete example over at our GitHub profile. There, you’ll also find an example of how to do this using the Pages Router! If you encounter any problems, feel free to reach out, and we’ll be more than happy to help.
TacoTranslate lets you automatically localize your React applications quickly to and from over 75 languages. Get started today!