استخدم مساعدك المفضل للملخص واستخدم هذه الصفحة والموفر AI الذي تريده
بدءاً من الدمج مع خادم MCP Intlayer ، يمكن لمساعدك الذكي الاسترجاع من جميع المستندات مباشرة من ChatGPT ، DeepSeek ، Cursor ، VSCode ، إلخ.
عرض الوثائق الخاصة بالخادم MCPتاريخ الإصدارات
- أضف validatePrefix وشرح خطوة 14: معالجة صفحات 404 مع الطرق المعتمدة على اللغة.v7.4.011/12/2025
- أضف خطوة 13: كيفية جلب اللغة الحالية داخل عمليات الخادم (اختياري)v7.3.95/12/2025
- أضيف لـ Tanstack Startv5.8.19/9/2025
تمت ترجمة محتوى هذه الصفحة باستخدام الذكاء الاصطناعي.
اعرض آخر نسخة المحتوى الأصلي باللغة الإنكليزيةإذا كان لديك فكرة لتحسين هذه الوثيقة، فلا تتردد في المساهمة من خلال تقديم طلب سحب على GitHub.
رابط GitHub للتوثيقنسخ الـ Markdown من المستند إلى الحافظة
ترجم Tanstack Start باستخدام Intlayer | التدويل (i18n)
جدول المحتويات
يوضح هذا الدليل كيفية دمج Intlayer لتحقيق تدويل سلس في مشاريع Tanstack Start مع توجيه يعتمد على اللغة، ودعم TypeScript، وممارسات تطوير حديثة.
ما هو Intlayer؟
Intlayer هو مكتبة تدويل (i18n) مبتكرة ومفتوحة المصدر مصممة لتبسيط دعم اللغات المتعددة في تطبيقات الويب الحديثة.
مع Intlayer، يمكنك:
- إدارة الترجمات بسهولة باستخدام قواميس إعلانية على مستوى المكونات.
- توطين البيانات الوصفية والمسارات والمحتوى ديناميكيًا.
- ضمان دعم TypeScript مع أنواع مولدة تلقائيًا، مما يحسن الإكمال التلقائي واكتشاف الأخطاء.
- الاستفادة من الميزات المتقدمة، مثل الكشف الديناميكي عن اللغة والتبديل بينها.
- تمكين التوجيه المعتمد على اللغة باستخدام نظام التوجيه القائم على الملفات في Tanstack Start.
دليل خطوة بخطوة لإعداد Intlayer في تطبيق Tanstack Start
راجع قالب التطبيق على GitHub.
الخطوة 1: إنشاء المشروع
ابدأ بإنشاء مشروع TanStack Start جديد باتباع دليل بدء مشروع جديد على موقع TanStack Start.
الخطوة 2: تثبيت حزم Intlayer
قم بتثبيت الحزم اللازمة باستخدام مدير الحزم المفضل لديك:
npm install intlayer react-intlayernpm install vite-intlayer --save-dev- intlayer
الحزمة الأساسية التي توفر أدوات التدويل لإدارة التكوين، الترجمة، إعلان المحتوى، التحويل البرمجي، وأوامر CLI.
react-intlayer الحزمة التي تدمج Intlayer مع تطبيق React. توفر مزودي السياق (context providers) وخطافات (hooks) لتدويل React.
vite-intlayer تتضمن إضافة Vite لدمج Intlayer مع مجمّع Vite، بالإضافة إلى وسيط (middleware) لاكتشاف اللغة المفضلة للمستخدم، إدارة الكوكيز، والتعامل مع إعادة توجيه عناوين URL.
الخطوة 3: تكوين مشروعك
أنشئ ملف تكوين لتكوين لغات تطبيقك:
نسخ الكود إلى الحافظة
import type { IntlayerConfig } from "intlayer";import { Locales } from "intlayer";const config: IntlayerConfig = { internationalization: { defaultLocale: Locales.ENGLISH, locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], },};export default config;من خلال ملف التكوين هذا، يمكنك إعداد عناوين URL محلية، إعادة توجيه الوسيط (middleware)، أسماء الكوكيز، موقع وامتداد إعلانات المحتوى الخاصة بك، تعطيل سجلات Intlayer في وحدة التحكم، والمزيد. للحصول على قائمة كاملة بالمعلمات المتاحة، راجع توثيق التكوين.
الخطوة 4: دمج Intlayer في تكوين Vite الخاص بك
أضف مكون intlayer الإضافي إلى تكوينك:
نسخ الكود إلى الحافظة
import { tanstackStart } from "@tanstack/react-start/plugin/vite";import viteReact from "@vitejs/plugin-react";import { nitro } from "nitro/vite";import { defineConfig } from "vite";import { intlayer } from "vite-intlayer";import viteTsConfigPaths from "vite-tsconfig-paths";const config = defineConfig({ plugins: [ nitro(), viteTsConfigPaths({ projects: ["./tsconfig.json"], }), tanstackStart(), viteReact(), intlayer(), // To add ],});export default config;يُستخدم مكون Vite الإضافي intlayer() لدمج Intlayer مع Vite. يضمن بناء ملفات إعلان المحتوى ومراقبتها في وضع التطوير. كما يعرّف متغيرات بيئة Intlayer داخل تطبيق Vite. بالإضافة إلى ذلك، يوفر ألقابًا لتحسين الأداء.
الخطوة 5: إنشاء مكونات التخطيط
قم بإعداد التخطيط الجذري والتخطيطات الخاصة بكل لغة:
التخطيط الجذري
نسخ الكود إلى الحافظة
import { createFileRoute, Outlet } from "@tanstack/react-router";import { IntlayerProvider, useLocale } from "react-intlayer";import { useI18nHTMLAttributes } from "@/hooks/useI18nHTMLAttributes";export const Route = createFileRoute("/{-$locale}")({ component: LayoutComponent,});function LayoutComponent() { const { defaultLocale } = useLocale(); const { locale } = Route.useParams(); return ( <IntlayerProvider locale={locale ?? defaultLocale}> <Outlet /> </IntlayerProvider> );}الخطوة 6: إعلان المحتوى الخاص بك
قم بإنشاء وإدارة إعلانات المحتوى الخاصة بك لتخزين الترجمات:
نسخ الكود إلى الحافظة
import type { Dictionary } from "intlayer";import { t } from "intlayer";const appContent = { content: { links: { about: t({ ar: "حول", en: "About", es: "Acerca de", fr: "À propos", }), home: t({ ar: "الرئيسية", en: "Home", es: "Inicio", fr: "Accueil", }), }, meta: { description: t({ ar: "هذا مثال على استخدام Intlayer مع TanStack Router", en: "This is an example of using Intlayer with TanStack Router", es: "Este es un ejemplo de uso de Intlayer con TanStack Router", fr: "Ceci est un exemple d'utilisation d'Intlayer avec TanStack Router", }), }, title: t({ ar: "مرحبًا بك في Intlayer + TanStack Router", en: "Welcome to Intlayer + TanStack Router", es: "Bienvenido a Intlayer + TanStack Router", fr: "Bienvenue à Intlayer + TanStack Router", }), }, key: "app",} satisfies Dictionary;export default appContent;يمكن تعريف إعلانات المحتوى الخاصة بك في أي مكان في تطبيقك بمجرد تضمينها في دليل contentDir (افتراضيًا، ./app). ويجب أن تطابق امتداد ملف إعلان المحتوى (افتراضيًا، .content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}).
لمزيد من التفاصيل، راجع توثيق إعلان المحتوى.
الخطوة 7: إنشاء مكونات وخطافات تدعم الواجهة متعددة اللغات
أنشئ مكون LocalizedLink للتنقل المدرك للواجهة متعددة اللغات:
نسخ الكود إلى الحافظة
import type { FC } from "react";import { Link, type LinkComponentProps } from "@tanstack/react-router";import { useLocale } from "react-intlayer";import { getPrefix } from "intlayer";export const LOCALE_ROUTE = "{-$locale}" as const;// الأداة الرئيسيةexport type RemoveLocaleParam<T> = T extends string ? RemoveLocaleFromString<T> : T;export type To = RemoveLocaleParam<LinkComponentProps["to"]>;type CollapseDoubleSlashes<S extends string> = S extends `${infer H}//${infer T}` ? CollapseDoubleSlashes<`${H}/${T}`> : S;type LocalizedLinkProps = { to?: To;} & Omit<LinkComponentProps, "to">;// المساعداتtype RemoveAll< S extends string, Sub extends string,> = S extends `${infer H}${Sub}${infer T}` ? RemoveAll<`${H}${T}`, Sub> : S;type RemoveLocaleFromString<S extends string> = CollapseDoubleSlashes< RemoveAll<S, typeof LOCALE_ROUTE>>;export const LocalizedLink: FC<LocalizedLinkProps> = (props) => { const { locale } = useLocale(); const { localePrefix } = getPrefix(locale); return ( <Link {...props} params={{ locale: localePrefix, ...(typeof props?.params === "object" ? props?.params : {}), }} to={`/${LOCALE_ROUTE}${props.to}` as LinkComponentProps["to"]} /> );};هذا المكون له هدفان:
- إزالة بادئة {-$locale} غير الضرورية من عنوان URL.
- حقن معامل اللغة (locale) في عنوان URL لضمان إعادة توجيه المستخدم مباشرة إلى المسار المحلي.
بعد ذلك يمكننا إنشاء هوك useLocalizedNavigate للملاحة البرمجية:
نسخ الكود إلى الحافظة
import { useNavigate } from "@tanstack/react-router";import { getPrefix } from "intlayer";import { useLocale } from "react-intlayer";import { LOCALE_ROUTE } from "@/components/localized-link";import type { FileRouteTypes } from "@/routeTree.gen";type StripLocalePrefix<T extends string> = T extends | `/${typeof LOCALE_ROUTE}` | `/${typeof LOCALE_ROUTE}/` ? "/" : T extends `/${typeof LOCALE_ROUTE}/${infer Rest}` ? `/${Rest}` : never;type LocalizedTo = StripLocalePrefix<FileRouteTypes["to"]>;type LocalizedNavigate = { (to: LocalizedTo): ReturnType<ReturnType<typeof useNavigate>>; ( opts: { to: LocalizedTo } & Record<string, unknown> ): ReturnType<ReturnType<typeof useNavigate>>;};export const useLocalizedNavigate = () => { const navigate = useNavigate(); const { locale } = useLocale(); const localizedNavigate: LocalizedNavigate = (args: any) => { const { localePrefix } = getPrefix(locale); if (typeof args === "string") { return navigate({ to: `/${LOCALE_ROUTE}${args}`, params: { locale: localePrefix }, }); } const { to, ...rest } = args; const localizedTo = `/${LOCALE_ROUTE}${to}` as any; return navigate({ to: localizedTo, params: { locale: localePrefix, ...rest } as any, }); }; return localizedNavigate;};الخطوة 8: استخدام Intlayer في صفحاتك
قم بالوصول إلى قواميس المحتوى الخاصة بك في جميع أنحاء تطبيقك:
الصفحة الرئيسية المحلية
نسخ الكود إلى الحافظة
import { createFileRoute } from "@tanstack/react-router";import { getIntlayer } from "intlayer";import { useIntlayer } from "react-intlayer";import LocaleSwitcher from "@/components/locale-switcher";import { LocalizedLink } from "@/components/localized-link";import { useLocalizedNavigate } from "@/hooks/useLocalizedNavigate";export const Route = createFileRoute("/{-$locale}/")({ component: RouteComponent, head: ({ params }) => { const { locale } = params; const metaContent = getIntlayer("app", locale); return { meta: [ { title: metaContent.title }, { content: metaContent.meta.description, name: "description" }, ], }; },});function RouteComponent() { const content = useIntlayer("app"); const navigate = useLocalizedNavigate(); return ( <div> <div> {content.title} <LocaleSwitcher /> <div> <LocalizedLink to="/">{content.links.home}</LocalizedLink> <LocalizedLink to="/about">{content.links.about}</LocalizedLink> </div> <div> <button onClick={() => navigate({ to: "/" })}> {content.links.home} </button> <button onClick={() => navigate({ to: "/about" })}> {content.links.about} </button> </div> </div> </div> );}لمعرفة المزيد عن الخطاف useIntlayer، راجع التوثيق.
الخطوة 9: إنشاء مكون لتبديل اللغة
قم بإنشاء مكون يسمح للمستخدمين بتغيير اللغة:
نسخ الكود إلى الحافظة
import type { FC } from "react";import { useLocation } from "@tanstack/react-router";import { getHTMLTextDir, getLocaleName, getPathWithoutLocale, getPrefix, Locales,} from "intlayer";import { useLocale } from "react-intlayer";import { LocalizedLink, To } from "./localized-link";export const LocaleSwitcher: FC = () => { const { pathname } = useLocation(); const { availableLocales, locale, setLocale } = useLocale(); const pathWithoutLocale = getPathWithoutLocale(pathname); return ( <ol> {availableLocales.map((localeEl) => ( <li key={localeEl}> <LocalizedLink aria-current={localeEl === locale ? "page" : undefined} onClick={() => setLocale(localeEl)} params={{ locale: getPrefix(localeEl).localePrefix }} > <span> {/* اللغة المحلية - مثل FR */} {localeEl} </span> <span> {/* اللغة بلغتها المحلية - مثل Français */} {getLocaleName(localeEl, locale)} </span> <span dir={getHTMLTextDir(localeEl)} lang={localeEl}> {/* اللغة في اللغة الحالية - مثل Francés مع تعيين اللغة الحالية إلى Locales.SPANISH */} {getLocaleName(localeEl)} </span> <span dir="ltr" lang={Locales.ENGLISH}> {/* اللغة بالإنجليزية - مثل French */} {getLocaleName(localeEl, Locales.ENGLISH)} </span> </LocalizedLink> </li> ))} </ol> );};لمعرفة المزيد عن الخطاف useLocale، راجع التوثيق.
الخطوة 10: إضافة إدارة خصائص HTML (اختياري)
أنشئ خطافًا لإدارة خصائص lang و dir في HTML:
نسخ الكود إلى الحافظة
// src/hooks/useI18nHTMLAttributes.tsximport { getHTMLTextDir } from "intlayer";import { useEffect } from "react";import { useLocale } from "react-intlayer";export const useI18nHTMLAttributes = () => { const { locale } = useLocale(); useEffect(() => { document.documentElement.lang = locale; document.documentElement.dir = getHTMLTextDir(locale); }, [locale]);};ثم استخدمه في مكون الجذر الخاص بك:
نسخ الكود إلى الحافظة
import { createFileRoute, Outlet } from "@tanstack/react-router";import { IntlayerProvider, useLocale } from "react-intlayer";import { useI18nHTMLAttributes } from "@/hooks/useI18nHTMLAttributes"; // استيراد الخطافexport const Route = createFileRoute("/{-$locale}")({ component: LayoutComponent,});function LayoutComponent() { useI18nHTMLAttributes(); // أضف هذا السطر const { defaultLocale } = useLocale(); const { locale } = Route.useParams(); return ( <IntlayerProvider locale={locale ?? defaultLocale}> <Outlet /> </IntlayerProvider> );}الخطوة 11: إضافة الوسيط (اختياري)
يمكنك أيضًا استخدام intlayerProxy لإضافة التوجيه من جانب الخادم إلى تطبيقك. سيقوم هذا الملحق تلقائيًا بالكشف عن اللغة الحالية بناءً على عنوان URL وتعيين ملف تعريف الارتباط الخاص باللغة المناسبة. إذا لم يتم تحديد لغة، فسيحدد الملحق اللغة الأنسب بناءً على تفضيلات لغة متصفح المستخدم. وإذا لم يتم الكشف عن أي لغة، فسيتم إعادة التوجيه إلى اللغة الافتراضية.
لاحظ أنه لاستخدام intlayerProxy في بيئة الإنتاج، تحتاج إلى نقل حزمة vite-intlayer من devDependencies إلى dependencies.
نسخ الكود إلى الحافظة
import { reactRouter } from "@react-router/dev/vite";import tailwindcss from "@tailwindcss/vite";import { defineConfig } from "vite";import { intlayer, intlayerProxy } from "vite-intlayer";import tsconfigPaths from "vite-tsconfig-paths";export default defineConfig({ plugins: [ intlayerProxy(), // يجب وضع الوكيل قبل الخادم إذا كنت تستخدم Nitro tailwindcss(), reactRouter(), tsconfigPaths(), intlayer(), ],});الخطوة 12: تدويل البيانات الوصفية (اختياري)
يمكنك أيضًا استخدام الخطاف getIntlayer للوصول إلى قواميس المحتوى الخاصة بك في جميع أنحاء التطبيق:
نسخ الكود إلى الحافظة
import { createFileRoute } from "@tanstack/react-router";import { getIntlayer } from "intlayer";export const Route = createFileRoute("/{-$locale}/")({ component: RouteComponent, head: ({ params }) => { const { locale } = params; const metaContent = getIntlayer("page-metadata", locale); return { meta: [ { title: metaContent.title }, { content: metaContent.description, name: "description" }, ], }; },});Step 13: Retrieve the locale in your server actions (Optional)
You may want to access the current locale from inside your server actions or API endpoints. You can do this using the getLocale helper from intlayer.
Here's an example using TanStack Start's server functions:
نسخ الكود إلى الحافظة
import { createServerFn } from "@tanstack/react-start";import { getRequestHeader, getRequestHeaders,} from "@tanstack/react-start/server";import { getCookie, getIntlayer, getLocale } from "intlayer";export const getLocaleServer = createServerFn().handler(async () => { const locale = await getLocale({ // Get the cookie from the request (default: 'INTLAYER_LOCALE') getCookie: (name) => { const cookieString = getRequestHeader("cookie"); return getCookie(name, cookieString); }, // Get the header from the request (default: 'x-intlayer-locale') // Fallback using Accept-Language negotiation getHeader: (name) => getRequestHeader(name), }); // Retrieve some content using getIntlayer() const content = getIntlayer("app", locale); return { locale, content };});الخطوة 14: إدارة الصفحات غير الموجودة (اختياري)
عندما يزور المستخدم صفحة غير موجودة، يمكنك عرض صفحة مخصصة "غير موجودة" وقد يؤثر بادئة اللغة على طريقة تشغيل صفحة "غير موجودة".
فهم معالجة 404 في TanStack Router مع بادئات اللغة
في TanStack Router، يتطلب التعامل مع صفحات 404 باستخدام المسارات المترجمة نهجًا متعدد الطبقات:
- مسار 404 مخصص: مسار محدد لعرض واجهة المستخدم 404
- التحقق على مستوى المسار: يتحقق من بادئات اللغة ويعيد توجيه غير الصالحة إلى 404
- مسار catch-all: يلتقط أي مسارات غير متطابقة داخل مقطع اللغة
نسخ الكود إلى الحافظة
import { createFileRoute } from "@tanstack/react-router";// هذا ينشئ مسارًا مخصصًا /[locale]/404// يتم استخدامه كمسار مباشر واستيراده كعنصر في ملفات أخرىexport const Route = createFileRoute("/{-$locale}/404")({ component: NotFoundComponent,});// يتم تصديره بشكل منفصل حتى يمكن إعادة استخدامه في notFoundComponent والمسارات catch-allexport function NotFoundComponent() { return ( <div> <h1>404</h1> </div> );}نسخ الكود إلى الحافظة
import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";import { validatePrefix } from "intlayer";import { IntlayerProvider, useLocale } from "react-intlayer";import { LocaleSwitcher } from "@/components/locale-switcher";import { NotFoundComponent } from "./404";export const Route = createFileRoute("/{-$locale}")({ // beforeLoad يعمل قبل عرض المسار (على كل من الخادم والعميل) // إنه المكان المثالي للتحقق من بادئة اللغة beforeLoad: ({ params }) => { // الحصول على اللغة من معاملات المسار (وليس من رؤوس الخادم، حيث يعمل beforeLoad على كل من العميل والخادم) const localeParam = params.locale; // validatePrefix يتحقق مما إذا كانت اللغة صالحة وفقًا لتكوين intlayer الخاص بك // إرجاع: { isValid: boolean, localePrefix: string } // - isValid: true إذا كانت البادئة تطابق لغة مُكوَّنة (أو فارغة عندما تكون البادئة اختيارية) // - localePrefix: البادئة المُتحقق منها أو بادئة اللغة الافتراضية لإعادة التوجيه const { isValid, localePrefix } = validatePrefix(localeParam); if (isValid) { // اللغة صالحة، السماح للمسار بالعرض بشكل طبيعي return; } // بادئة لغة غير صالحة (على سبيل المثال، /xyz/about حيث "xyz" ليست لغة صالحة) // إعادة التوجيه إلى صفحة 404 ببادئة لغة صالحة // يضمن هذا أن صفحة 404 لا تزال محلية بشكل صحيح throw redirect({ to: "/{-$locale}/404", params: { locale: localePrefix }, }); }, component: RouteComponent, // يتم استدعاء notFoundComponent عندما لا يوجد مسار فرعي // على سبيل المثال، /en/صفحة-غير-موجودة يطلق هذا داخل تخطيط /en notFoundComponent: NotFoundLayout,});function RouteComponent() { const { defaultLocale } = useLocale(); const { locale } = Route.useParams(); return ( // لف كامل مقطع اللغة بـ IntlayerProvider // يعود إلى defaultLocale عندما تكون معلمة اللغة undefined (وضع البادئة الاختياري) <IntlayerProvider locale={locale ?? defaultLocale}> <Outlet /> </IntlayerProvider> );}// NotFoundLayout يلف عنصر 404 بـ IntlayerProvider// يضمن هذا أن الترجمات لا تزال تعمل على صفحة 404function NotFoundLayout() { const { defaultLocale } = useLocale(); const { locale } = Route.useParams(); return ( <IntlayerProvider locale={locale ?? defaultLocale}> <NotFoundComponent /> {/* تضمين LocaleSwitcher حتى يتمكن المستخدمون من تغيير اللغة حتى على 404 */} <LocaleSwitcher /> </IntlayerProvider> );}نسخ الكود إلى الحافظة
import { createFileRoute } from "@tanstack/react-router";import { NotFoundComponent } from "./404";// المسار $ (splat/catch-all) يطابق أي مسار لا يطابق المسارات الأخرى// على سبيل المثال، /en/بعض/المسار/المتداخل/بعمق/غير-صالح// يضمن هذا أن جميع المسارات غير المتطابقة داخل اللغة تعرض صفحة 404// بدون هذا، قد تعرض المسارات العميقة غير المتطابقة صفحة فارغة أو خطأexport const Route = createFileRoute("/{-$locale}/$")({ component: NotFoundComponent,});الخطوة 15: تكوين TypeScript (اختياري)
يستخدم Intlayer توسيع الوحدات (module augmentation) للاستفادة من TypeScript وجعل قاعدة الشيفرة الخاصة بك أقوى.
تأكد من أن تكوين TypeScript الخاص بك يتضمن الأنواع التي تم إنشاؤها تلقائيًا:
نسخ الكود إلى الحافظة
{ // ... التكوينات الحالية الخاصة بك include: [ // ... الملفات التي تشملها حاليًا ".intlayer/**/*.ts", // تضمين الأنواع التي تم إنشاؤها تلقائيًا ],}تكوين Git
يوصى بتجاهل الملفات التي تم إنشاؤها بواسطة Intlayer. هذا يسمح لك بتجنب الالتزام بها في مستودع Git الخاص بك.
لتحقيق ذلك، يمكنك إضافة التعليمات التالية إلى ملف .gitignore الخاص بك:
نسخ الكود إلى الحافظة
# تجاهل الملفات التي تم إنشاؤها بواسطة Intlayer.intlayerامتداد VS Code
لتحسين تجربة التطوير الخاصة بك مع Intlayer، يمكنك تثبيت امتداد Intlayer الرسمي لـ VS Code.
يوفر هذا الامتداد:
- الإكمال التلقائي لمفاتيح الترجمة.
- الكشف الفوري عن الأخطاء للترجمات المفقودة.
- معاينات داخلية للمحتوى المترجم.
- إجراءات سريعة لإنشاء الترجمات وتحديثها بسهولة.
لمزيد من التفاصيل حول كيفية استخدام الإضافة، راجع توثيق إضافة Intlayer لـ VS Code.
التقدم أكثر
للتقدم أكثر، يمكنك تنفيذ المحرر المرئي أو إخراج محتواك باستخدام نظام إدارة المحتوى (CMS).
مراجع التوثيق
يوفر هذا الدليل الشامل كل ما تحتاجه لدمج Intlayer مع Tanstack Start لتطبيق دولي بالكامل مع توجيه واعٍ للغة ودعم TypeScript.