المؤلف:
    إنشاء:2025-09-04آخر تحديث:2026-10-08

    ترجم React Router v7 باستخدام Intlayer

    يوضح هذا الدليل كيفية دمج Intlayer لتحقيق التدويل السلس في مشاريع React Router v7 مع توجيه يدعم اللغة المحلية، ودعم TypeScript، وممارسات تطوير حديثة.

    يغطي هذا الدليل كلاً من التوجيه المعتمد على الإعدادات (routes.ts) والتوجيه المعتمد على نظام الملفات (@react-router/fs-routes).

    جدول المحتويات

    لماذا تختار Intlayer مقارنة بالبدائل الأخرى؟

    بالمقارنة مع الحلول الرئيسية مثل react-i18next أو i18next، يعد Intlayer حلاً يأتي مزودًا بتحسينات متكاملة مثل:

    تم تحسين Intlayer للعمل بشكل مثالي مع React Router من خلال تقديم توجيه مدرك للإعدادات المحلية، برامج وسيطة للكشف عن الإعدادات المحلية، وجميع الميزات اللازمة لتوسيع نطاق التدويل (i18n).

    بدلاً من تحميل ملفات JSON ضخمة إلى صفحاتك، قم بتحميل المحتوى الضروري فقط. يساعد Intlayer في تقليل حجم حزمة JavaScript (bundle size) وصفحاتك بنسبة تصل إلى 50%.

    تحديد نطاق المحتوى لكل مكوّن على حدة يُسهّل صيانة التطبيقات الكبيرة. يمكنك نسخ مجلد ميزة بالكامل أو حذفه دون القلق بشأن مراجعة قاعدة بيانات المحتوى بأكملها. بالإضافة إلى ذلك، فإن Intlayer مكتوب بنظام أنواع قوي (Fully Typed) لضمان الدقة الكاملة لمحتواك.

    يؤدي وضع المحتوى إلى جانب المكونات (Co-location) إلى تقليل السياق المطلوب بواسطة نماذج اللغات الكبيرة (LLMs). كما يوفر Intlayer مجموعة أدوات متكاملة مثل واجهة سطر الأوامر (CLI) لفحص الترجمات المفقودة، وLSP، وخادم MCP، ومهارات الوكلاء (Agent Skills)، لتوفير أفضل تجربة تطوير لوكلاء الذكاء الاصطناعي.

    استخدم الأتمتة لترجمة المحتوى مباشرةً في مسار CI/CD الخاص بك باستخدام نموذج اللغة الكبير (LLM) الذي تختاره ووفق تكلفة مزود الذكاء الاصطناعي لديك. يقدم Intlayer أيضًا مترجمًا لأتمتة استخراج المحتوى، بالإضافة إلى منصة ويب للمساعدة في الترجمة في الخلفية.

    قد يؤدي تحميل ملفات JSON ضخمة في المكونات إلى مشكلات في الأداء وسرعة الاستجابة. يعمل Intlayer على تحسين تحميل المحتوى بدقة عند وقت البناء (Build Time).

    أكثر من مجرد حل i18n، يوفر Intlayer محررًا مرئيًا مستضافًا ذاتيًا ونظام إدارة محتوى كامل (CMS) لإدارة المحتوى متعدد اللغات في الوقت الفعلي، مما يجعل التعاون مع المترجمين وكتاب المحتوى وأعضاء الفريق الآخرين سلسًا للغاية. يمكن تخزين المحتوى محليًا و/أو عن بعد.

    دليل خطوة بخطوة لإعداد Intlayer في تطبيق React Router v7

    youtube.com
    ide.intlayer.org
    ide.intlayer.org
    intlayer-react-router-v7.vercel.app

    See the Config-Based Routing Template or File-System Routes Template on GitHub.

    1. تثبيت التبعيات

      قم بتثبيت الحزم اللازمة باستخدام مدير الحزم المفضل لديك:

      bash
      npx intlayer init --interactive
      
      علامة --interactive اختيارية. استخدم intlayer-cli init إذا كنت وكيل ذكاء اصطناعي.
      سيقوم هذا الأمر باكتشاف بيئتك وتثبيت الحزم المطلوبة. على سبيل المثال:
      bash
      npm install intlayer react-intlayer
      npm install vite-intlayer --save-dev
      
      • intlayer

      الحزمة الأساسية التي توفر أدوات التدويل لإدارة التكوين، والترجمة، وإعلان المحتوى، والترجمة البرمجية، وأوامر CLI.

      • react-intlayer الحزمة التي تدمج Intlayer مع تطبيق React. توفر موفري السياق وخطافات للتدويل في React.

      • vite-intlayer تتضمن إضافة Vite لدمج Intlayer مع مجمّع Vite، بالإضافة إلى وسيط للكشف عن اللغة المفضلة للمستخدم، وإدارة الكوكيز، والتعامل مع إعادة توجيه URL.

    2. تكوين مشروعك

      البنية

      في هذه البنية، يتم تحديد المسارات برمجياً في app/routes.ts مع مقاطع ديناميكية اختيارية /:locale?. يتم تنظيم الصفحات المترجمة والتخطيطات وإعلانات المحتوى داخل دليل app/:

      bash
      .
      ├── app
      │   ├── components
      │   │   ├── locale-switcher.content.ts
      │   │   ├── locale-switcher.tsx
      │   │   ├── localized-link.tsx
      │   │   ├── navbar.content.ts
      │   │   └── navbar.tsx
      │   ├── hooks
      │   │   ├── useI18nHTMLAttributes.tsx
      │   │   └── useLocalizedNavigate.tsx
      │   ├── routes
      │   │   ├── about
      │   │   │   ├── page.content.ts
      │   │   │   └── page.tsx
      │   │   ├── layout.tsx
      │   │   ├── page.content.ts
      │   │   └── page.tsx
      │   ├── root.tsx                      # Root layout for IntlayerProvider
      │   └── routes.ts                     # Route definition file
      ├── intlayer.config.ts
      ├── package.json
      ├── react-router.config.ts
      ├── tsconfig.json
      └── vite.config.ts
      

      التكوين

      قم بإنشاء ملف تكوين intlayer.config.ts للإعلان عن اللغات المدعومة في تطبيقك:

      intlayer.config.ts
      import { type IntlayerConfig, Locales } from "intlayer";
      
      const config: IntlayerConfig = {
        internationalization: {
          defaultLocale: Locales.ENGLISH,
          locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
        },
      };
      
      export default config;
      

      البنية

      في هذه البنية، تتبع المسارات اصطلاحات نظام الملفات في React Router v7 باستخدام flatRoutes، حيث تمثل النقاط (.) مقاطع عنوان URL وتشير ($locale) إلى مقطع اللغة الاختياري:

      bash
      .
      ├── app
      │   ├── components
      │   │   ├── locale-switcher.content.ts
      │   │   ├── locale-switcher.tsx
      │   │   ├── localized-link.tsx
      │   │   ├── navbar.content.ts
      │   │   └── navbar.tsx
      │   ├── hooks
      │   │   ├── useI18nHTMLAttributes.tsx
      │   │   └── useLocalizedNavigate.tsx
      │   ├── routes
      │   │   ├── ($locale)._index.content.ts
      │   │   ├── ($locale)._index.tsx
      │   │   ├── ($locale).about.content.ts
      │   │   └── ($locale).about.tsx
      │   ├── root.tsx                      # Root layout for IntlayerProvider
      │   └── routes.ts                     # ملف تعريف المسارات باستخدام flatRoutes
      ├── intlayer.config.ts
      ├── package.json
      ├── react-router.config.ts
      ├── tsconfig.json
      └── vite.config.ts
      

      التكوين

      قم بإنشاء ملف تكوين intlayer.config.ts للإعلان عن اللغات المدعومة في تطبيقك:

      intlayer.config.ts
      import { type IntlayerConfig, Locales } from "intlayer";
      
      const config: IntlayerConfig = {
        internationalization: {
          defaultLocale: Locales.ENGLISH,
          locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
        },
      };
      
      export default config;
      
      من خلال ملف التكوين هذا، يمكنك إعداد عناوين URL محلية، إعادة توجيه الوسيط، أسماء ملفات تعريف الارتباط، موقع وامتداد إعلانات المحتوى الخاصة بك، تعطيل سجلات Intlayer في وحدة التحكم، والمزيد. للحصول على قائمة كاملة بالمعلمات المتاحة، راجع توثيق التكوين.
    3. دمج Intlayer في تكوين Vite الخاص بك

      أضف مكون intlayer الإضافي إلى تكوينك:

      vite.config.ts
      import { reactRouter } from "@react-router/dev/vite";
      import { defineConfig } from "vite";
      import { intlayer } from "vite-intlayer";
      
      export default defineConfig({
        plugins: [reactRouter(), intlayer()],
      });
      
      يتم استخدام مكون Vite الإضافي intlayer() لدمج Intlayer مع Vite. يضمن بناء ملفات إعلان المحتوى ويراقبها في وضع التطوير. كما يحدد متغيرات بيئة Intlayer داخل تطبيق Vite. بالإضافة إلى ذلك، يوفر أسماء مستعارة لتحسين الأداء.
    4. تكوين مسارات React Router v7

      قم بإعداد تكوين التوجيه الخاص بك مع مسارات مدركة للغة:

      app/routes.ts
      import { layout, route, type RouteConfig } from "@react-router/dev/routes";
      
      export default [
        route("/:locale?", "routes/page.tsx"), // الصفحة الرئيسية المحلية
        route("/:locale?/about", "routes/about/page.tsx"), // صفحة حول المحلية
      ] satisfies RouteConfig;
      

      قم بإعداد تكوين التوجيه الخاص بك لاستخدام المسارات القائمة على نظام الملفات باستخدام flatRoutes:

      app/routes.ts
      import type { RouteConfig } from "@react-router/dev/routes";
      import { flatRoutes } from "@react-router/fs-routes";
      import { configuration } from "intlayer";
      
      const routes: RouteConfig = flatRoutes({
        // Ignore content declaration files from being treated as routes
        ignoredRouteFiles: configuration.content.fileExtensions.map(
          (fileExtension) => `**/*${fileExtension}`
        ),
      });
      
      export default routes;
      
      تتيح دالة flatRoutes من @react-router/fs-routes التوجيه القائم على نظام الملفات، حيث تحدد بنية الملفات في دليل routes/ مسارات تطبيقك. ويضمن خيار ignoredRouteFiles عدم التعامل مع ملفات إعلان محتوى Intlayer (.content.ts وما إلى ذلك) كملفات مسارات.
    5. إنشاء مكونات التخطيط

      قم بإعداد التخطيط الجذري والتخطيطات الخاصة باللغة:

      التخطيط الجذري

      app/root.tsx
      import { getLocaleFromPath } from "intlayer";
      import { IntlayerProvider } from "react-intlayer";
      import {
        data,
        Meta,
        Scripts,
        ScrollRestoration,
        useLoaderData,
      } from "react-router";
      import type { Route } from "./+types/root";
      
      // ... Unchanged App, links and ErrorBoundary code
      
      export async function loader({ request }: Route.LoaderArgs) {
        const locale = getLocaleFromPath(request.url);
      
        if (!locale) {
          throw data("Language not supported", { status: 404 });
        }
      
        return { locale };
      }
      
      export function Layout({
        children,
      }: { children: React.ReactNode } & Route.ComponentProps) {
        const data = useLoaderData<typeof loader>();
        const { locale } = data ?? {};
      
        return (
          <html lang={locale}>
            <head>
              <meta charSet="utf-8" />
              <meta content="width=device-width, initial-scale=1" name="viewport" />
              <Meta />
              <Links />
            </head>
            <body>
              <IntlayerProvider locale={locale}>{children}</IntlayerProvider>
              <ScrollRestoration />
              <Scripts />
            </body>
          </html>
        );
      }
      
    6. إعلان المحتوى الخاص بك

      قم بإنشاء وإدارة إعلانات المحتوى الخاصة بك لتخزين الترجمات:

      app/routes/[lang]/page.content.ts
      import { t, type Dictionary } from "intlayer";
      
      const pageContent = {
        key: "page",
        content: {
          title: t({
            en: "Welcome to React Router v7 + Intlayer",
            es: "Bienvenido a React Router v7 + Intlayer",
            fr: "Bienvenue sur React Router v7 + Intlayer",
          }),
          description: t({
            en: "Build multilingual applications with ease using React Router v7 and Intlayer.",
            es: "Cree aplicaciones multilingües fácilmente usando React Router v7 y Intlayer.",
            fr: "Créez des applications multilingues facilement avec React Router v7 et Intlayer.",
          }),
          aboutLink: t({
            en: "تعرف علينا",
            es: "Aprender Sobre Nosotros",
            fr: "En savoir plus sur nous",
          }),
          homeLink: t({
            en: "الرئيسية",
            es: "Inicio",
            fr: "Accueil",
          }),
        },
      } satisfies Dictionary;
      
      export default pageContent;
      
      يمكن تعريف إعلانات المحتوى الخاصة بك في أي مكان في تطبيقك بمجرد تضمينها في دليل contentDir (افتراضيًا، ./app). ويجب أن تتطابق مع امتداد ملف إعلان المحتوى (افتراضيًا، .content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml}).
      Could be placed in app/routes/($locale)._index.content.ts in case of using file-system based routing.
      لمزيد من التفاصيل، راجع توثيق إعلان المحتوى.
    7. إنشاء مكونات تدرك اللغة

      قم بإنشاء مكون LocalizedLink للتنقل المدرك للغة:

      app/components/localized-link.tsx
      import type { FC } from "react";
      
      import { getLocalizedUrl, type LocalesValues } from "intlayer";
      import { useLocale } from "react-intlayer";
      import { Link, type LinkProps, type To } from "react-router";
      
      const isExternalLink = (to: string) => /^(https?:)?\/\//.test(to);
      
      // دالة لتحويل الرابط إلى رابط محلي بناءً على اللغة
      export const locacalizeTo = (to: To, locale: LocalesValues): To => {
        if (typeof to === "string") {
          if (isExternalLink(to)) {
            return to;
          }
      
          return getLocalizedUrl(to, locale);
        }
      
        if (isExternalLink(to.pathname ?? "")) {
          return to;
        }
      
        return {
          ...to,
          pathname: getLocalizedUrl(to.pathname ?? "", locale),
        };
      };
      
      // مكون رابط محلي يدعم التنقل حسب اللغة
      export const LocalizedLink: FC<LinkProps> = (props) => {
        const { locale } = useLocale();
      
        return <Link {...props} to={locacalizeTo(props.to, locale)} />;
      };
      

      في حال رغبت في التنقل إلى المسارات المحلية، يمكنك استخدام الخطاف useLocalizedNavigate:

      app/hooks/useLocalizedNavigate.ts
      import { useLocale } from "react-intlayer";
      import { type NavigateOptions, type To, useNavigate } from "react-router";
      
      import { locacalizeTo } from "~/components/localized-link";
      
      export const useLocalizedNavigate = () => {
        const navigate = useNavigate();
        const { locale } = useLocale();
      
        const localizedNavigate = (to: To, options?: NavigateOptions) => {
          const localedTo = locacalizeTo(to, locale);
      
          navigate(localedTo, options);
        };
      
        return localizedNavigate;
      };
      
    8. استخدام Intlayer في صفحاتك

      قم بالوصول إلى قواميس المحتوى الخاصة بك في جميع أنحاء تطبيقك:

      الصفحة الرئيسية المترجمة

      app/routes/page.tsx
      import { getIntlayer, validatePrefix } from "intlayer";
      import { useIntlayer } from "react-intlayer";
      import { data } from "react-router";
      
      import { LocaleSwitcher } from "~/components/locale-switcher";
      
      import { Navbar } from "~/components/navbar";
      import type { Route } from "./+types/page";
      
      export const loader = ({ params }: Route.LoaderArgs) => {
        const { locale } = params;
      
        const { isValid } = validatePrefix(locale);
      
        if (!isValid) {
          throw data("Locale not supported", { status: 404 });
        }
      };
      
      export const meta: Route.MetaFunction = ({ params }) => {
        const content = getIntlayer("page", params.locale);
      
        return [
          { title: content.title },
          { content: content.description, name: "description" },
        ];
      };
      
      export default function Page() {
        const { title, description, aboutLink } = useIntlayer("page");
      
        return (
          <div>
            <h1>{title}</h1>
            <p>{description}</p>
            <nav>
              <LocalizedLink to="/about">{aboutLink}</LocalizedLink>
            </nav>
          </div>
        );
      }
      
      app/routes/($locale)._index.tsx
      import { getIntlayer, validatePrefix } from "intlayer";
      import { useIntlayer } from "react-intlayer";
      import { data } from "react-router";
      
      import { LocaleSwitcher } from "~/components/locale-switcher";
      
      import { Navbar } from "~/components/navbar";
      import type { Route } from "./+types/($locale)._index";
      
      export const loader = ({ params }: Route.LoaderArgs) => {
        const { locale } = params;
      
        const { isValid } = validatePrefix(locale);
      
        if (!isValid) {
          throw data("Locale not supported", { status: 404 });
        }
      };
      
      export const meta: Route.MetaFunction = ({ params }) => {
        const content = getIntlayer("page", params.locale);
      
        return [
          { title: content.title },
          { content: content.description, name: "description" },
        ];
      };
      
      export default function Page() {
        const { title, description, aboutLink } = useIntlayer("page");
      
        return (
          <div>
            <h1>{title}</h1>
            <p>{description}</p>
            <nav>
              <LocalizedLink to="/about">{aboutLink}</LocalizedLink>
            </nav>
          </div>
        );
      }
      
      لمعرفة المزيد عن الخطاف useIntlayer، راجع التوثيق.
      إذا كان تطبيقك موجودًا بالفعل، يمكنك استخدام مترجم Intlayer، بالإضافة إلى أمر الاستخراج، لتحويل آلاف المكونات في ثانية واحدة.
    9. إنشاء مكون لتبديل اللغة

      قم بإنشاء مكون يسمح للمستخدمين بتغيير اللغات:

      app/components/locale-switcher.tsx
      import type { FC } from "react";
      
      import {
        getHTMLTextDir,
        getLocaleName,
        getLocalizedUrl,
        getPathWithoutLocale,
        defaultLocale,
      } from "intlayer";
      import { useIntlayer, useLocale } from "react-intlayer";
      import { Link, useLocation } from "react-router";
      
      export const LocaleSwitcher: FC = () => {
        const { localeSwitcherLabel } = useIntlayer("locale-switcher");
        const { pathname } = useLocation();
      
        const { availableLocales, locale, setLocale } = useLocale();
      
        const pathWithoutLocale = getPathWithoutLocale(pathname);
      
        return (
          <ol>
            {availableLocales.map((localeItem) => (
              <li key={localeItem}>
                <Link
                  aria-current={localeItem === locale ? "page" : undefined}
                  aria-label={`${localeSwitcherLabel.value} ${getLocaleName(localeItem)}`}
                  onClick={() => setLocale(localeItem)}
                  reloadDocument // Reload the page to apply the new locale
                  to={getLocalizedUrl(pathWithoutLocale, localeItem)}
                >
                  <span>
                    {/* اللغة - على سبيل المثال FR */}
                    {localeItem}
                  </span>
                  <span>
                    {/* اللغة بلغتها الخاصة - على سبيل المثال Français */}
                    {getLocaleName(localeItem, locale)}
                  </span>
                  <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
                    {/* اللغة باللغة الحالية - على سبيل المثال Francés مع تعيين اللغة الحالية إلى Locales.SPANISH */}
                    {getLocaleName(localeItem)}
                  </span>
                  <span dir="ltr" lang={defaultLocale}>
                    {/* اللغة باللغة الإنجليزية - على سبيل المثال French */}
                    {getLocaleName(localeItem, defaultLocale)}
                  </span>
                </Link>
              </li>
            ))}
          </ol>
        );
      };
      
      app/components/locale-switcher.tsx
      import type { FC } from "react";
      
      import {
        getHTMLTextDir,
        getLocaleName,
        getLocalizedUrl,
        getPathWithoutLocale,
        defaultLocale,
      } from "intlayer";
      import { useIntlayer, useLocale } from "react-intlayer";
      import { Link, useLocation } from "react-router";
      
      export const LocaleSwitcher: FC = () => {
        const { localeSwitcherLabel } = useIntlayer("locale-switcher");
        const { pathname } = useLocation();
      
        const { availableLocales, locale, setLocale } = useLocale();
      
        const pathWithoutLocale = getPathWithoutLocale(pathname);
      
        return (
          <ol>
            {availableLocales.map((localeItem) => (
              <li key={localeItem}>
                <Link
                  aria-current={localeItem === locale ? "page" : undefined}
                  aria-label={`${localeSwitcherLabel.value} ${getLocaleName(localeItem)}`}
                  onClick={() => setLocale(localeItem)}
                  reloadDocument // Reload the page to apply the new locale
                  to={getLocalizedUrl(pathWithoutLocale, localeItem)}
                >
                  <span>
                    {/* Locale - e.g. FR */}
                    {localeItem}
                  </span>
                  <span>
                    {/* Language in its own Locale - e.g. Français */}
                    {getLocaleName(localeItem, locale)}
                  </span>
                  <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
                    {/* Language in current Locale - e.g. Francés with current locale set to Locales.SPANISH */}
                    {getLocaleName(localeItem)}
                  </span>
                  <span dir="ltr" lang={defaultLocale}>
                    {/* Language in English - e.g. French */}
                    {getLocaleName(localeItem, defaultLocale)}
                  </span>
                </Link>
              </li>
            ))}
          </ol>
        );
      };
      
      لمعرفة المزيد عن الخطاف useLocale، راجع التوثيق.
    10. إضافة إدارة سمات HTML

      أنشئ خطافًا لإدارة سمات lang و dir في HTML:

      app/hooks/useI18nHTMLAttributes.tsx
      import { 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]);
      };
      

      ثم استخدمه في مكون الجذر الخاص بك:

      app/routes/layout.tsx
      import { Outlet } from "react-router";
      import { IntlayerProvider } from "react-intlayer";
      
      import { useI18nHTMLAttributes } from "app/hooks/useI18nHTMLAttributes"; // استيراد الخطاف
      
      export default function RootLayout() {
        useI18nHTMLAttributes(); // استدعاء الخطاف
      
        return (
          <IntlayerProvider>
            <Outlet />
          </IntlayerProvider>
        );
      }
      
    11. إضافة middleware

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

      لاحظ أنه لاستخدام intlayerProxy في الإنتاج، تحتاج إلى نقل حزمة vite-intlayer من devDependencies إلى dependencies.
      منذ Intlayer v9، يتم تجميع intlayerProxy() مباشرة في plugin intlayer() وتفعيله بشكل افتراضي من خلال خيار routing.enableProxy (true بشكل افتراضي). تسجيل هذه الدالة بشكل منفصل كما هو موضح أدناه أصبح اختيارياً الآن، يتم الاحتفاظ به للتوافقية العكسية والإعدادات التي تحتاج إلى التحكم في ترتيب plugin. عيّن routing.enableProxy: false للإلغاء. راجع ملاحظات الإصدار v9.
      vite.config.ts
      import { defineConfig } from "vite";
      import react from "@vitejs/plugin-react-swc";
      import { intlayer } from "vite-intlayer";
      
      // https://vitejs.dev/config/
      export default defineConfig({
        plugins: [
          react(),
          intlayer({
            proxy: {
              ignore: (req) => req.url?.startsWith("/api"),
            },
          }),
        ],
      });
      
    12. استخراج محتوى مكوناتك

      اختياري

      إذا كان لديك قاعدة بيانات كود موجودة، فقد يكون تحويل آلاف الملفات مستهلكًا للوقت.

      لتسهيل هذه العملية، يقترح Intlayer مترجمًا / مستخرجًا لتحويل مكوناتك واستخراج المحتوى.

      لإعداده، يمكنك إضافة قسم compiler في ملف intlayer.config.ts الخاص بك:

      intlayer.config.ts
      import { type IntlayerConfig } from "intlayer";
      
      const config: IntlayerConfig = {
        // ... بقية التكوين الخاص بك
        compiler: {
          /**
           * يشير إلى ما إذا كان يجب تمكين المترجم.
           */
          enabled: true,
      
          /**
           * يحدد مسار ملفات المخرجات
           */
          output: ({ fileName, extension }) => `./${fileName}${extension}`,
      
          /**
           * يشير إلى ما إذا كان يجب حفظ المكونات بعد تحويلها. بهذه الطريقة، يمكن تشغيل المترجم مرة واحدة فقط لتحويل التطبيق، ثم يمكن إزالته.
           */
          saveComponents: false,
      
          /**
           * بادئة مفتاح القاموس
           */
          dictionaryKeyPrefix: "",
        },
      };
      
      export default config;
      

      قم بتشغيل المستخرج لتحويل مكوناتك واستخراج المحتوى

      bash
      npx intlayer extract
      
      Since v9, the intlayerCompiler is included in the intlayer plugin. So you don't need to add it manually.

      قم بتحديث vite.config.ts لتضمين مكون intlayerCompiler الإضافي:

      vite.config.ts
      import { defineConfig } from "vite";
      import { intlayer, intlayerCompiler } from "vite-intlayer";
      
      export default defineConfig({
        plugins: [
          intlayer(),
          intlayerCompiler(), // Adds the compiler plugin
        ],
      });
      

      قم ببناء تطبيقك لتحويل مكوناتك واستخراج المحتوى

      bash
      npm run build # أو npm run dev
      

    تكوين TypeScript

    يستخدم Intlayer ميزة زيادة الوحدات (module augmentation) للاستفادة من مزايا TypeScript وجعل قاعدة الكود الخاصة بك أكثر قوة وموثوقية.

    تأكد من أن تكوين TypeScript يتضمن الأنواع التي يتم إنشاؤها تلقائيًا:

    tsconfig.json
    {
      // ... your existing configurations
      include: [
        // ... your existing includes
        ".intlayer/**/*.ts", // تضمين الأنواع المُنشأة تلقائيًا
      ],
    }
    

    تكوين Git

    يوصى بتجاهل الملفات التي تم إنشاؤها بواسطة Intlayer، لتجنب حفظها في مستودع Git الخاص بك.

    للقيام بذلك، يمكنك إضافة التعليمات التالية إلى ملف .gitignore الخاص بك:

    .gitignore
    # تجاهل الملفات المُنشأة بواسطة Intlayer
    .intlayer
    

    إضافة VS Code

    لتحسين تجربة التطوير الخاصة بك مع Intlayer، يمكنك تثبيت إضافة Intlayer الرسمية لـ VS Code.

    توفر هذه الإضافة ما يلي:

    • الإكمال التلقائي لمفاتيح الترجمة.
    • اكتشاف الأخطاء في الوقت الفعلي للترجمات المفقودة.
    • معاينة مضمنة (inline preview) للمحتوى المترجم.
    • إجراءات سريعة لإنشاء وتحديث الترجمات بسهولة.

    لمزيد من التفاصيل حول كيفية استخدام الإضافة، راجع توثيق إضافة Intlayer لـ VS Code.

    المضي قدمًا

    للمضي قدمًا، يمكنك تفعيل المحرر المرئي أو إدارة المحتوى الخاص بك خارجيًا باستخدام نظام إدارة المحتوى (CMS).

    مراجع التوثيق

    يوفر هذا الدليل الشامل كل ما تحتاجه لدمج Intlayer مع React Router v7 لتطبيق دولي بالكامل مع توجيه مدرك للغة ودعم TypeScript.

    الأسئلة الشائعة

    لا يوفر React Router v7 أي طبقة رسائل، لذا يمكنك إقرانه بمكتبة تدويل (i18n):

    • react-i18next: مكتبة شائعة تُحمل فضاءات أسماء JSON في وقت التشغيل.
    • react-intl: حل يعتمد على تنسيق ICU.
    • Intlayer: إعلان المحتوى بجانب المكون، ترجمة وقت البناء، دعم كامل لـ SSR ومحملات البيانات (loaders)، فحص كامل للأنواع، ترجمة بالذكاء الاصطناعي، ومحرر مرئي.

    انظر لماذا Intlayer و المقارنة المعيارية.

    أقل بكثير من أنظمة الكتالوجات التقليدية. يتجاهل المترجم المفاتيح غير المستخدمة وتفصل القواميس الديناميكية اللغات، مما يقلل الحزمة بنسبة تصل إلى 50%. انظر تحسين الحزم.

    نعم. اتبع دليل ترحيل react-i18next أو استخدم محولات التوافق للحفاظ على واجهات برمجة التطبيقات الحالية.

    نعم. تحافظ مكونة مزامنة JSON على ملفات /messages/{locale}/{namespace}.json الخاصة بك كمصدر الحقيقة وتُنشئ قواميس Intlayer منها، في كلا الاتجاهين. وتقوم مكونة مزامنة PO بنفس الشيء لكتالوجات gettext، وتسمح لك الملفات المقسمة حسب اللغة بتقسيم المحتوى حسب اللغة بدلاً من تجميع كل اللغات في ملف واحد.

    لا. قم بتشغيل npx intlayer extract وسيقرأ Intlayer مكوناتك، ويسحب السلاسل النصية الموجهة للمستخدم، ويكتب ملف .content بجانب كل منها، حتى تراجع diff بدلاً من نسخ السلاسل إلى كتالوج يدويًا. تشرح الخطوة 12 من هذا الدليل ذلك بالتفصيل.

    لأتمتة كاملة، يقوم Intlayer Compiler بالشيء نفسه في وقت البناء: يمسح كود JSX و TSX و Vue و Svelte عند كل تغيير، وينشئ القواميس ويزامنها عبر استبدال الوحدات الساخن (HMR)، بحيث لا توجد مفاتيح للحفاظ عليها يدويًا على الإطلاق.

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

    خمس أدوات، كلها اختيارية:

    • امتداد VS Code: الانتقال من مفتاح useIntlayer إلى ملف المحتوى المصرح به، استخراج المحتوى من المكون، وتشغيل build و fill و test و push و pull من لوحة الأوامر أو علامة تبويب Intlayer.
    • خادم LSP: نفس التجربة في أي محرر يدعم LSP، مع الانتقال إلى التعريف وعروض القيمة المترجمة عند التمرير والإكمال التلقائي للمفاتيح. يدعم أيضًا استدعاءات i18next و react-i18next و next-intl و use-intl.
    • خادم MCP: يكشف وثائق Intlayer و CLI إلى Cursor و VS Code و Claude Desktop و Claude Code و ChatGPT.
    • Agent skills: مهارات مخصصة مثل intlayer-config و intlayer-cli و intlayer-content.
    • ESLint plugin: قاعدة no-raw-text ترصد النصوص المكتوبة مباشرة بدون تدويل.