الرئيسيةبيئة اختبارمعرض الأعمالتطبيقوثيقةمدونة
    • Englishالإنجليزية
      EN
    • русскийالروسية
      RU
    • 日本語اليابانية
      JA
    • françaisالفرنسية
      FR
    • 한국어الكورية
      KO
    • 中文الصينية
      ZH
    • españolالإسبانية
      ES
    • Deutschالألمانية
      DE
    • العربيةالعربية
      AR
    • italianoالإيطالية
      IT
    • British Englishالإنجليزية (المملكة المتحدة)
      EN-GB
    • portuguêsالبرتغالية
      PT
    • हिन्दीالهندية
      HI
    • Türkçeالتركية
      TR
    • polskiالبولندية
      PL
    • Indonesiaالإندونيسية
      ID
    • Tiếng Việtالفيتنامية
      VI
    • українськаالأوكرانية
      UK
    /
    تصفية المستندات حسب الإطار
    Alt+←
    لماذا Intlayer؟
    ابدأ
    مفهوم
    • كيف يعمل Intlayer
    • التكوين
    • TestFillBuildWatchExtractLoginPushPullConfigurationListVersionEditorLiveDebugDoc ReviewDoc TranslateSDK
    • المحرر المرئي
    • CMS
    • تكامل CI/CD
    • ترجمةجمعتعدادشرطجنسإدراجملفتداخلMarkdownHTMLجلب الوظيفة
    • ملف لكل لغة
    • محرر
    • الملء التلقائي
    • اختبار
    • تحسين الحزمة
    بيئة
    • Next.js 14 وموجه التطبيق
      Next.js 15
      Next.js بدون locale URL
      Next.js وموجه الصفحة
      المترجم
    • Tanstack Start Solid
    • Astro و React
      Astro و Svelte
      Astro و Vue
      Astro و Solid
      Astro و Preact
      Astro و Lit
      Astro و Vanilla JS
    • React Router v7
      React Router v7 (fs-routes)
      Compiler
    • Nuxt و Vue
    • Vite و Solid
    • SvelteKit
    • Vite و Preact
    • Vite و Vanilla JS
    • Vite و Lit
    • Angular 19 (Webpack)
      Analog
    • React CRA
    • React Native و Expo
    • Express.js
      NestJS
      Fastify
      Hono
      Adonis
    • Lynx و React
    Plugins
    • JSON
    • gettext (.po)
    امتداد VS Code
    وكيل
    • خادم MCP
    • مهارات الوكيل
    إصدارات
    • v8
    • v7
    • v6
    مؤشر أداء
    • Next.js
    • TanStack
    • Vue
    • Solid
    • Svelte
    مدونة
    طرح سؤال
    1. Documentation
    2. بيئة
    3. Tanstack Start
    إنشاء:2025-09-09آخر تحديث:2026-05-06
    عرض قالب التطبيق على GitHub

    هذه الصفحة لديها قالب تطبيق متاح.

    عرض تطبيق العرض

    هذه الصفحة ترتبط بعرض مباشر للقالب.

    شاهد الفيديو التعليمي

    هذه الصفحة لديها فيديو تعليمي متاح.

    استخدم هذه الصفحة والموفر AI الذي تريده
    ChatGPT
    Claude
    DeepSeek
    Google AI mode
    Gemini
    Perplexity
    Mistral
    Grok

    استخدم مساعدك المفضل للملخص واستخدم هذه الصفحة والموفر AI الذي تريده

    تاريخ الإصدارات

    1. "تحديث استخدام واجهة برمجة تطبيقات useIntlayer في Solid للوصول المباشر إلى الخصائص"
      v8.9.04‏/5‏/2026
    2. "إضافة أمر init"
      v7.5.930‏/12‏/2025
    3. "تقديم validatePrefix وإضافة الخطوة 14: معالجة صفحات 404 مع المسارات المترجمة."
      v7.4.011‏/12‏/2025
    4. "إضافة الخطوة 13: جلب اللغة في إجراءات الخادم (اختياري)"
      v7.3.95‏/12‏/2025
    5. "إضافة الخطوة 13: تكييف Nitro"
      v7.2.318‏/11‏/2025
    6. "إصلاح الافتراضي للبادئة عن طريق إضافة وظيفة getPrefix واستخدام useLocalizedNavigate و LocaleSwitcher و LocalizedLink."
      v7.1.017‏/11‏/2025
    7. "تحديث التوثيق"
      v6.5.23‏/10‏/2025
    8. "تمت الإضافة لـ TanStack Start"
      v5.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

    www.youtube.com
    ide.intlayer.org
    intlayer-tanstack-start-template.vercel.app

    انظر قالب التطبيق على GitHub.

    الخطوة 1: إنشاء المشروع

    ابدأ بإنشاء مشروع TanStack Start جديد باتباع دليل بدء مشروع جديد على موقع TanStack Start.

    الخطوة 2: تثبيت حزم Intlayer

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

    bash
    نسخ الكود

    نسخ الكود إلى الحافظة

    npm install intlayer react-intlayernpm install vite-intlayer --save-devnpx intlayer init
    • intlayer

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

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

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

    الخطوة 3: تكوين مشروعك

    أنشئ ملف تكوين لتكوين لغات تطبيقك:

    intlayer.config.ts
    نسخ الكود

    نسخ الكود إلى الحافظة

    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 المترجمة، وإعادة توجيه الوسيط، وأسماء ملفات تعريف الارتباط، وموقع وامتداد إعلانات المحتوى الخاصة بك، وتعطيل سجلات Intlayer في وحدة التحكم، والمزيد. للحصول على قائمة كاملة بالمعلمات المتاحة، راجع توثيق التكوين.

    الخطوة 4: دمج Intlayer في تكوين Vite الخاص بك

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

    vite.config.ts
    نسخ الكود

    نسخ الكود إلى الحافظة

    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";const config = defineConfig({  plugins: [    nitro(),    intlayer(),    tanstackStart({      router: {        routeFileIgnorePattern:          ".content.(ts|tsx|js|mjs|cjs|jsx|json|jsonc|json5)$",      },    }),    viteReact(),  ],});export default config;
    تُستخدم إضافة intlayer() لـ Vite لدمج Intlayer مع Vite. تضمن بناء ملفات إعلان المحتوى ومراقبتها في وضع التطوير. كما تُعرف متغيرات بيئة Intlayer داخل تطبيق Vite. بالإضافة إلى ذلك، توفر أسماء مستعارة لتحسين الأداء.

    الخطوة 5: إنشاء التخطيط الجذري

    قم بتكوين التخطيط الجذري الخاص بك لدعم التدويل باستخدام useParams للكشف عن اللغة الحالية وتعيين سمات lang و dir على علامة html.

    src/routes/__root.tsx
    نسخ الكود

    نسخ الكود إلى الحافظة

    import {  createRootRouteWithContext,  HeadContent,  Scripts,} from "@tanstack/react-router";import { defaultLocale, getHTMLTextDir } from "intlayer";import { type ReactNode } from "react";import { IntlayerProvider } from "react-intlayer";import { Route as LocaleRoute } from "./{-$locale}/route";export const Route = createRootRouteWithContext<{}>()({  head: () => ({    meta: [      {        charSet: "utf-8",      },      {        content: "width=device-width, initial-scale=1",        name: "viewport",      },      {        title: "TanStack Start Starter",      },    ],  }),  shellComponent: RootDocument,});function RootDocument({ children }: { children: ReactNode }) {  const params = LocaleRoute.useParams();  const locale = params?.locale ?? defaultLocale;  return (    <html dir={getHTMLTextDir(locale)} lang={locale}>      <head>        <HeadContent />      </head>      <body>        <IntlayerProvider locale={locale}>{children}</IntlayerProvider>        <Scripts />      </body>    </html>  );}
    إذا كنت ترغب في استخدام المحتوى الخاص بك في خاصية من نوع string، مثل alt، title، href، aria-label، إلخ، يجب عليك استدعاء قيمة الدالة، مثل:
    html
    نسخ الكود

    نسخ الكود إلى الحافظة

    <img src="{content.image.src.value}" alt="{content.image.value}" /><img src="{content.image.src.toString()}" alt="{content.image.toString()}" /><img src="{String(content.image.src)}" alt="{String(content.image)}" />

    الخطوة 6: إنشاء تخطيط اللغة

    أنشئ تخطيطًا يتعامل مع بادئة اللغة ويقوم بالتحقق من الصحة.

    src/routes/{-$locale}/route.tsx
    نسخ الكود

    نسخ الكود إلى الحافظة

    import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";import { validatePrefix } from "intlayer";export const Route = createFileRoute("/{-$locale}")({  beforeLoad: ({ params }) => {    const localeParam = params.locale;    // التحقق من صحة بادئة اللغة    const { isValid, localePrefix } = validatePrefix(localeParam);    if (!isValid) {      throw redirect({        to: "/{-$locale}/404",        params: { locale: localePrefix },      });    }  },  component: Outlet,});
    هنا، {-$locale} هي معلمة مسار ديناميكية يتم استبدالها باللغة الحالية. هذا الترميز يجعل الجزء اختياريًا، مما يسمح له بالعمل مع أوضاع التوجيه مثل 'prefix-no-default' وما إلى ذلك.

    كن على علم بأن هذا الجزء قد يسبب مشاكل إذا كنت تستخدم أجزاء ديناميكية متعددة في نفس المسار (على سبيل المثال، /{-$locale}/other-path/$anotherDynamicPath/...). بالنسبة لوضع 'prefix-all'، قد تفضل تبديل الجزء إلى $locale بدلاً من ذلك. بالنسبة لوضع 'no-prefix' أو 'search-params'، يمكنك إزالة الجزء تمامًا.

    الخطوة 7: إعلان المحتوى الخاص بك

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

    src/contents/page.content.ts
    نسخ الكود

    نسخ الكود إلى الحافظة

    import type { Dictionary } from "intlayer";import { t } from "intlayer";const appContent = {  content: {    links: {      about: t({        en: "About",        es: "Acerca de",        fr: "À propos",      }),      home: t({        en: "Home",        es: "Inicio",        fr: "Accueil",      }),    },    meta: {      title: t({        en: "Welcome to Intlayer + TanStack Router",        es: "Bienvenido a Intlayer + TanStack Router",        fr: "Bienvenue à Intlayer + TanStack Router",      }),      description: t({        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",      }),    },  },  key: "app",} satisfies Dictionary;export default appContent;
    يمكن تعريف إعلانات المحتوى الخاصة بك في أي مكان في تطبيقك بمجرد تضمينها في دليل contentDir (افتراضيًا، ./app). وتطابق امتداد ملف إعلان المحتوى (افتراضيًا، .content.{json,ts,tsx,js,jsx,mjs,cjs}).
    لمزيد من التفاصيل، راجع توثيق إعلان المحتوى.

    الخطوة 8: إنشاء مكونات وخطافات مدركة للغة

    أنشئ مكون LocalizedLink للتنقل المدرك للغة:

    src/components/localized-link.tsx
    نسخ الكود

    نسخ الكود إلى الحافظة

    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 To = StripLocalePrefix<LinkComponentProps["to"]>;export type StripLocalePrefix<T extends string | undefined> = T extends  | `/${typeof LOCALE_ROUTE}/`  | `/${typeof LOCALE_ROUTE}`  ? "/"  : T extends `/${typeof LOCALE_ROUTE}/${infer Rest}`    ? `/${Rest}`    : T;type LocalizedLinkProps = {  to?: To;} & Omit<LinkComponentProps, "to">;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.
    • حقن معلمة اللغة في عنوان URL لضمان إعادة توجيه المستخدم مباشرة إلى المسار المترجم.

    ثم يمكننا إنشاء خطاف useLocalizedNavigate للتنقل البرمجي:

    src/hooks/useLocalizedNavigate.tsx
    نسخ الكود

    نسخ الكود إلى الحافظة

    import { useNavigate } from "@tanstack/react-router";import { getPrefix } from "intlayer";import { useLocale } from "react-intlayer";import type { StripLocalePrefix } from "@/components/localized-link";import type { FileRouteTypes } from "@/routeTree.gen";type NavigateFn = ReturnType<typeof useNavigate>;type BaseNavigateOptions = Parameters<NavigateFn>[0];type LocalizedTo = StripLocalePrefix<FileRouteTypes["to"]>;export type LocalizedNavigateOptions = Omit<  BaseNavigateOptions,  "to" | "params"> & {  to: LocalizedTo;  params?: Omit<NonNullable<BaseNavigateOptions["params"]>, "locale">;};type LocalizedNavigate = (  options: LocalizedNavigateOptions) => ReturnType<NavigateFn>;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;};

    الخطوة 9: استخدام Intlayer في صفحاتك

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

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

    src/routes/{-$locale}/index.tsx
    نسخ الكود

    نسخ الكود إلى الحافظة

    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,});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 ، راجع التوثيق.

    الخطوة 10: إنشاء مكون لتبديل اللغة

    أنشئ مكونًا للسماح للمستخدمين بتغيير اللغات:

    src/components/locale-switcher.tsx
    نسخ الكود

    نسخ الكود إلى الحافظة

    import { useLocation } from "@tanstack/react-router";import {  getHTMLTextDir,  getLocaleName,  getPathWithoutLocale,  getPrefix,  Locales,} from "intlayer";import type { FC } from "react";import { useLocale } from "react-intlayer";import { LocalizedLink, type 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 }}            to={pathWithoutLocale as To}          >            <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 ، راجع التوثيق.

    الخطوة 11: إدارة سمات HTML

    كما رأينا في الخطوة 5، يمكنك إدارة سمات lang و dir لعلامة html باستخدام useParams في مكونك الجذري. يضمن هذا تعيين السمات الصحيحة على الخادم والعميل.

    src/routes/__root.tsx
    نسخ الكود

    نسخ الكود إلى الحافظة

    function RootDocument({ children }: { children: ReactNode }) {  const params = LocaleRoute.useParams();  const locale = params?.locale ?? defaultLocale;  return (    <html dir={getHTMLTextDir(locale)} lang={locale}>      {/* ... */}    </html>  );}

    الخطوة 12: إضافة وسيط (اختياري)

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

    لاحظ أنه لاستخدام intlayerProxy في الإنتاج، تحتاج إلى نقل حزمة vite-intlayer من devDependencies إلى dependencies.
    vite.config.ts
    نسخ الكود

    نسخ الكود إلى الحافظة

    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, intlayerProxy } from "vite-intlayer";export default defineConfig({  plugins: [    intlayerProxy(), // يجب وضع البروكسي قبل الخادم إذا كنت تستخدم Nitro    nitro(),    intlayer(),    tanstackStart({      router: {        routeFileIgnorePattern:          ".content.(ts|tsx|js|mjs|cjs|jsx|json|jsonc|json5)$",      },    }),    viteReact(),  ],});

    الخطوة 13: تدويل البيانات الوصفية الخاصة بك (اختياري)

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

    src/routes/{-$locale}/index.tsx
    نسخ الكود

    نسخ الكود إلى الحافظة

    import { createFileRoute } from "@tanstack/react-router";import { getIntlayer } from "intlayer";export const Route = createFileRoute("/{-$locale}/")({  component: RouteComponent,  head: ({ params }) => {    const { locale } = params;    const path = "/"; // The path for this route    const metaContent = getIntlayer("app", locale);    return {      links: [        // Canonical link: Points to the current localized page        { rel: "canonical", href: getLocalizedUrl(path, locale) },        // Hreflang: Tell Google about all localized versions        ...localeMap(({ locale: mapLocale }) => ({          rel: "alternate",          hrefLang: mapLocale,          href: getLocalizedUrl(path, mapLocale),        })),        // x-default: For users in unmatched languages        // Define the default fallback locale (usually your primary language)        {          rel: "alternate",          hrefLang: "x-default",          href: getLocalizedUrl(path, defaultLocale),        },      ],      meta: [        { title: metaContent.title },        { name: "description", content: metaContent.meta.description },      ],    };  },});

    الخطوة 14: جلب اللغة في إجراءات الخادم الخاصة بك (اختياري)

    قد ترغب في الوصول إلى اللغة الحالية من داخل إجراءات الخادم أو نقاط نهاية API الخاصة بك. يمكنك القيام بذلك باستخدام مساعد getLocale من intlayer.

    إليك مثال باستخدام وظائف خادم TanStack Start:

    src/routes/{-$locale}/index.tsx
    نسخ الكود

    نسخ الكود إلى الحافظة

    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({    // الحصول على ملف تعريف الارتباط من الطلب (الافتراضي: 'INTLAYER_LOCALE')    getCookie: (name) => {      const cookieString = getRequestHeader("cookie");      return getCookie(name, cookieString);    },    // الحصول على الترويسة من الطلب (الافتراضي: 'x-intlayer-locale')    // تراجع باستخدام مفاوضة Accept-Language    getHeader: (name) => getRequestHeader(name),  });  // جلب بعض المحتوى باستخدام getIntlayer()  const content = getIntlayer("app", locale);  return { locale, content };});

    الخطوة 15: إدارة الصفحات غير الموجودة (اختياري)

    عندما يزور المستخدم صفحة غير موجودة، يمكنك عرض صفحة مخصصة "غير موجودة" وقد تؤثر بادئة اللغة على الطريقة التي يتم بها تشغيل صفحة "غير موجودة".

    فهم معالجة 404 في TanStack Router مع بادئات اللغة

    في TanStack Router، تتطلب معالجة صفحات 404 مع المسارات المترجمة نهجًا متعدد الطبقات:

    1. مسار 404 مخصص: مسار محدد لعرض واجهة مستخدم 404
    2. التحقق من الصحة على مستوى المسار: يتحقق من صحة بادئات اللغة ويعيد توجيه البادئات غير الصالحة إلى 404
    3. مسار catch-all: يلتقط أي مسارات غير متطابقة داخل جزء اللغة
    src/routes/{-$locale}/404.tsx
    نسخ الكود

    نسخ الكود إلى الحافظة

    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>  );}
    src/routes/{-$locale}/route.tsx
    نسخ الكود

    نسخ الكود إلى الحافظة

    import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";import { validatePrefix } from "intlayer";import { NotFoundComponent } from "./404";export const Route = createFileRoute("/{-$locale}")({  // يتم تشغيل beforeLoad قبل رندر المسار (على كل من الخادم والعميل)  // إنه المكان المثالي للتحقق من صحة بادئة اللغة  beforeLoad: ({ params }) => {    const localeParam = params.locale;    // validatePrefix يتحقق مما إذا كانت اللغة صالحة وفقًا لتكوين intlayer الخاص بك    const { isValid, localePrefix } = validatePrefix(localeParam);    if (!isValid) {      // بادئة لغة غير صالحة - إعادة التوجيه إلى صفحة 404 ببادئة لغة صالحة      throw redirect({        to: "/{-$locale}/404",        params: { locale: localePrefix },      });    }  },  component: Outlet,  // يتم استدعاء notFoundComponent عندما لا يوجد مسار طفل  // على سبيل المثال، /en/non-existent-page يطلق هذا داخل تخطيط /en  notFoundComponent: NotFoundComponent,});
    src/routes/{-$locale}/$.tsx
    نسخ الكود

    نسخ الكود إلى الحافظة

    import { createFileRoute } from "@tanstack/react-router";import { NotFoundComponent } from "./404";// المسار $ (splat/catch-all) يطابق أي مسار لا يطابق المسارات الأخرى// على سبيل المثال، /en/some/deeply/nested/invalid/path// هذا يضمن أن جميع المسارات غير المتطابقة داخل اللغة تعرض صفحة 404// بدون هذا، قد تعرض المسارات العميقة غير المتطابقة صفحة فارغة أو خطأexport const Route = createFileRoute("/{-$locale}/$")({  component: NotFoundComponent,});

    الخطوة 16: تكوين TypeScript (اختياري)

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

    تأكد من أن تكوين TypeScript الخاص بك يتضمن الأنواع المولدة تلقائيًا:

    tsconfig.json
    نسخ الكود

    نسخ الكود إلى الحافظة

    {  // ... تكويناتك الحالية  include: [    // ... التضمينات الحالية الخاصة بك    ".intlayer/**/*.ts", // تضمين الأنواع المولدة تلقائيًا  ],}

    تكوين Git

    يوصى بتجاهل الملفات الناتجة عن Intlayer. يتيح لك هذا تجنب الالتزام بها في مستودع Git الخاص بك.

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

    .gitignore
    نسخ الكود

    نسخ الكود إلى الحافظة

    # تجاهل الملفات الناتجة عن Intlayer.intlayer

    (اختياري) خطوة 1 : استخراج محتوى مكوناتك

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

    لتسهيل هذه العملية، يقترح 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
    bash
    نسخ الكود

    نسخ الكود إلى الحافظة

    npm install @intlayer/babel --save-dev
    babel.config.js
    نسخ الكود

    نسخ الكود إلى الحافظة

    const { intlayerExtractBabelPlugin, getExtractPluginOptions,} = require("@intlayer/babel");module.exports = { presets: ["next/babel"], plugins: [   // استخراج المحتوى من المكونات إلى القواميس   [intlayerExtractBabelPlugin, getExtractPluginOptions()], ],};
    bash
    نسخ الكود

    نسخ الكود إلى الحافظة

    npm run build # أو npm run dev

    إضافة VS Code

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

    التثبيت من VS Code Marketplace

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

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

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


    اذهب أبعد من ذلك

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


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

    • توثيق Intlayer
    • توثيق TanStack Start
    • خطاف useIntlayer
    • خطاف useLocale
    • إعلان المحتوى
    • التكوين
    المترجم
    Tanstack Start Solid
    Alt+→

    في هذه الصفحة

      المناقشات مجهولة الهوية ويتم مراجعتها بانتظام لمعالجة المشكلات الشائعة. لا تتردد في مشاركة أفكار الميزات أو التعليقات على الوثائق أو أي شيء يتعلق بـ Intlayer, نستخدم هذه المدخلات لتشكيل خارطة الطريق وتحسين المنتج.

      npm install intlayer react-intlayernpm install vite-intlayer --save-devnpx intlayer init
      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;
      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";const config = defineConfig({  plugins: [    nitro(),    intlayer(),    tanstackStart({      router: {        routeFileIgnorePattern:          ".content.(ts|tsx|js|mjs|cjs|jsx|json|jsonc|json5)$",      },    }),    viteReact(),  ],});export default config;
      import {  createRootRouteWithContext,  HeadContent,  Scripts,} from "@tanstack/react-router";import { defaultLocale, getHTMLTextDir } from "intlayer";import { type ReactNode } from "react";import { IntlayerProvider } from "react-intlayer";import { Route as LocaleRoute } from "./{-$locale}/route";export const Route = createRootRouteWithContext<{}>()({  head: () => ({    meta: [      {        charSet: "utf-8",      },      {        content: "width=device-width, initial-scale=1",        name: "viewport",      },      {        title: "TanStack Start Starter",      },    ],  }),  shellComponent: RootDocument,});function RootDocument({ children }: { children: ReactNode }) {  const params = LocaleRoute.useParams();  const locale = params?.locale ?? defaultLocale;  return (    <html dir={getHTMLTextDir(locale)} lang={locale}>      <head>        <HeadContent />      </head>      <body>        <IntlayerProvider locale={locale}>{children}</IntlayerProvider>        <Scripts />      </body>    </html>  );}
      <img src="{content.image.src.value}" alt="{content.image.value}" /><img src="{content.image.src.toString()}" alt="{content.image.toString()}" /><img src="{String(content.image.src)}" alt="{String(content.image)}" />
      import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";import { validatePrefix } from "intlayer";export const Route = createFileRoute("/{-$locale}")({  beforeLoad: ({ params }) => {    const localeParam = params.locale;    // التحقق من صحة بادئة اللغة    const { isValid, localePrefix } = validatePrefix(localeParam);    if (!isValid) {      throw redirect({        to: "/{-$locale}/404",        params: { locale: localePrefix },      });    }  },  component: Outlet,});
      import type { Dictionary } from "intlayer";import { t } from "intlayer";const appContent = {  content: {    links: {      about: t({        en: "About",        es: "Acerca de",        fr: "À propos",      }),      home: t({        en: "Home",        es: "Inicio",        fr: "Accueil",      }),    },    meta: {      title: t({        en: "Welcome to Intlayer + TanStack Router",        es: "Bienvenido a Intlayer + TanStack Router",        fr: "Bienvenue à Intlayer + TanStack Router",      }),      description: t({        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",      }),    },  },  key: "app",} satisfies Dictionary;export default appContent;
      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 To = StripLocalePrefix<LinkComponentProps["to"]>;export type StripLocalePrefix<T extends string | undefined> = T extends  | `/${typeof LOCALE_ROUTE}/`  | `/${typeof LOCALE_ROUTE}`  ? "/"  : T extends `/${typeof LOCALE_ROUTE}/${infer Rest}`    ? `/${Rest}`    : T;type LocalizedLinkProps = {  to?: To;} & Omit<LinkComponentProps, "to">;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"]}    />  );};
      import { useNavigate } from "@tanstack/react-router";import { getPrefix } from "intlayer";import { useLocale } from "react-intlayer";import type { StripLocalePrefix } from "@/components/localized-link";import type { FileRouteTypes } from "@/routeTree.gen";type NavigateFn = ReturnType<typeof useNavigate>;type BaseNavigateOptions = Parameters<NavigateFn>[0];type LocalizedTo = StripLocalePrefix<FileRouteTypes["to"]>;export type LocalizedNavigateOptions = Omit<  BaseNavigateOptions,  "to" | "params"> & {  to: LocalizedTo;  params?: Omit<NonNullable<BaseNavigateOptions["params"]>, "locale">;};type LocalizedNavigate = (  options: LocalizedNavigateOptions) => ReturnType<NavigateFn>;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;};
      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,});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>  );}
      import { useLocation } from "@tanstack/react-router";import {  getHTMLTextDir,  getLocaleName,  getPathWithoutLocale,  getPrefix,  Locales,} from "intlayer";import type { FC } from "react";import { useLocale } from "react-intlayer";import { LocalizedLink, type 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 }}            to={pathWithoutLocale as To}          >            <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>  );};
      function RootDocument({ children }: { children: ReactNode }) {  const params = LocaleRoute.useParams();  const locale = params?.locale ?? defaultLocale;  return (    <html dir={getHTMLTextDir(locale)} lang={locale}>      {/* ... */}    </html>  );}
      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, intlayerProxy } from "vite-intlayer";export default defineConfig({  plugins: [    intlayerProxy(), // يجب وضع البروكسي قبل الخادم إذا كنت تستخدم Nitro    nitro(),    intlayer(),    tanstackStart({      router: {        routeFileIgnorePattern:          ".content.(ts|tsx|js|mjs|cjs|jsx|json|jsonc|json5)$",      },    }),    viteReact(),  ],});
      import { createFileRoute } from "@tanstack/react-router";import { getIntlayer } from "intlayer";export const Route = createFileRoute("/{-$locale}/")({  component: RouteComponent,  head: ({ params }) => {    const { locale } = params;    const path = "/"; // The path for this route    const metaContent = getIntlayer("app", locale);    return {      links: [        // Canonical link: Points to the current localized page        { rel: "canonical", href: getLocalizedUrl(path, locale) },        // Hreflang: Tell Google about all localized versions        ...localeMap(({ locale: mapLocale }) => ({          rel: "alternate",          hrefLang: mapLocale,          href: getLocalizedUrl(path, mapLocale),        })),        // x-default: For users in unmatched languages        // Define the default fallback locale (usually your primary language)        {          rel: "alternate",          hrefLang: "x-default",          href: getLocalizedUrl(path, defaultLocale),        },      ],      meta: [        { title: metaContent.title },        { name: "description", content: metaContent.meta.description },      ],    };  },});
      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({    // الحصول على ملف تعريف الارتباط من الطلب (الافتراضي: 'INTLAYER_LOCALE')    getCookie: (name) => {      const cookieString = getRequestHeader("cookie");      return getCookie(name, cookieString);    },    // الحصول على الترويسة من الطلب (الافتراضي: 'x-intlayer-locale')    // تراجع باستخدام مفاوضة Accept-Language    getHeader: (name) => getRequestHeader(name),  });  // جلب بعض المحتوى باستخدام getIntlayer()  const content = getIntlayer("app", locale);  return { locale, content };});
      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 { NotFoundComponent } from "./404";export const Route = createFileRoute("/{-$locale}")({  // يتم تشغيل beforeLoad قبل رندر المسار (على كل من الخادم والعميل)  // إنه المكان المثالي للتحقق من صحة بادئة اللغة  beforeLoad: ({ params }) => {    const localeParam = params.locale;    // validatePrefix يتحقق مما إذا كانت اللغة صالحة وفقًا لتكوين intlayer الخاص بك    const { isValid, localePrefix } = validatePrefix(localeParam);    if (!isValid) {      // بادئة لغة غير صالحة - إعادة التوجيه إلى صفحة 404 ببادئة لغة صالحة      throw redirect({        to: "/{-$locale}/404",        params: { locale: localePrefix },      });    }  },  component: Outlet,  // يتم استدعاء notFoundComponent عندما لا يوجد مسار طفل  // على سبيل المثال، /en/non-existent-page يطلق هذا داخل تخطيط /en  notFoundComponent: NotFoundComponent,});
      import { createFileRoute } from "@tanstack/react-router";import { NotFoundComponent } from "./404";// المسار $ (splat/catch-all) يطابق أي مسار لا يطابق المسارات الأخرى// على سبيل المثال، /en/some/deeply/nested/invalid/path// هذا يضمن أن جميع المسارات غير المتطابقة داخل اللغة تعرض صفحة 404// بدون هذا، قد تعرض المسارات العميقة غير المتطابقة صفحة فارغة أو خطأexport const Route = createFileRoute("/{-$locale}/$")({  component: NotFoundComponent,});
      {  // ... تكويناتك الحالية  include: [    // ... التضمينات الحالية الخاصة بك    ".intlayer/**/*.ts", // تضمين الأنواع المولدة تلقائيًا  ],}
      # تجاهل الملفات الناتجة عن Intlayer.intlayer
      npx intlayer extract
      npm install @intlayer/babel --save-dev
      const { intlayerExtractBabelPlugin, getExtractPluginOptions,} = require("@intlayer/babel");module.exports = { presets: ["next/babel"], plugins: [   // استخراج المحتوى من المكونات إلى القواميس   [intlayerExtractBabelPlugin, getExtractPluginOptions()], ],};
      npm run build # أو npm run dev