الرئيسيةبيئة اختبارمعرض الأعمالتطبيقوثيقةمدونة
    • 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. Vite و React
    4. Compiler
    إنشاء:2024-03-07آخر تحديث: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. "Update compiler options, add FilePathPattern support"
      v8.2.09‏/3‏/2026
    3. "الإصدار الأولي"
      v8.1.623‏/2‏/2026

    تمت ترجمة محتوى هذه الصفحة باستخدام الذكاء الاصطناعي.

    اعرض آخر نسخة المحتوى الأصلي باللغة الإنكليزية
    تعديل هذه الوثيقة

    إذا كان لديك فكرة لتحسين هذه الوثيقة، فلا تتردد في المساهمة من خلال تقديم طلب سحب على GitHub.

    رابط GitHub للتوثيق
    نسخ

    نسخ الـ Markdown من المستند إلى الحافظة

    كيفية جعل تطبيق Vite و React الحالي متعدد اللغات (i18n) لاحقًا (دليل i18n لعام 2026)

    www.youtube.com
    ide.intlayer.org
    intlayer-vite-react-template.vercel.app

    شاهد قالب التطبيق على GitHub.

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

    لماذا يصعب تدويل تطبيق موجود؟

    إذا كنت قد حاولت يومًا إضافة لغات متعددة إلى تطبيق تم بناؤه للغة واحدة فقط، فأنت تعرف المعاناة. الأمر ليس مجرد "صعب" - إنه ممل. عليك فحص كل ملف على حدة، ومطاردة كل سلسلة نصية، ونقلها إلى ملفات قاموس منفصلة.

    ثم يأتي الجزء الخطير: استبدال كل هذا النص بخطافات الكود (code hooks) دون كسر التخطيط أو المنطق. إنه نوع العمل الذي يوقف تطوير الميزات الجديدة لأسابيع ويشعرك بإعادة هيكلة (refactoring) لا تنتهي.

    ما هو مترجم Intlayer؟

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

    وثائق المترجم: /ar/doc/compiler

    القيود

    نظرًا لأن المترجم يقوم بتحليل الكود وتحويله (إدخال الخطافات وإنشاء القواميس) في وقت الترجمة (compile time)، فقد يؤدي ذلك إلى إبطاء عملية بناء تطبيقك.

    للتخفيف من هذا التأثير أثناء التطوير، يمكنك تكوين المترجم ليعمل في وضع 'build-only' أو تعطيله عندما لا تكون هناك حاجة إليه.


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

    الخطوة 1: تثبيت التبعيات

    ثبّت الحزم اللازمة باستخدام npm:

    bash
    نسخ الكود

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

    npm install intlayer react-intlayernpm install vite-intlayer --save-devnpx intlayer init
    • intlayer الحزمة الأساسية التي توفر أدوات التدويل لإدارة التكوين، والترجمة، وإعلان المحتوى، والتحويل البرمجي، وأوامر CLI.

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

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

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

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

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

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

    import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH, Locales.ARABIC],    defaultLocale: Locales.ENGLISH,  },  compiler: {    /**     * يشير إلى ما إذا كان يجب تمكين المجمّع.     */    enabled: true,    /**     * دليل الإخراج للقواميس المحسنة.     */    output: ({ locale, key }) => `compiler/${locale}/${key}.json`,    /**     * أدخل المحتوى فقط في الملف الذي تم إنشاؤه، بدون مفتاح.     */    noMetadata: false,    /**     * بادئة مفتاح القاموس     */    dictionaryKeyPrefix: "", // Remove base prefix    /**     * يشير إلى ما إذا كان يجب حفظ المكونات بعد تحويلها.     * بهذه الطريقة، يمكن تشغيل المجمّع مرة واحدة فقط لتحويل التطبيق، ثم يمكن إزالته.     */    saveComponents: false,  },  ai: {    provider: "openai",    model: "gpt-5-mini",    apiKey: process.env.OPEN_AI_API_KEY,    applicationContext: "هذا التطبيق هو تطبيق خرائط", // ملاحظة: يمكنك تخصيص وصف التطبيق هذا  },};export default config;
    ملاحظة: تأكد من ضبط OPEN_AI_API_KEY في متغيرات البيئة الخاصة بك.
    من خلال ملف التكوين هذا، يمكنك إعداد عناوين URL المترجمة، وإعادة توجيه الوسيط، وأسماء ملفات تعريف الارتباط، وموقع وامتداد إعلانات المحتوى الخاصة بك، وتعطيل سجلات Intlayer في وحدة التحكم، والمزيد. للحصول على قائمة كاملة بالمعلمات المتاحة، ارجع إلى وثائق التكوين.

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

    أضف مكون intlayer الإضافي إلى التكوين الخاص بك.

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

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

    import { defineConfig } from "vite";import react from "@vitejs/plugin-react-swc";import { intlayer, intlayerCompiler } from "vite-intlayer";// https://vitejs.dev/config/export default defineConfig({  plugins: [react(), intlayer(), intlayerCompiler()],});
    يُستخدم مكون intlayer() الإضافي لـ Vite لدمج Intlayer مع Vite. يضمن بناء ملفات إعلان المحتوى ومراقبتها في وضع التطوير. يحدد متغيرات بيئة Intlayer داخل تطبيق Vite. بالإضافة إلى ذلك، يوفر أسماء مستعارة (aliases) لتحسين الأداء.
    يُستخدم مكون intlayerCompiler() الإضافي لـ Vite لاستخراج المحتوى من المكون وكتابة ملفات .content.

    الخطوة 4: ترجمة الكود الخاص بك

    فقط اكتب مكوناتك بسلاسل نصية ثابتة بلغتك الافتراضية. يتولى المترجم الباقي.

    مثال على كيف قد تبدو صفحتك:

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

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

    import { useState, type FC } from "react";import reactLogo from "./assets/react.svg";import viteLogo from "/vite.svg";import "./App.css";import { IntlayerProvider } from "react-intlayer";const AppContent: FC = () => { const [count, setCount] = useState(0); return (   <>     <div>       <a href="https://vitejs.dev" target="_blank">         <img src={viteLogo} className="logo" alt="Vite logo" />       </a>       <a href="https://react.dev" target="_blank">         <img src={reactLogo} className="logo react" alt="React logo" />       </a>     </div>     <h1>Vite + React</h1>     <div className="card">       <button onClick={() => setCount((count) => count + 1)}>         count is {count}       </button>       <p>         Edit <code>src/App.tsx</code> and save to test HMR       </p>     </div>     <p className="read-the-docs">       Click on the Vite and React logos to learn more     </p>   </> );};const App: FC = () => ( <IntlayerProvider>   <AppContent /> </IntlayerProvider>);export default App;
    i18n/app-content.content.json
    نسخ الكود

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

    { key: "app-content", content: {   nodeType: "translation",   translation: {     en: {       viteLogo: "Vite logo",       reactLogo: "React logo",       title: "Vite + React",       countButton: "count is",       editMessage: "Edit",       hmrMessage: "and save to test HMR",       readTheDocs: "Click on the Vite and React logos to learn more",     },     ar: {       viteLogo: "شعار Vite",       reactLogo: "شعار React",       title: "Vite + React",       countButton: "العدد هو",       editMessage: "عدّل",       hmrMessage: "واحفظ لاختبار HMR",       readTheDocs: "انقر على شعارات Vite و React لمعرفة المزيد",     },   } }}
    src/App.tsx
    نسخ الكود

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

    import { useState, type FC } from "react";import reactLogo from "./assets/react.svg";import viteLogo from "/vite.svg";import "./App.css";import { IntlayerProvider, useIntlayer } from "react-intlayer";const AppContent: FC = () => { const [count, setCount] = useState(0); const content = useIntlayer("app-content"); return (   <>     <div>       <a href="https://vitejs.dev" target="_blank">         <img src={viteLogo} className="logo" alt={content.viteLogo.value} />       </a>       <a href="https://react.dev" target="_blank">         <img           src={reactLogo}           className="logo react"           alt={content.reactLogo.value}         />       </a>     </div>     <h1>{content.title}</h1>     <div className="card">       <button onClick={() => setCount((count) => count + 1)}>         {content.countButton} {count}       </button>       <p>         {content.editMessage} <code>src/App.tsx</code> {content.hmrMessage}       </p>     </div>     <p className="read-the-docs">{content.readTheDocs}</p>   </> );};const App: FC = () => ( <IntlayerProvider>   <AppContent /> </IntlayerProvider>);export default App;
    • يُستخدم IntlayerProvider لتوفير اللغة للمكونات المتداخلة.

    (اختياري) الخطوة 6: تغيير لغة المحتوى الخاص بك

    لتغيير لغة المحتوى الخاص بك، يمكنك استخدام وظيفة setLocale التي يوفرها خطاف useLocale. تسمح لك هذه الوظيفة بضبط لغة التطبيق وتحديث المحتوى وفقًا لذلك.

    src/components/LocaleSwitcher.tsx
    نسخ الكود

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

    import type { FC } from "react";import { Locales } from "intlayer";import { useLocale } from "react-intlayer";const LocaleSwitcher: FC = () => {  const { setLocale } = useLocale();  return (    <button onClick={() => setLocale(Locales.ARABIC)}>      تغيير اللغة إلى العربية    </button>  );};
    لمعرفة المزيد حول خطاف useLocale ، راجع الوثائق.

    (اختياري) المرحلة 7: ملء الترجمات المفقودة

    يوفر Intlayer أداة CLI لمساعدتك في ملء الترجمات المفقودة. يمكنك استخدام الأمر intlayer لاختبار وملء الترجمات المفقودة من التعليمات البرمجية الخاصة بك.

    bash
    نسخ الكود

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

    npx intlayer test         # اختبار ما إذا كانت هناك ترجمات مفقودة
    bash
    نسخ الكود

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

    npx intlayer fill         # ملء الترجمات المفقودة
    لمزيد من التفاصيل، راجع وثائق CLI

    (اختياري) خريطة الموقع و robots.txt (توليد وقت البناء)

    يوفّر Intlayer الدالتين generateSitemap وgetMultilingualUrls لتنسيق مخرجات جاهزة للزحّافات (sitemap.xml متعدد اللغات وrobots.txt) وكتابتها تلقائياً إلى public/. عادةً تشغّل سكربت Node صغير قبل Vite (مثلاً خطافات npm predev / prebuild).

    خريطة الموقع

    يولّد مولّد خرائط المواقع إعدادات اللغات ويضيف البيانات الوصفية المناسبة.

    تدعم الخريطة مساحة الاسم xhtml:link (hreflang). بدلاً من قائمة عناوين مسطحة، يربط Intlayer بين جميع النسخ اللغوية لكل صفحة في الاتجاهين (مثل /about و/fr/about أو /about?lang=fr وفقًا لوضع التوجيه).

    Robots.txt

    استخدم getMultilingualUrls لتشمل قواعد Disallow كل المتغيرات المحلية للمسارات الحساسة.

    1. أضف generate-seo.mjs في جذر المشروع

    generate-seo.mjs
    نسخ الكود

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

    import fs from "fs";import path from "path";import { fileURLToPath } from "url";import { generateSitemap, getMultilingualUrls } from "intlayer";const __dirname = path.dirname(fileURLToPath(import.meta.url));const SITE_URL = (process.env.SITE_URL || "http://localhost:5173").replace(  /\/$/,  "");const pathList = [  { path: "/", changefreq: "daily", priority: 1.0 },  { path: "/about", changefreq: "monthly", priority: 0.7 },];const sitemapXml = generateSitemap(pathList, { siteUrl: SITE_URL });fs.writeFileSync(path.join(__dirname, "public", "sitemap.xml"), sitemapXml);const getAllMultilingualUrls = (urls) =>  urls.flatMap((url) => Object.values(getMultilingualUrls(url)));const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);const robotsTxt = [  "User-agent: *",  "Allow: /",  ...disallowedPaths.map((path) => `Disallow: ${path}`),  "",  `Sitemap: ${SITE_URL}/sitemap.xml`,].join("\n");fs.writeFileSync(path.join(__dirname, "public", "robots.txt"), robotsTxt);console.log("SEO files generated successfully.");

    يجب تثبيت حزمة intlayer. عيّن SITE_URL في بيئة الإنتاج (مثلاً في CI).

    يُفضّل generate-seo.mjs لـ ESM في Node. إن استخدمت generate-seo.js ففعّل "type": "module" في package.json أو ESM بطريقة أخرى.

    2. شغّل السكربت قبل Vite

    package.json
    نسخ الكود

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

    {  "scripts": {    "dev": "vite",    "prebuild": "node generate-seo.mjs",    "build": "vite build",    "preview": "vite preview"  }}

    عدّل الأوامر إن كنت تستخدم pnpm أو yarn. يمكن استدعاء السكربت من CI أيضاً.

    تكوين Git

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

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

    .gitignore
    نسخ الكود

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

    # تجاهل الملفات التي تم إنشاؤها بواسطة Intlayer.intlayer

    إضافة VS Code

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

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

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

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

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

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

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

    React Router v7 (fs-routes)
    Vite و Vue
    Alt+→

    في هذه الصفحة

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

      npm install intlayer react-intlayernpm install vite-intlayer --save-devnpx intlayer init
      import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH, Locales.ARABIC],    defaultLocale: Locales.ENGLISH,  },  compiler: {    /**     * يشير إلى ما إذا كان يجب تمكين المجمّع.     */    enabled: true,    /**     * دليل الإخراج للقواميس المحسنة.     */    output: ({ locale, key }) => `compiler/${locale}/${key}.json`,    /**     * أدخل المحتوى فقط في الملف الذي تم إنشاؤه، بدون مفتاح.     */    noMetadata: false,    /**     * بادئة مفتاح القاموس     */    dictionaryKeyPrefix: "", // Remove base prefix    /**     * يشير إلى ما إذا كان يجب حفظ المكونات بعد تحويلها.     * بهذه الطريقة، يمكن تشغيل المجمّع مرة واحدة فقط لتحويل التطبيق، ثم يمكن إزالته.     */    saveComponents: false,  },  ai: {    provider: "openai",    model: "gpt-5-mini",    apiKey: process.env.OPEN_AI_API_KEY,    applicationContext: "هذا التطبيق هو تطبيق خرائط", // ملاحظة: يمكنك تخصيص وصف التطبيق هذا  },};export default config;
      import { defineConfig } from "vite";import react from "@vitejs/plugin-react-swc";import { intlayer, intlayerCompiler } from "vite-intlayer";// https://vitejs.dev/config/export default defineConfig({  plugins: [react(), intlayer(), intlayerCompiler()],});
      import { useState, type FC } from "react";import reactLogo from "./assets/react.svg";import viteLogo from "/vite.svg";import "./App.css";import { IntlayerProvider } from "react-intlayer";const AppContent: FC = () => { const [count, setCount] = useState(0); return (   <>     <div>       <a href="https://vitejs.dev" target="_blank">         <img src={viteLogo} className="logo" alt="Vite logo" />       </a>       <a href="https://react.dev" target="_blank">         <img src={reactLogo} className="logo react" alt="React logo" />       </a>     </div>     <h1>Vite + React</h1>     <div className="card">       <button onClick={() => setCount((count) => count + 1)}>         count is {count}       </button>       <p>         Edit <code>src/App.tsx</code> and save to test HMR       </p>     </div>     <p className="read-the-docs">       Click on the Vite and React logos to learn more     </p>   </> );};const App: FC = () => ( <IntlayerProvider>   <AppContent /> </IntlayerProvider>);export default App;
      { key: "app-content", content: {   nodeType: "translation",   translation: {     en: {       viteLogo: "Vite logo",       reactLogo: "React logo",       title: "Vite + React",       countButton: "count is",       editMessage: "Edit",       hmrMessage: "and save to test HMR",       readTheDocs: "Click on the Vite and React logos to learn more",     },     ar: {       viteLogo: "شعار Vite",       reactLogo: "شعار React",       title: "Vite + React",       countButton: "العدد هو",       editMessage: "عدّل",       hmrMessage: "واحفظ لاختبار HMR",       readTheDocs: "انقر على شعارات Vite و React لمعرفة المزيد",     },   } }}
      import { useState, type FC } from "react";import reactLogo from "./assets/react.svg";import viteLogo from "/vite.svg";import "./App.css";import { IntlayerProvider, useIntlayer } from "react-intlayer";const AppContent: FC = () => { const [count, setCount] = useState(0); const content = useIntlayer("app-content"); return (   <>     <div>       <a href="https://vitejs.dev" target="_blank">         <img src={viteLogo} className="logo" alt={content.viteLogo.value} />       </a>       <a href="https://react.dev" target="_blank">         <img           src={reactLogo}           className="logo react"           alt={content.reactLogo.value}         />       </a>     </div>     <h1>{content.title}</h1>     <div className="card">       <button onClick={() => setCount((count) => count + 1)}>         {content.countButton} {count}       </button>       <p>         {content.editMessage} <code>src/App.tsx</code> {content.hmrMessage}       </p>     </div>     <p className="read-the-docs">{content.readTheDocs}</p>   </> );};const App: FC = () => ( <IntlayerProvider>   <AppContent /> </IntlayerProvider>);export default App;
      import type { FC } from "react";import { Locales } from "intlayer";import { useLocale } from "react-intlayer";const LocaleSwitcher: FC = () => {  const { setLocale } = useLocale();  return (    <button onClick={() => setLocale(Locales.ARABIC)}>      تغيير اللغة إلى العربية    </button>  );};
      npx intlayer test         # اختبار ما إذا كانت هناك ترجمات مفقودة
      npx intlayer fill         # ملء الترجمات المفقودة
      import fs from "fs";import path from "path";import { fileURLToPath } from "url";import { generateSitemap, getMultilingualUrls } from "intlayer";const __dirname = path.dirname(fileURLToPath(import.meta.url));const SITE_URL = (process.env.SITE_URL || "http://localhost:5173").replace(  /\/$/,  "");const pathList = [  { path: "/", changefreq: "daily", priority: 1.0 },  { path: "/about", changefreq: "monthly", priority: 0.7 },];const sitemapXml = generateSitemap(pathList, { siteUrl: SITE_URL });fs.writeFileSync(path.join(__dirname, "public", "sitemap.xml"), sitemapXml);const getAllMultilingualUrls = (urls) =>  urls.flatMap((url) => Object.values(getMultilingualUrls(url)));const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);const robotsTxt = [  "User-agent: *",  "Allow: /",  ...disallowedPaths.map((path) => `Disallow: ${path}`),  "",  `Sitemap: ${SITE_URL}/sitemap.xml`,].join("\n");fs.writeFileSync(path.join(__dirname, "public", "robots.txt"), robotsTxt);console.log("SEO files generated successfully.");
      {  "scripts": {    "dev": "vite",    "prebuild": "node generate-seo.mjs",    "build": "vite build",    "preview": "vite preview"  }}
      # تجاهل الملفات التي تم إنشاؤها بواسطة Intlayer.intlayer