localize.dev

توثيق

يقوم localize.dev بتحويل النصوص المكتوبة مباشرة إلى استدعاءات ترجمة في قواعد أكواد React و Next.js و React Native و Vue و Nuxt و Svelte و Angular و Astro و Solid و Qwik و Lit و Ember و Flutter و Rails و Django و Laravel و Android و iOS و HTML الثابتة، ويكتب قواميس اللغات، ويقوم بإعداد مكتبة i18n إذا لم تكن موجودة، ويمكنه فتح طلب السحب لك. تتم الترجمة على نموذج localize.dev المستضاف، لذلك لا يوجد شيء لإعداده بخلاف مفتاح API.

البدء السريع

تحتاج إلى Node.js 22 أو أحدث. لا يحتاج تطبيقك إلى مكتبة i18n بعد؛ التشغيل الأول يقوم بإعداد واحدة. قم بإنشاء مفتاح API مجاني في لوحة التحكم، ثم اختر إطار العمل الخاص بك:

React

أي واجهة مستخدم تُعرض عبر مكون يمكن أن يدعو إلى useTranslation(): React مع Vite، Remix أو Gatsby، ومُعالجات Electron و Tauri، بالإضافة إلى أنظمة التصميم أو حزم واجهة مستخدم مشتركة. تُصبح مكونات الفئة t من خلال withTranslation(), أو <Translation> عندما لا تكون تصدير الملف الافتراضي. تظل الجمل حول الروابط كاملة مع <Trans> (رابط خاص به title شاملًا)، يتم العثور على النسخ في الثوابت، الإشعارات، رسائل zod، وتتبع التواريخ والأرقام والسعرات حسب لغة التطبيق.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

دليل React: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Next.js

مكونات خادم App Router تحصل على const { t } = await getTranslation() ومكونات العميل useTranslation()، كلاهما باللغة التي اختارها الخادم؛ يعمل Pages Router مثل React. تم إنشاؤه proxy.ts يمنح كل صفحة عنوان URL لكل لغة مع hreflang روابط.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

دليل Next.js: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

React Native and Expo

React Native و Expo. accessibilityLabel و accessibilityHint تتم ترجمتها أيضًا، ويتجنب إعداد i18n واجهات برمجة التطبيقات الخاصة بالمتصفح فقط.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

دليل React Native and Expo: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Vue

نص و {{ }} في <template> تصبح {{ $t('key') }} وتصبح السمات :placeholder="$t('key')"، مع إعداد vue-i18n في src/i18n.ts وتم تثبيته في main.ts. الرسائل المعروضة من <script setup> (alert, التنبيهات، document.title) استخدام t() من useI18n, و n === 1 ? … : … يصبح جمع vue-i18n. يتم ترك الإعداد الحالي كما هو. createI18n يُترك الإعداد كما هو. تظل الجملة حول رابط أو نص غامق رسالة واحدة عبر <i18n-t>, مع العناصر كفتحات. الثوابت في <script setup> معروض بواسطة القالب ({{ title }}, v-for="tab in tabs") تصبح مفاتيح تُقرأ من خلال $t(). قوالب مكتوبة بلغة Pug (<template lang="pug">) احصل على نفس الشيء: h1 {{ $t('key') }}، والنص المبوب والمضمن، و input(:placeholder="$t('key')").

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

دليل Vue: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Nuxt

تُعيد كتابة الصفحات والأكواد مثل أي مكون Vue، و @nuxtjs/i18n تُضاف إلى nuxt.config, مع عنوان URL لكل لغة (/es/about) و hreflang روابط من useLocaleHead().

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

دليل Nuxt: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Svelte and SvelteKit

الرمز يصبح {$_('key')} مع svelte-i18n، مبني من src/lib/i18n و مستورد في +layout (أو main.ts بدون SvelteKit). خصائص مثل title="Hello {name}" يصبح رسالة واحدة. في SvelteKit، يتم توليد hooks.server يظهر كل صفحة بلغة الزائر (اختياره المخزن، ثم Accept-Language) وبالتالي لا يوجد عرض سريع للغة الأصلية.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

دليل Svelte and SvelteKit: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Angular

القالب (.html والمضمنة template:) تصبح {{ 'key' | translate }} مع ngx-translate، السمات [placeholder]="'key' | translate" ([attr.aria-label] للـ aria)، والسلاسل النصية في الربط ('key' | translate). تدفق التحكم (@if, @for), *ngIf والقوالب المضمنة مفهومة؛ العناصر المميزة بـ Angular الخاصة i18n تُترك له. الإعداد يضيف provideI18n() إلى app.config.ts (كل لغة مجمعة، لا يوجد محمل HTTP) و TranslatePipe لكل مكون مستقل يحتاجه.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

دليل Angular: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Astro

نص و {expressions} في .astro الملفات تصبح {t('key')}, السمات title={t('key')}, مع t من تم إنشاؤه src/i18n وحدة تقرأ اللغة من عنوان URL. تحصل كل صفحة ثابتة على نسخة لكل لغة (src/pages/es/about.astro)، لذا فإن كل لغة هي صفحة حقيقية قابلة للفهرسة، وتعيّن التخطيطات <html lang dir>. localizePath(path, lang) يبني روابط بين اللغات. جزر React و Vue و Svelte (من @astrojs/react, /vue, /svelte) يتم توطينها في نفس التشغيل، ولكل منها مكتبتها الخاصة المعدة واتباع لغة الصفحة.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

دليل Astro: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Solid

JSX مثل React، مع useTranslation() من تم إنشاؤه src/i18n.ts: i18next خلف إشارة لغة، لذا يتم تحديث النص في مكانه عند تغيير اللغة. تظل الجمل حول الروابط رسالة واحدة، يتم عرضها بواسطة rich(t('key'), { a: (c) => <a href="/terms">{c}</a> }) من نفس الوحدة.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

دليل Solid: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Qwik

JSX في component$ يحصل على const { t } = useTranslation() من تم إنشاؤه src/i18n.ts الذي يقرأ اللغة من عنوان URL (Qwik City's useLocation)، وكل مسار، ديناميكيًا أيضًا، يحصل على نسخة لكل لغة تحت src/routes/es/. تظل الجمل حول الروابط رسالة واحدة من خلال rich() من نفس الوحدة.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

دليل Qwik: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Lit

نص و ${expressions} في html`…` تصبح القوالب ${t('key')}, السمات placeholder=${t('key')}. تحصل المكونات على I18nController حتى يعاد عرضها عندما setLanguage() يغير اللغة؛ تظل القوالب المتداخلة والأنماط والتعليقات كما هي.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

دليل Lit: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Ember

شبكات جليمر (.hbs, و <template> في .gjs/.gts) تصبح {{t "key" name=this.name}} مع ember-intl، الخصائص placeholder={{t "key"}}, النصوص في {{if}} (t "key"), و {{if (eq n 1) "item" "items"}} في جملة عدد مفرد. الرسائل تذهب إلى translations/<locale>.json؛ يختار مسار التطبيق المولّد اللغة.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

دليل Ember: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Flutter

Text('Hi $name') والوسائط مثل hintText: تصبح AppLocalizations.of(context)!.hiName(name)، مع الرسائل في lib/l10n/app_en.arb (مفاتيح camelCase، وصيغ الجمع ICU، وبيانات التعريف للنائب). const يتم إسقاطه من الأدوات التي تحتوي الآن على بحث؛ السلاسل النصية بدون BuildContext ضمن النطاق يتم الإبلاغ عنها. يضيف الإعداد flutter_localizations, generate: true, l10n.yaml، الـ MaterialApp المفوضين وقائمة لغات iOS.

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

لا package.json مطلوب: npx يشغل واجهة سطر الأوامر. دليل Flutter: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Static HTML

النص يبقى في الصفحة ويحصل على data-i18n="key" علامة (تتلقى الخصائص data-i18n-placeholder و مشابه. يتم توليد i18n.js يحمّل ملفات اللغة ويبدّل النص؛ أضف <select data-i18n-switcher></select> للواجهة القائمة بلغات. جملة تحتوي على عناصر داخلية (<strong>، الروابط) هي رسالة واحدة، تُعيد بناءها من عناصر الصفحة الخاصة بها. تُدمج الترجمات أيضًا في i18n.js، لذلك تعمل الصفحات المفتوحة من القرص أيضًا. النص من محرك الشبكة ({{ }}, {% %}، PHP) يُترك كما هو.

ت vجينات البحث تراها فقط النص في الصفحة، لذا قم بتحديد "htmlPages": true و "siteUrl" في localize.config.json لإضافة كتابة كل صفحة مترجمة إلى كل لغة (es/index.html)، مرتبطة بـ hreflang.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

دليل Static HTML: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Ruby on Rails

النص في مشاهد ERB يصبح <%= t('key', name: @user.name) %>, مع %{name} المتغيرات النائبة في config/locales/<locale>.yml والمجموعات العددية المستدعاة مع count:. available_locales وواحد switch_locale يتم إضافة حول-الإجراء.

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

لا package.json مطلوب: npx يشغل واجهة سطر الأوامر. دليل Ruby on Rails: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Django

تُحصل القوالب على {% translate '…' %} و {% blocktranslate %}, تذهب الترجمات إلى locale/<lang>/LC_MESSAGES/django.po, والإعدادات تحصل LANGUAGES, LOCALE_PATHS و LocaleMiddleware.

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

لا package.json مطلوب: npx يشغل واجهة سطر الأوامر. دليل Django: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Laravel

النص بلدي becomes {{ __('Hi :name', ['name' => $user->name]) }} مع lang/<locale>.json مُحدد بواسطة النص، ثم SetLocale الوسيط يختار اللغة (?locale=، ثم lang كوكيز، ثم Accept-Language).

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

لا package.json مطلوب: npx يشغل واجهة سطر الأوامر. دليل Laravel: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

Android

android:text, hint و contentDescription في تصميمات وأقواس تصبح @string/…، ثم Compose Text("Hi $name") داخل @Composable الوظائف تصبح stringResource(R.string.…, name). انظر الكود في Kotlin أو Java (label.setText("Hi"), label.text = "Hi") يصبح setText(R.string.…). النصوص تذهب إلى res/values-<lang>/strings.xml مع المرقمات %1$s محليات، و locales_config.xml قائمة اللغات المتوفرة لـ أندرويد 13+

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

لا package.json مطلوب: npx يشغل واجهة سطر الأوامر. دليل Android: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

iOS

نص SwiftUI (Text("Hi \(name)"), Button, .navigationTitle) يبقى كما هو، لأن SwiftUI يبحث عنه في قائمة النصوص الخاصة به؛ نص UIKit (label.text = "Hi") تصبح String(localized: "Hi"). كل شيء يذهب إلى Localizable.xcstrings مع كل اللغات في ملف واحد. أضف قائمة النصوص إلى هدف تطبيقك في Xcode مرة واحدة.

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

لا package.json مطلوب: npx يشغل واجهة سطر الأوامر. دليل iOS: ما الذي يتغير، مع مقارنة حقيقية قبل وبعد.

هل تريد إلقاء نظرة قبل التسجيل؟ npx localize-dev scan يسرد كل سلسلة سيتم استخراجها، و --offline يقوم بإنشاء مفاتيح دون ترجمة. لا يحتاج أي منهما إلى مفتاح أو يستخدم حصتك. يقوم تشغيل لاحق عبر الإنترنت بملء الترجمات المفقودة دون المساس بالمفاتيح الموجودة.

قواعد الأكواد المدعومة

يحصل كل إطار على الماسح الضوئي الخاص به ومكتبة i18n. ما يتغير في كل منها يكون تحت اسمه في البدء السريع، وفي دليله.

Monorepos: قم بالتشغيل من الجذر باستخدام --workspaces (أو الإجراء الخاص بـ workspaces: true) لتوطين كل تطبيق، ولكل منها ملفات اللغة الخاصة بها. مكتبات المكونات المشتركة (حزم بدون dev أو start البرنامج النصي) تُترجم أيضًا، بلغات التطبيقات التي تعتمد عليها، وتُضاف رسائلها إلى ملفات اللغة الخاصة بتلك التطبيقات، لذا فإن رسائل المكتبة t() تُحل الاستدعاءات من خلال إعداد كل تطبيق. لتوطين تطبيق واحد فقط، قم بتمرير الإجراء working_directory: apps/web بدلاً من ذلك: يقرأ التطبيق الخاص بـ localize.config.jsonوالملفات البرمجية وملفات اللغة، ويقوم طلب السحب بتغييرها في مكانها.

يتم اكتشاف الإطار من package.json (أو pubspec.yaml، أو الملفات عندما لا يكون هناك أي منهما)؛ قم بتعيين "framework" في localize.config.json لتجاوزها. تستخدم قواميس React عناصر نائبة i18next أو ICU؛ تستخدم Vue و Svelte و HTML نمط ICU {name}.

ملفات اللغة الحالية

هل لديك بالفعل إعداد i18n، في أي مكدس؟ localize-dev translate يتخطى الكود ويملأ ما هو مفقود في ملفات اللغة الخاصة بك: مفاتيح بدون ترجمة حتى الآن، بكل لغة لديك بالفعل، أو بلغات جديدة تسميها. لا يتم تغيير الترجمات الموجودة أبدًا، ولا يتم اكتشاف أي إطار عمل، لذا فهو يعمل مع أي مكدس، بما في ذلك iOS و Android الأصليان، و Rails و Django.

# Fill in what's missing in the languages already there
npx localize-dev translate --dry-run
npx localize-dev translate

# Add languages (creates the files)
npx localize-dev translate -l de,ja,pt-BR

# Or as a pull request
npx localize-dev pr --translate
التنسيقالملفاتملاحظات
JSONlocales/en.json, public/locales/en/*.jsoni18next (مع الجمع المفرد/الجمع)، ICU (react-intl، next-intl، بما في ذلك المطابقات =0 والاختيار)، vue-i18n، ngx-translate، Transloco
YAMLconfig/locales/en.yml, devise.en.ymlRails، تحت مفتاح اللغة؛ خريطة الجمع المفرد/الجمع
gettextlocale/fr/LC_MESSAGES/django.poDjango، WordPress، PHP، Python. يتم ملء الإدخالات الفارغة والمبهمة؛ تتبع أماكن الجمع نمط Plural-Forms. يتم إنشاء لغات جديدة بجانب لغة موجودة، مع نمطها الخاص للجمع.
Flutterlib/l10n/app_en.arbرسائل ICU؛ تصبح أوصاف @key سياقًا. يلتقط gen-l10n الملفات الجديدة.
Androidres/values/strings.xml<string> و <plurals>؛ غير قابل للترجمة، مع احترام <xliff:g> والتهرب. يكتب القيم في values-es/، values-pt-rBR/.
AppleLocalizable.xcstrings, en.lproj/*.stringsكتالوجات السلاسل النصية تضع كل لغة في مكانها، بما في ذلك الجمع؛ ملفات .strings تحصل على مجلدات .lproj جديدة (أضف اللغات في Xcode).
ملحقات المتصفح_locales/en/messages.jsonتُنسخ العناصر النائبة إلى كل لغة.

العناصر النائبة في بناء جملة كل تنسيق الخاص بها ({{name}}, %{name}, %1$s, %@, %(name)s, $NAME$) محمية: الترجمة التي تفقد واحدة أو تضيفها، أو تعيد ترتيب غير المسماة مثل %s، يتم إسقاطها والإبلاغ عنها. تحصل الصيغ الجمع على كل شكل تحتاجه اللغة المستهدفة (الروسية تحصل على one, few و many). تذهب التعليقات والأوصاف الموجودة في الملفات إلى النموذج كسياق.

النسخة المعدلة: localize.lock.json تحتفظ ببصمة لكل رسالة مصدر عند ترجمتها. قم بتغيير اللغة الإنجليزية والملف التالي run, translate أو تشغيل الإجراء يترجمها مرة أخرى بكل لغة؛ check يفشل في الترجمات التي تم تركها قديمة. قم بتثبيت الملف.

في GitHub Action، قم بتعيين mode: translate. كل تشغيل يفتح أو يحدث طلب سحب بما هو مفقود، لذا تتم ترجمة المفاتيح الجديدة المضافة باللغة الإنجليزية فور وصولها.

Crowdin، Phrase، Lokalise، Transifex

هل تعمل مع مترجمين في نظام إدارة الترجمة (TMS)؟ قم بدفع ملفات اللغة المصدر الخاصة بك إلى هناك واسحب ترجماتهم مرة أخرى. أضف المشروع إلى localize.config.json (provider: crowdin, phrase, lokalise أو transifex) وضع رمز واجهة برمجة التطبيقات في CROWDIN_TOKEN, PHRASE_TOKEN, LOKALISE_TOKEN أو TRANSIFEX_TOKEN (لا تضعه أبدًا في ملف التكوين):

localize.config.json
{
  "tms": { "provider": "crowdin", "projectId": "123456" }
}
# Upload source files (and, the first time, your existing translations)
npx localize-dev sync push --translations

# Download translations into your locale files
npx localize-dev sync pull

JSON، YAML، ARB، Android، .strings ويتم مزامنة الملفات الإضافية. يحتفظ Crowdin بمجلداتك، ويحتفظ Phrase بكل ملف على حدة بعلامة، ويخزن Lokalise كل ملف تحت مساره مع اللغة كـ %LANG_ISO%، ويحصل Transifex على مورد لكل ملف (projectId مثل o:acme:p:web). تتم مطابقة اللغات مع رموز المشروع الخاصة (es → es-ES, pt-BR → pt_BR). بالنسبة لـ Crowdin Enterprise أو مركز بيانات Phrase في الولايات المتحدة، قم بتعيين "url" إلى عنوان واجهة برمجة التطبيقات الخاص به. يتم خدمة ملفات gettext و String Catalog بشكل أفضل بواسطة عمليات التكامل الخاصة بـ TMS. حلقة شائعة: قم بتشغيل localize-dev run أو translate للترجمات الآلية، ادفع، اسمح للمراجعين بالتحرير، اسحب.

أوامر سطر الأوامر

localize-dev init
يكتب ملف localize.config.json مع جميع الإعدادات الافتراضية موضحة.
localize-dev init --agent [--pre-commit]
يقوم بإعداد وكلاء الترميز لترجمة النص أثناء كتابته: خادم MCP لـ Claude Code و Cursor، وخطاف بعد التحرير لـ Claude Code، وتعليمات في AGENTS.md وقاعدة Cursor. --pre-commit يتحقق أيضًا من الملفات المرحلية قبل كل تثبيت. كيف يعمل.
localize-dev login [--api-key ldv_live_…]
يحفظ مفتاح API الخاص بك لهذه الآلة. بدون --api-key يطلب الإدخال، أو يقرأ المفتاح من stdin.
localize-dev whoami
يعرض مساحة العمل، والخطة، والاستخدام للمفتاح الحالي.
localize-dev logout
يحذف المفتاح المحفوظ من هذه الآلة.
localize-dev scan [-d src] [-o extracted_strings.json]
يعرض جميع السلاسل التي سيتم استخراجها، بالإضافة إلى تلك التي تم تخطيها والأسباب. لا يغير شيئًا؛ لا حاجة لمفتاح.
localize-dev run [--dry-run] [--offline] [--workspaces] [--files a.tsx… | --changed | --staged] [-l es,fr] [-d src] [--api-key …]
العملية الكاملة: الاستخراج، تسمية المفاتيح، الترجمة، إعادة كتابة الملفات، تحديث القواميس، و إعداد مكتبة التدويل (i18n) إذا لم يكن لدى التطبيق أي منها. مع --workspaces، كل تطبيق على حدة في مستودع أحادي.
localize-dev translate [--dry-run] [-l de,ja] [-s en] [--api-key …]
يملأ الترجمات المفقودة في ملفات اللغة الحالية، لأي تقنية. لا يتم تعديل الكود. التنسيقات.
localize-dev check [--only strings|translations] [--files a.tsx… | --changed | --staged] [--json]
يفشل اختبار التكامل المستمر عند وجود نص ثابت، ترجمات مفقودة أو قديمة؛ يُبلغ عن المفاتيح غير المستخدمة، ومع اللغات من اليمين إلى اليسار، أنماط اليسار/اليمين. التفاصيل.
localize-dev prune [--dry-run]
يزيل المفاتيح التي لا يشير إليها الكود من ملفات اللغة لكل لغة.
localize-dev rtl [--fix]
قوائم الأنماط المثبتة على اليسار أو اليمين؛ --fix يبدل الأنماط الآمنة بالمنطقية. من اليمين إلى اليسار.
localize-dev content [--dry-run] [-l de,ja]
يترجم مستندات Markdown و MDX إلى نسخة لكل لغة. الوثائق والمحتوى.
localize-dev sync push|pull [--translations] [-l de,ja]
يدفع ملفات اللغة المصدر إلى Crowdin أو Phrase أو Lokalise أو Transifex، أو يسحب ترجماتها مرة أخرى. إعداد.
localize-dev seo <url> [--limit 500] [--json]
يتحقق مما تراه محركات البحث لكل لغة على موقع، مباشر أو بناء محلي: خريطة الموقع، روابط hreflang، <html lang>، العنوان الأساسي و og:locale. يخرج برمز 1 عند العثور على مشكلة، حتى يمكن تشغيله في CI بعد النشر التفاصيل.
localize-dev pr [--translate] [--base main] [--repo owner/name] [--branch name] [--token …]
يشغل العملية ويفتح (أو يحدث) طلب سحب على localize-dev/<base> بدلاً من الكتابة محليًا. يستخدم GITHUB_TOKEN عندما --token يُحذف. مع --translate, يملأ طلب السحب الترجمة المفقودة فقط.

وكلاء الترميز

localize-dev mcp يشغل خادم MCP، حتى يتمكن وكيل الترميز (Claude Code، Cursor، Codex، GitHub Copilot وغيرها) من التحقق من المستودع الذي يعمل فيه وترجمته. يتصل Lovable و Bolt و v0 والبناة الآخرون الذين يعملون في المتصفح بالخادم المستضاف على https://uselocalize.dev/api/mcp باستخدام مفتاح API. الإعداد لكل وكيل موجود على صفحة MCP. لجعل الوكيل يترجم النص أثناء كتابته، قم بتشغيل هذا في مجلد التطبيق:

npx localize-dev init --agent               # MCP server, Claude Code hook, AGENTS.md, Cursor rule
npx localize-dev init --agent --pre-commit  # also check staged files before each commit

يكتب هذه الملفات:

  • .mcp.json و .cursor/mcp.json: خادم MCP، لـ Claude Code و Cursor.
  • .claude/settings.json: خطاف بعد التحرير يقوم بتشغيل npx -y localize-dev hook. عندما يحتوي ملف يقوم Claude Code بتحريره على نص غير مترجم، يسرد الخطاف الأسطر ويستدعي الوكيل localize على هذا الملف قبل المتابعة.
  • AGENTS.md، و CLAUDE.md الذي يستورده عندما لا يكون موجودًا: متى يتم استدعاء localize و check. قاعدة Cursor في .cursor/rules/localize.mdc تقول الشيء نفسه لملفات واجهة المستخدم الخاصة بك.
  • مع --pre-commit: check --staged في خطاف ما قبل الالتزام الخاص بـ husky، أو خطاف git الخاص به.

في مستودع أحادي، تحدد التعليمات اسم التطبيق. يتم الاحتفاظ بالإعدادات والخوادم والنصوص الموجودة لديك، وتشغيل ثانٍ لا يغير شيئًا. قم بتثبيت الملفات حتى تشاركها أنت وفريقك وعملاؤهم. يقرأ الخطاف الملف فقط، بدون مفتاح أو نموذج، ويستغرق حوالي ثانية؛ LOCALIZE_DEV_HOOK=off يوقفه. تظهر السلاسل التي يترجمها الوكيل عبر خادم MCP باسم "أثناء الكتابة" في صفحة الاستخدام.

إعداد التدويل

تم إعداد Vue و Nuxt و Svelte و HTML ثابت كما هو موضح في قواعد الأكواد المدعومةفي React، تستدعي المكونات المعاد كتابتها useTranslation(), لذلك يحتاج التطبيق إلى تشغيل i18next. عندما لا يكون، يضيف التشغيل (وطلب السحب الخاص بالإجراء) ما هو مفقود:

  • i18next و react-i18next في package.json. كما يقوم الإجراء بتحديث ملف القفل الخاص بك (npm، pnpm، Yarn أو Bun)؛ بعد التشغيل المحلي، قم بتثبيت الحزم.
  • src/i18n.ts (أو .js), الذي يقوم بتحميل ملفات اللغة ويختار اللغة من اختيار محفوظ، ثم المتصفح، ثم اللغة المصدر الخاصة بك. مع أكثر من ثلاثة لغات مستهدفة، يتم تجميع اللغة المصدر فقط، والباقي يتم تحميله عند الاستخدام الأول ("lazyLocales" للاختيار). في تطبيقات Remix بدون v3_routeConfig، يتم ترطيب الصفحات في <html lang> وتغير بعد التحميل.
  • تفسير import './i18n' في ملفك الرئيسي: النص البرمجي في index.html، وإلا src/main.* أو src/index.*.
  • resolveJsonModule في tsconfig.json، بحيث يمكن استيراد ملفات اللغة.
  • إضافة استيراد لها في ملف إعدادات الاختبار (Vitest setupFiles, Jest setupFilesAfterEnv, src/setupTests)، لذلك ستجدها الاختبارات التي تبحث عن النص. يتم تثبيت vue-i18n تلقائيًا لـ Vue @vue/test-utils.
  • سطر في .gitattributes الذي يدمج ملفات اللغة مفتاحًا بعد مفتاح، بحيث لا تتعارض فروع مختلفة عند إضافة مفاتيح. قم بتشغيله مرة واحدة لكل نسخة باستخدام git config merge.localize-dev.driver "npx localize-dev merge-locales %O %A %B %P" (الدمج على GitHub نفسه لا ينفذه).
  • src/language-switcher.tsx, تصدير <LanguageSwitcher /> و useLanguage() مع إعدادات التطبيق هذه، بالإضافة إلى localize-dev كاعتماد. قم برسم مفتاح التبديل في المكان الذي يختار فيه المستخدمون اللغة، مثل رأس الصفحة؛ فهو لا يتم وضعه تلقائيًا لك. خيارات.

إذا كان أي ملف قد بدأ بالفعل في تشغيل i18next، فلن يتم إضافة أي شيء، وسيستخدم إعدادك كما هو. يحفظ المحول الاختيار في localStorage ويعيد استعادته في الزيارة التالية؛ لتغيير إلى كودك الخاص، ادع i18n.changeLanguage('es') واحفظ lang بالمثل. ستحصل المشاريع التي تم إعدادها بواسطة نسخة أقدم على المحول في تشغيلها التالي. في Next.js Pages Router، يتم وضع الاستيراد في pages/_app.

Next.js App Router

ملفات تحت app/ بدون 'use client' هي مكونات خادم، والتي لا يمكن أن تستخدم hooks. ستحصل على const { t } = await getTranslation() بدلاً من ذلك (يصبح المكون async إذا لم يكن كذلك)، من ملف مُولد i18n.server مодуل يختار اللغة من lang كوكيز، ثم متصفح Accept-Language. المكونات العميل تحافظ على useTranslation(). يتم تغليف تخطيط الجذر في <I18nProvider> الذي يوفر للمكونات العميل نفس اللغة، و <html lang> يتابعها. يقوم المحول المولّد بتحديد lang الكوكيز ويجددها، لذا يتم إعادة رسم المكونات الخادمة بلغة جديدة.

محول اللغة

<LanguageSwitcher /> هو قائمة بلANGUAGES التي يدعمها تطبيقك (لغتك الأصلية ولغات الهدف التي قمت بتكوينها)، لكل منها علمها واسمها الخاص. يعمل مع لوحة المفاتيح (السهم، Home/End، Enter، Escape، كتابة الاسم) ومقرئ الشاشة، ويذكر الاختيار، ويحدد <html lang> و dir لللغات من اليمين إلى اليسار.

Header.tsx
import { LanguageSwitcher, useLanguage } from './language-switcher';

<LanguageSwitcher />                                   // flag + native name
<LanguageSwitcher compact />                           // just the flag
<LanguageSwitcher nameStyle="native-english" />        // Español · Spanish
<LanguageSwitcher languages={['en', 'es']} />          // choose and order the list
<LanguageSwitcher regions={{ en: 'GB', pt: 'BR' }} />  // which country's flag
<LanguageSwitcher renderFlag={(l) => <img src={`/flags/${l.code}.svg`} alt="" />} />
<LanguageSwitcher unstyled className="…" buttonClassName="…" menuClassName="…" optionClassName="…" />

// Anywhere else: the current language and the list
const { language, info, languages, setLanguage, isRTL } = useLanguage();
info.flag        // "🇪🇸"
info.nativeName  // "Español"

خصائص أخرى: showFlag, align (start/end), side (top/bottom), label, disabled, renderButton, renderOption, persist (localStorage, cookie أو none), storageKey و onChange. يستقر الأسلوب المدمج على متغيرات CSS، لذلك يمكن إنشاء موضوع أو وضع مظلم في بضع خطوط: --ldv-bg, --ldv-fg, --ldv-border, --ldv-hover, --ldv-muted, --ldv-accent, --ldv-radius, --ldv-shadow. يتم نقل الخيارات المختارة والمحددة بالخط: data-selected و data-active لCSS الخاص بك. خارج React، getLanguageInfo('pt-BR') يرجع نفس الأسماء، العلم والإتجاه.

في Next.js App Router، يحفظ الملف المولّد الاختيار في lang الكوكيز وتجديد الصفحة، لذلك تتبع المكونات الخادمة. تظهر أعلام الإيموجي كحروفتين على ويندوز؛ استخدم renderFlag لصور هناك.

يتلقى كل إطار عمل آخر نفس القائمة، والتي يتم توليدها لمكوناته وحالتها الخاصة، على <localize-language-switcher> عنصر مخصص من localize-dev/switcher: يأخذ نفس خيارات السمات، ويصدر تغيير اللغة، ويتم تصميمه بنفس متغيرات --ldv-* أو ::part(button|menu|option|flag).

ما الذي تكتبه الإعدادات
Vue          src/language-switcher.ts           <LanguageSwitcher />, useLanguage()
Nuxt         components/LanguageSwitcher.ts     auto-imported, with composables/useLanguage.ts
Svelte       LanguageSwitcher.svelte            the $language store from language.ts
Solid, Qwik  src/language-switcher.tsx          <LanguageSwitcher />, useLanguage()
Angular      language-switcher.component.ts     <app-language-switcher />, languageOf(translate)
Astro        components/LanguageSwitcher.astro  useLanguage(Astro.url) from i18n/language.ts
Lit          src/language-switcher.ts           <app-language-switcher>, useLanguage()
Ember        components/language-switcher       <LanguageSwitcher />, the language service
React Native language-switcher.tsx              a native picker, useLanguage()
HTML         <localize-language-switcher>       from the CDN; i18n.js switches on language-change
Rails        shared/_language_switcher.html.erb render "shared/language_switcher", current_language
Django       language_switcher.html             {% include %}, {{ language }} in every template
Laravel      <x-language-switcher />            App\Support\Language::current()
Flutter      lib/language_switcher.dart         LanguageSwitcher(), language.of(context)
iOS          LanguageSwitcher.swift             LanguageSwitcher(), LanguageStore.shared, .appLanguage()
Android      LanguageSwitcher.kt                LanguageSwitcher(), showLanguagePicker(context)

مفتاح API

المفاتيح تشبه ldv_live_… وتنتمي إلى مساحة عمل؛ كل مفتاح في مساحة العمل يشارك حصته الشهرية. يبحث CLI عن مفتاح بهذا الترتيب:

  1. الـ --api-key علم
  2. الـ LOCALIZE_API_KEY متغير البيئة (استخدم هذا في CI)
  3. المفتاح المحفوظ بواسطة localize-dev login، في ~/.config/localize-dev/credentials.json (قابل للقراءة بواسطتك فقط)

يتم تخزين تجزئة (hash) لكل مفتاح فقط من جانبنا، لذا يتم عرض السر مرة واحدة عند إنشائه. قم بإلغاء مفتاح من لوحة التحكم وسيتوقف عن العمل فورًا.

الإعدادات

كل شيء اختياري. ضع التجاوزات في localize.config.json في جذر المشروع؛ تتفوق أعلام CLI على الملف.

حقلافتراضيوصف
srcDir"src"الدليل للمسح
frameworkdetectedReact و React Native و Vue و Svelte أو HTML. يتم اكتشافه من package.json، ثم من الملفات.
include / ignoreby framework / tests, stories, .d.tsأنماط عامة (Globs) نسبة إلى srcDir: *.{tsx,jsx}، *.vue، *.svelte أو *.html.
sourceLocale"en"لغة النسخة المكتوبة بالشيفرة الثابتة.
targetLocales["es", "fr"]اللغات المراد الترجمة إليها.
localesPath"locales/{locale}.json"موقع القاموس، على سبيل المثال public/locales/{locale}/common.json.
attributesplaceholder, alt, title, aria-label, label, tooltipالسمات التي تُعامل كنسخة واجهة المستخدم. يضيف React Native accessibilityLabel و accessibilityHint.
importSource"react-i18next"React: من أين يتم استيراد useTranslation، على سبيل المثال next-i18next.
interpolationby frameworkيكتب i18next {{name}} (React)؛ ويكتب icu {name} (Svelte، HTML)؛ ويكتب vue {name} مع الهروب من الأحرف الخاصة لـ vue-i18n.
htmlPagesfalseHTML ثابت: اكتب أيضًا كل صفحة مترجمة لكل لغة (es/index.html)، لمحركات البحث.
siteUrlnoneعنوان الموقع، على سبيل المثال https://example.com. مطلوب لروابط hreflang بين إصدارات اللغة.
localizeFormatstrueاجعل التواريخ والأرقام والأسعار ثابتة لواجهة لغة واحدة تتبع لغة التطبيق.
currency"USD"ماذا يعني الرمز $ بدون أي شيء قبله عند تحديد الأسعار المحلية، مثلاً "كندا".
lazyLocalesأكثر من 3 لغاتريأكت: حزم اللغة المصدر فقط وتحميل اللغات الأخرى عند الاستخدام الأول.
contentnoneمستندات ماركداون وMDX لمحتوى localize-dev: { "include": ["docs/**/*.md"], "output": "{dir}/{name}.{locale}{ext}" }.

إجراء GitHub

تقوم العملية بتنفيذ نفس الممر في CI وتفتح طلب سحب ضد الفرع الذي أطلقها. إعادة التشغيل تحدث نفس الفرع وطلب السحب. قبل التشغيل الأول، قم بتخزين مفتاح API الخاص بك في المستودع:

  1. 1

    نسخ مفتاح API الخاص بك

    يبدأ بـ ldv_live_ و يُظهر مرة واحدة فقط. فقدته؟ أنشئ واحدًا جديدًا على مفتاح API الصفحة.
  2. 2

    فتح أسرار إجراءات الموديل

    في جيت هاب، افتح مستودعك و اذهب إلى الإعدادات → السرات والمتغيرات → العمليات, ثم انقر سر جديد للمخزن. تحتاج إلى وصول إداري للمخزن لرؤية الإعدادات.
  3. 3

    إضافة السر

    الاسم: LOCALIZEDEV_API_KEYالسر: لصق مفتاحك دون فضاءات أو انقطاعات. ثم انقر على إضافة السر. يحفظ GitHub القيمة بعد ذلك؛ لتغييرها، تحديث السر.
  4. 4

    بدون تطبيق localize.dev ل GitHub: السماح للعملية بفتح طلبات التدمين

    في الإعدادات → العمليات → عام, تحت إذنات عملية العمل, اضغط على علامة التمرير أذن GitHub Actions لإنشاء وتأكيد طلبات التدمين واضغط حفظ. بدون ذلك، ستترجم العملية كل شيء ولكن ستفشل عند فتح طلب التدمين. إذا كان الخيار معتيمًا، يجب على صاحب المنظمة تمكينه أولاً في إعدادات المنظمة → إجراءات → عام.

ثم قم بارتكاب سير العمل:

.github/workflows/localize.yml
name: Localize

on:
  push:
    branches: [main]
  pull_request:
    types: [opened, synchronize]
  workflow_dispatch: # "Run workflow" button in the Actions tab

permissions:
  contents: write # push the localize-dev/<branch> branch
  pull-requests: write # open or update the localization PR

# One run per branch at a time; a newer push supersedes the running one.
concurrency:
  group: localize-${{ github.head_ref || github.ref_name }}
  cancel-in-progress: true

jobs:
  localize:
    runs-on: ubuntu-latest
    timeout-minutes: 60
    # Skip localize.dev's own branches, and fork PRs (their token is read-only).
    if: >-
      !startsWith(github.head_ref || github.ref_name, 'localize-dev/') &&
      (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
    steps:
      - name: Checkout
        uses: actions/checkout@v5
        with:
          # On PRs, scan the branch itself rather than the merge commit.
          ref: ${{ github.head_ref || github.ref_name }}

      - name: Localize
        uses: ufortstephen/autolocalize-action@v1
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          api_key: ${{ secrets.LOCALIZEDEV_API_KEY }}
          target_locales: 'es,fr,de'
          # src_dir: 'src' # default: your framework's (src, app/views, resources/views, lib…)
          # locales_path: 'public/locales/{locale}/common.json' # default: your framework's
          # working_directory: 'apps/web' # monorepo: localize just this app

مدخلات أخرى: src_dir, locales_path, base_branch, api_url, offline (لا حاجة لمفتاح), workspaces (كل تطبيق في مستودع متعدد التطبيقات)، working_directory (تطبيق واحد من مستودع متعدد التطبيقات)، tms_pull / tms_push (مع tms_token: أدخل الترجمات المراجعة إلى طلب الاندماج، Upload ملفات المصدر من فرع الافتراضي)، mode: translate (املأ فقط ملفات اللغة الموجودة) النتائج: pr_url, strings_count.

تقدم كل تشغيل تقريرًا عند الانتهاء: يدرج صفحة المشروع في لوحة التحكم في عمليات التشغيل الأخيرة مع طلب الاندماج الخاص بها،_strings تم استبدالها، الترجمات لكل لغة، والخطأ إذا فشل أحدها.

مشاهدة طلب الاندماج

هل تريد رؤيته على كودك الخاص قبل إعداد أي شيء؟ اتصل بالمستودع في لوحة التحكم واختر افتح طلب سحب متقدم على صفحة التطبيق. localize.dev يقرأ فرع الافتراضي، ويترجم حتى 200 سلسلة إلى لغة المشروع الأساسية على الخادم، ويفتح طلب سحب من localize-dev/preview. لا تحتاج إلى أي عملية عمل أو مفتاح API أو تسجيل دخول؛ يتم احتساب السلاسل ضمن خطةك، وتظهر الترجمات في علامة التبويب "مراجعة" مثل أي تشغيل آخر. إعادة تشغيله تحديث نفس طلب السحب.

في مخزن واحد، يتم ترجمة كل تطبيق على حدة حتى يتم استخدام 200 سلسلة. لا يتم تضمين ملفات Git LFS أو تحت المودول في أرشيف GitHub المقدم، لذلك يتم تجاهلها، وفي مخازن كبيرة جدًا يتم قراءة جزء منها فقط؛ يذكر طلب السحب ذلك. لا يوجد أي حد لعملية GitHub Action.

فحص CI

localize-dev check يفشل (كود الخروج 1) عندما تكون النسخ مدمجة مباشرة، أو عندما تكون لغة ما خالية من الترجمات، أو عندما تكون الترجمات قديمة بسبب تغيير اللغة الإنجليزية منذ (من localize.lock.json)، ويذكر كل منها. كما أنه يورد المفاتيح التي لا تستخدمها أي كود (قم بإزالتها باستخدام localize-dev prune)، نص في ملفات الأنماط (content: "New"رسائل تظهر قيمة مخزنة كما هي (Status: {{status}} يظهر "دفع")، وفي حال كانت اللغة المستهدفة من اليمين إلى اليسار، يتم تثبيت الأنماط على اليسار أو اليمين، و next/font الخطوط التي تفتقر إلى أحرف لغة مستهدفة لا تفشل في التحقق. المفتاح الذي يستخدمه الكود والذي يفتقر إليه ملف اللغة المصدر يفشل، حيث سيرى الأشخاص المفتاح نفسه. يقرأ الملفات فقط: لا مفتاح API، لا شيء يتم إرساله. في GitHub Actions، كل مشكلة هي أيضًا تعليق توضيحي على فرق طلب السحب.

npx localize-dev check                      # both
npx localize-dev check --only strings       # hardcoded copy only
npx localize-dev check --only translations  # missing translations only
npx localize-dev check --json
npx localize-dev check --staged             # files staged for the next commit (pre-commit hook)
npx localize-dev check --changed            # files changed since the last commit, and new ones

مع --files أو --changed أو --staged، ينظر الفحص فقط إلى تلك الملفات: النسخ المضمنة والمفاتيح المفقودة من ملف اللغة المصدر. يتخطى الفحوصات على مستوى المشروع، لذا يعمل في حوالي ثانية واحدة، وهو سريع بما يكفي لخطاف ما قبل الالتزام أو خطاف ما بعد التحرير للوكيل. يعمل الأمر run بنفس الخيارات.

أو في سير عمل يعمل على طلبات السحب، مع الإجراء:

.github/workflows/i18n-check.yml
on: pull_request
jobs:
  i18n:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: ufortstephen/autolocalize-action@v1
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          mode: check

الترجمة الزائفة

قبل الدفع مقابل ترجمة واحدة، انظر أين يتعطل تخطيطك. --pseudo يكتب en-XA لغة: كل رسالة مزخرفة، أطول بنسبة 35% تقريبًا (مثل الألمانية أو الفنلندية) وفي أقواس، مع الاحتفاظ بالمعلمات والعلامات بالضبط، بحيث يعمل التطبيق كما لو كان بترجمة حقيقية. قم بالتبديل إليها وابحث عن الأزرار المقتطعة، والبطاقات المتدفقة، وأي شيء بدون أقواس: هذه النسخة لا تزال مبرمجة بشكل ثابت.

npx localize-dev run --pseudo         # en-XA: [Šáṽé çĥáñĝéš one two]
npx localize-dev run --pseudo rtl     # ar-XB: right to left
npx localize-dev translate --pseudo   # from existing locale files, code untouched

لا يوجد نموذج ولا مفتاح: لا يستخدم حصتك. تظل لغاتك الحقيقية كما هي. الملعب يحتوي عليها أيضًا، كـ en-XA لغة.

التواريخ والأرقام والمال

في تطبيقات React و React Native و Electron و Tauri و Solid و Vue و Svelte، تعمل أيضًا على إعادة كتابة التواريخ والأرقام والأسعار التي تم ترميزها مسبقًا في لغة معينة، بحيث تتبع لغة التطبيق:

  • date.toLocaleDateString('en-US', …) و new Intl.NumberFormat('en-US') تأخذ لغة التطبيق بدلاً من ذلك (وكذلك المكالمات التي لا تحتوي على لغة، والتي تستخدم لغة المتصفح).
  • `$${price}` و <span>${price}</span> تصبح تنسيق عملة، لذا $1,234.50 يقرأ 1.234,50 $ باللغة الألمانية. €, £, ¥, ₹, ₦, CA$, A$ وترمز الرموز الأخرى إلى عملتها؛ مجرد $ هو دولار أمريكي ما لم "currency" في localize.config.json يقول خلاف ذلك.
  • في قوالب ونصوص Vue، تأتي اللغة من vue-i18n ($i18n.locale؛ في Svelte، من svelte-i18n $locale.

التواريخ من date-fns (format(d, 'MMM d, yyyy'))، dayjs و moment تصبح Intl.DateTimeFormat بنفس الأجزاء؛ الأوقات النسبية (formatDistance, fromNow) مدرجة لتتحول إليها Intl.RelativeTimeFormat. localeCompare والأحرف الكبيرة أو الصغيرة المعروضة في JSX تستخدم لغة التطبيق (الحرف التركي i). القوائم تتبع اللغة أيضًا: {tags.join(', ')} في JSX و `${xs.slice(0, -1).join(', ')} and ${xs[xs.length - 1]}` تصبح Intl.ListFormat، لذا تحصل اليابانية على 、 والإسبانية على "y" الخاصة بها. تدرج طلبات السحب كل تغيير. قم بإيقاف تشغيله باستخدام "localizeFormats": false في localize.config.json. تُركت تطبيقات Next.js App Router كما هي في الوقت الحالي، حيث تحصل مكوناتها العميل على اللغة من خلال موفر.

عنوان URL لكل لغة

تفهرس محركات البحث كل لغة عندما يكون لها عنوان URL خاص بها. في تطبيقات Next.js App Router، يتم إنشاء proxy.ts (middleware.ts قبل Next 16) يخدم /es/about مع الـ /about صفحة بالإسبانية، دون نقل ملفاتك، و <LanguageAlternates /> في التخطيط الجذر يضيف hreflang روابط بين الإصدارات. تظل عناوين URL غير المسبوقة تتبع الـ lang ملف تعريف الارتباط والمتصفح، وتنتقل قائمة اللغات بين عناوين URL المسبوقة.

تطبيقات Nuxt تحصل على @nuxtjs/i18nالخاص بـ prefix_except_default عناوين URL مع useLocaleHead() في app.vue؛ اضبط "siteUrl" للروابط المطلقة. تحصل المواقع الثابتة على نفس الشيء من htmlPages. يحتفظ التطبيق الذي لديه وكيل أو برنامج وسيط خاص به بهذا: يشرح التشغيل الرأسين ( x-localize-lang, x-localize-path ) لضبطهما هناك.

تتبع عناوين الأوصاف والصفحات أيضًا. Next.js export const metadata يصبح generateMetadata الذي يستخدم مترجم الطلب (قالب عنوان %s تم الاحتفاظ به)، و generateMetadata يحصل على t. في تطبيقات الصفحة الواحدة (Vite React، Vue، Svelte، Angular، Solid)، index.htmlالخاص بـ <title> ويتم ترجمة الوصف وتعيينه بواسطة الوحدة النمطية التي تم إنشاؤها عند تغيير اللغة؛ يحتفظ الملف بها كما هي مكتوبة للطلاء الأول.

بالنسبة لمحركات البحث، يحصل التخطيط الجذري أيضًا على عنوان معياري و og:locale لكل عنوان URL للغة، من الملف الذي تم إنشاؤه i18n-seo.ts. app/sitemap.ts يسرد كل صفحة بعنوان ثابت (لا توجد مسارات [slug]، أو مناطق تسجيل دخول، أو مجلدات خاصة) بكل لغة، مع بدائل hreflang. يشير robots.ts إليه. يتم كتابة كليهما فقط عندما لا يحتوي التطبيق على أي منهما، ويمكنك تعديلهما. قم بتعيين "siteUrl" حتى يكون لخريطة الموقع عناوين كاملة. عندما لا يتم تعيينه، يأتي العنوان من ملف CNAME أو الصفحة الرئيسية في package.json، وعلى Vercel أو Netlify أو Render أو Railway من العنوان الذي يمنحه المضيف للبناء.

تحصل تخطيطات Astro على مكون I18nHead في رأسها، مع نفس الروابط و og:locale. يخدم SvelteKit 2.3 والإصدارات الأحدث كل لغة على عنوانها الخاص من خلال خطاف إعادة توجيه في src/hooks.ts, لذلك لا تحتاج المسارات إلى مجلد [lang]، ويضيف hooks.server الروابط إلى كل صفحة. كلاهما يحصل على sitemap.xml مبني من مجلد الصفحات أو المسارات، لذلك يتم سرد الصفحات الجديدة دون تشغيل localize مرة أخرى، وملف robots.txt عندما لا يحتوي التطبيق على أي منهما.

تحصل تطبيقات Qwik City على مكون LanguageHead في root.tsx بنفس الروابط، ونفس مسارات sitemap و robots.

تطبيقات React Router (وضع الإطار) تحصل على كل مسار مرة أخرى تحت كل لغة، لذا فإن /es/about هي صفحة "حول" بالإسبانية. يمر ملف المسارات عبر مساراته عبر withLanguageRoutes من app/i18n-routes.ts, ويقوم الجذر بعرض كل صفحة بلغة عنوانها، مع نفس الروابط. تحتفظ الروابط التي لا تحتوي على لغة بلغة الصفحة، وتتم إضافة مسارات sitemap.xml و robots.txt عندما لا يحتوي التطبيق على أي منهما. مع أكثر من ثلاث لغات، يتم تحميل اللغات غير الموجودة في الحزمة في محمل المسار، لذلك يقوم الخادم بعرضها أيضًا.

تطبيقات Remix 2 تحصل على نفس الشيء عندما v3_routeConfig قيد التشغيل في vite.config والمسارات موجودة في app/routes.ts (تكوين مسار Remix). بدونه، يخبر التشغيل بما يجب تغييره.

تحصل المواقع الثابتة التي تحتوي على htmlPages و siteUrl أيضًا على ملف sitemap.xml يسرد كل صفحة بكل لغة، وملف robots.txt عندما لا يكون لديها أي منهما.

تتم مطابقة لغة الزائر بالضبط، حسب اللغة، أو بمتغير إقليمي يقدمه التطبيق: متصفح تم تعيينه على pt-PT يحصل على التطبيق pt-BR.

لمعرفة ما تراه محركات البحث، وجه localize-dev seo إلى الموقع. يعمل على أي موقع، تم إعداده بواسطة localize.dev أم لا.

npx localize-dev seo https://example.com     # the live site
npx localize-dev seo http://localhost:3000   # a local build, before you deploy

يقرأ robots.txt وخريطة الموقع، ثم يقوم بتحميل كل صفحة والصفحات التي تسميها روابط hreflang الخاصة بها. يبلغ عن الصفحات التي لا يتم تحميلها أو إعادة توجيهها، وروابط hreflang بدون العنوان الكامل أو بدون x-default، ولغة لا ترتبط صفحتها بالرجوع، و <html lang> أو og:locale لا يتطابق مع لغة الصفحة، ورابط أساسي يشير إلى مكان آخر. يتم تحميل العناوين على أصل آخر (siteUrl، عند التحقق من بناء محلي) من العنوان الذي تقدمه.

مراجعة الترجمات

الترجمات الآلية من تشغيلات GitHub Action وطلبات سحب CLI (pr, pr --translate) تظهر على المشروع مراجعة علامة التبويب، المصدر والترجمة جنبًا إلى جنب، قابلة للتصفية حسب اللغة. وافق عليها واحدة تلو الأخرى أو كلها مرة واحدة، أو قم بتحرير واحدة: يجب أن يحافظ التحرير على عناصر النائبة للمصدر، ويحل محل إدخال ذاكرة الترجمة في مساحة العمل، بحيث يستخدم كل تشغيل لاحق التصحيح. تظهر رسائل الجمع كل شكل تحتاجه اللغة (الروسية one, few, many...) ويتم تحريرها شكلاً بشكلاً.

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

تحتفظ كل ترجمة بسجل لـ ملاحظات للمراجع التالي، ويظهر من وافق عليه أو عدله ومتى. عندما يتكرر نفس التصحيح، تقترح علامة التبويب مصطلح في المسرد: كلمة مصدر يجب أن تُترجم دائمًا بطريقة معينة (checkout → pago)، أو اسم يصر المراجعون على إعادته ويجب أن يظل غير مترجم. بنقرة واحدة تضيفه إلى مسرد المشروع، والذي يتبعه كل تشغيل.

تعيين مُراجع لكل لغة من أعضاء مساحة العمل. عندما يجلب تشغيل ترجمات جديدة بلغتهم، يحصلون على بريد إلكتروني واحد للتشغيل مع رابط إلى علامة التبويب. كل صف يربط بملف المصدر الذي جاء منه على GitHub. يضع النموذج علامة على الترجمات التي ليست متأكدًا منها (كلمة غامضة، تعبير اصطلاحي، تخمين رسمي أو غير رسمي) مع سببه، وتفتح علامة التبويب على تلك الترجمات، تحت تحتاج إلى مراجعة; وافق على الباقي واتركهم لشخص آخر. في الكود يعرض الأسطر حول المكان الذي تم استخدامه فيه، ويقرأ من طلب السحب الخاص بالتشغيل، بحيث يمكن التحقق من النسخة في المكان الذي تظهر فيه.

مسرد المصطلحات

يحتوي كل مشروع على مسرد مصطلحات في صفحة لوحة التحكم الخاصة به: المصطلحات التي يجب عدم ترجمتها أبدًا (أسماء العلامات التجارية والمنتجات)، والترجمات المفضلة لمفرداتك، وملاحظة حول الأسلوب مثل "غير رسمي؛ استخدم du في الألمانية". ينطبق هذا على كل طلب من إجراء GitHub الخاص بالمشروع وتشغيلات سطر الأوامر. يتم رفض الترجمات التي تغير مصطلحًا لا يجب ترجمته؛ الترجمات المفضلة وملاحظة الأسلوب توجه النموذج.

الخطط والحدود

الخطةسلاسل نصية / شهراللغات
Free1,0003
Proغير محدود5
Teamغير محدودغير محدود

تُحتسب السلسلة مرة واحدة بغض النظر عن عدد اللغات التي تُترجم إليها. تعمل المخصصات في فترات مدتها 30 يومًا: من اليوم الذي تم فيه إنشاء مساحة العمل الخاصة بك، أو من تاريخ الفوترة الخاص بك في خطة مدفوعة. تعرض لوحة المعلومات متى يتم إعادة تعيينها. يحدد حد اللغة كل لغة تمت الترجمة إليها في آخر 30 يومًا، عبر مساحات العمل والمشاريع الخاصة بك. إذا تجاوز التشغيل الحد المسموح به أو حد اللغة، فإنه يتوقف قبل كتابة أي شيء، ويوضح السبب ويخرج بالرمز 2، بحيث يفشل التكامل المستمر بدلاً من الالتزام بترجمة جزئية.

اللغات

تترجم localize.dev إلى أي لغة يعرفها Unicode CLDR، وأكثر من 600 منها، مكتوبة كرمز BCP 47: لغة (es، ja، sw)، مع نص أو منطقة عندما يكون ذلك مهمًا (zh-Hant، sr-Latn، pt-BR، es-419). لا توجد قائمة للاختيار من بينها: قم بتعيين sourceLocale و targetLocales في localize.config.json، أو مرر --locales.

يتم رفض الرمز الذي لا يسمي لغة قبل ترجمة أي شيء، مع ما كان يُقصد به على الأرجح: jp → ja، cn → zh. يتم قبول كل رمز صالح، بما في ذلك الأسماء المستعارة مثل en-UK (تُقرأ كـ en-GB) ورموز الاستخدام الخاص. يقوم سطر الأوامر، وإجراء GitHub، ولوحة التحكم، وواجهة برمجة التطبيقات بالتحقق بنفس الطريقة.

  • يعتمد عدد اللغات التي يمكن للتشغيل الواحد ترجمتها على خطة اشتراكك. تُحتسب السلسلة مرة واحدة، بغض النظر عن عدد اللغات التي تُترجم إليها.
  • تكون الترجمات أقوى في اللغات شائعة الاستخدام. بالنسبة للغات التي تحتوي على نصوص أقل على الإنترنت، اطلب من متحدث أصلي مراجعة طلب السحب، وأضف مسردًا لمصطلحات منتجك الخاصة.
  • كل لغة تُكتب فيها الحروف من اليمين إلى اليسار (العربية، العبرية، الفارسية، الأردية، الكردية، البشتو، السريانية، نكو وغيرها) تحصل على dir="rtl" وفحوصات الأنماط لليمين واليسار. الرمز الذي يُعرّف خط اللغة يُحتسب أيضًا: pa-Arab.
  • تتبع صيغ الجمع كل لغة بأشكالها الخاصة (واحد، قليل، كثير...) من CLDR، لذا تحصل البولندية والعربية والويلزية على كل صيغة يحتاجونها.
  • اللغات الزائفة en-XA (بلكنة وأطول) و ar-XB (من اليمين إلى اليسار) لا تحتاج إلى نموذج أو مفتاح.

صيغ الجمع والنصوص المنسقة

اختيار يعتمد على الكمية مثل {n} {n === 1 ? 'file' : 'files'} left يصبح رسالة واحدة (أيضًا n > 1 ? …, rules.select(n) === 'one' ? … ومساعدات مثل plural(n, 'file', 'files'))، يُعاد كتابتها إلى t('files.left', { count: n }). تحصل كل لغة على الأشكال التي تحتاجها بالضبط (الإسبانية ثلاثة، البولندية أربعة، العربية ستة)، مكتوبة كـ files.left_one, files.left_few... لـ i18next أو رسالة plural ICU واحدة، ويختار i18next الرسالة الصحيحة في وقت التشغيل.

جملة بعدّين، {files} {files === 1 ? 'file' : 'files'} in {folders} {folders === 1 ? 'folder' : 'folders'}، تصبح رسالة لكل عبارة معدودة ({{count}} file / {{count}} files) موضوعة في جملة واحدة، {{files}} in {{folders}}، لذا يحصل كل عد على أشكاله الخاصة ولا يزال بإمكان المترجمين إعادة ترتيبها. الترتيبات من مساعدات مثل ordinal(place) أو {n}{ordinalSuffix(n)} تصبح صيغ الجمع الترتيبية لـ i18next (t('rank.place', { count: place, ordinal: true })، مع صيغ الترتيب الخاصة بكل لغة: الإنجليزية 1st/2nd/3rd/4th، الفرنسية 1re/2e، الإسبانية 1.º.

يعمل الشيء نفسه خارج React: رسائل ICU (Svelte، Ember) تحصل على selectordinal، vue-i18n تحصل على key_ordinal_one، مفاتيح تم اختيارها بواسطة Intl.PluralRules، وفي Vue و Svelte و Astro و Lit و Ember و Flutter و Rails، تصبح كل عبارة معدودة استدعاء جمع خاصة بها داخل الجملة.

النص حول العناصر المضمنة البسيطة، مثل Read the <a href="/docs">docs</a> first، يصبح رسالة واحدة (Read the <a>docs</a> first) يتم عرضه باستخدام <Trans>، حتى يتمكن المترجمون من نقل الرابط. يحتفظ العنصر بخصائصه. يتم رفض الترجمات التي تفقد أو تعيد تسمية علامة.

إطارات بدون <Trans> تتمكن من الحصول على نفس الشيء، باستخدام نص العنصر الخاص به كرسالة خاصة به: فيو عبر <i18n-t> مع الفتحات، سفلت عبر توليد <I18nT> (مقطع في سفلت 5، فتحة في 3 و4)، أنغولار عبر توليد <i18n-t> مع ng-template الفتحات (NgModule قبل أنغولار 14)، إمبر عبر توليد <I18nT>، صوليد وقويك عبر rich(). في ريلز، link_to داخل جملة يتم دمجها في _html رسالة، لذا يتم حفظ تكويناتها.

ما الذي يُترجم

  • نص JSX, مع دمج النص والتعبيرات البسيطة في رسالة واحدة: Hi {user.name}! → Hi {name}!
  • السمات في قائمة السماح (عنصر نائب، بديل، عنوان، aria-label، aria-description، aria-valuetext، aria-roledescription، تسمية، أداة تلميح؛ قابل للتكوين)، وسمات SVG <title> و <desc>
  • السلاسل الحرفية وقوالب النصوص معروض في JSX، بما في ذلك الفرعين من a ? 'X' : 'Y' وجانب اليمين من &&
  • نسخ في الثوابت التي يقرأها المكونات (const NAV = [{ label: 'Home' }] مع NAV.map((n) => n.label)): تصبح السلاسل مفاتيح ويصبح كل قراءة t(n.label)
  • سلاسل موصولة ('Hi ' + name + '!') كرسالة واحدة، والرسائل المرسلة إلى مُعيِّنات الحالة، والإشعارات، alert والتحقق من صحة zod أو yup (z.string().min(1, 'Required'))
  • خصائص المكونات التي تحمل النص (<EmptyState heading="No orders yet" />، خاص بـ Vue empty-text="…")، جداول البحث المقروءة بالمفتاح (STATUS_LABELS[order.status])، الدوال المساعدة التي يتم عرض نتائجها، والنسخ المستوردة من وحدة نمطية عادية (nav.ts)، التي تصبح سلاسلها مفاتيح هناك عندما يمكن تتبع كل مكون يستوردها
  • الجمل المخصصة للجنس (gender === 'female' ? 'She…' : 'He…') كرسالة واحدة مع متغير لكل جنس، لذا تصيغ كل لغة كلماتها بطريقتها الخاصة
  • قوالب Vue و Svelte (Vue في HTML أو Pug): نص، {{ }} و { } التعبيرات، السمات (بما في ذلك title="Hi {name}")، والسلاسل النصية التي يعرضها التعبير، مثل {{ saving ? 'Saving…' : 'Save' }}
  • نصوص Vue و Svelte البرمجية: الرسائل التي يتم عرضها، أو تمريرها إلى alert, confirm، والرسائل المنبثقة والإشعارات، أو تعيينها إلى document.title، والثوابت التي يعرضها القالب (const tabs = [{ label: 'Home' }] مع {{ tab.label }}): تصبح السلاسل النصية مفاتيح ويقرأها القالب من خلال $t() أو $_()
  • HTML ثابت: نص العنصر، والجمل حول العناصر المضمنة كرسالة واحدة، ونفس السمات. يُترك النص من محرك قوالب أو PHP كما هو ويتم الإبلاغ عنه.

لا تتم ترجمتها أبدًا: عناوين URL والمسارات، والألوان، ومعرفات UUID، ووحدات CSS، ورسائل البريد الإلكتروني، وأسماء الملفات، والمعرفات snake_case أو kebab-case، والنصوص التي تحتوي على رموز فقط، وأي شيء بالداخل <code>, <pre>, <Trans>, translate="no" أو data-i18n-ignore.

يتم فحص كل ترجمة قبل كتابتها: أي ترجمة تضيف أو تحذف أو تعيد تسمية {placeholder} تُرفض. لا يتم أبدًا الكتابة فوق الترجمات الموجودة في قواميسك.

من اليمين إلى اليسار

اللغات العربية والعبرية والفارسية والأردية تُقرأ من اليمين إلى اليسار، لذا ml-4 أو margin-left ينتهي بها الأمر على الجانب الخطأ. عندما تكون اللغة المستهدفة من اليمين إلى اليسار، check قوائم الأنماط المثبتة على اليسار أو اليمين، و localize-dev rtl --fix يستبدل تلك التي لها مكافئ منطقي يبدو بنفس الشكل في اللغة الإنجليزية:

  • تايلويند: ml-/mr- → ms-/me-, pl-/pr- → ps-/pe-, text-left → text-start، والزوايا والحدود المستديرة، مع متغيرات مثل md: تم الاحتفاظ بها.
  • CSS: margin-left → margin-inline-start, padding-right → padding-inline-end, text-align: left → start, والحدود ونصف قطر الزوايا.

left-/right- يتم الإبلاغ عن المواضع والعوامات فقط، نظرًا لأنها غالبًا ما تكون حيلًا للتوسيط. تحقق من النتيجة في ar-XB مع localize-dev run --pseudo rtl.

الوثائق والمحتوى

تتم ترجمة الوثائق ومنشورات المدونة والصفحات القانونية كمستندات كاملة. localize-dev content تترجم ملفات Markdown و MDX إلى نسخة لكل لغة: تتم ترجمة النثر والعناوين وعناصر القائمة وخلايا الجدول وعناوين وأوصاف الواجهة الأمامية؛ تظل كتل التعليمات البرمجية والتعليمات البرمجية المضمنة وعناوين URL للروابط وواردات MDX والمكونات والتعبيرات كما هي مكتوبة بالضبط. يتم الاحتفاظ بالمقطع الذي تفقد ترجمته أيًا من هذه العناصر باللغة الإنجليزية والإبلاغ عنها.

localize.config.json
{
  "targetLocales": ["es", "fr"],
  "content": {
    "include": ["docs/**/*.md", "blog/**/*.mdx"],
    "output": "{dir}/{name}.{locale}{ext}"
  }
}

يقع الإخراج الافتراضي بجوار كل ملف (intro.es.md)، كما يتوقع Nextra و Fumadocs و Hugo. بالنسبة لـ Docusaurus استخدم "i18n/{locale}/docusaurus-plugin-content-docs/current/{path}". يتم تخطي المستندات التي لم تتغير منذ إنشاء نسخها (بصماتها موجودة في localize.lock.json، لذا تتم ترجمة النسخ المعدلة فقط مرة أخرى.

الخصوصية والبيانات

  • تُرسل السلاسل النصية المستخرجة فقط إلى واجهة برمجة التطبيقات (API)، مع مسار الملف والمكون كسياق. لا تُرسل الملفات بأكملها أبدًا.
  • عمليات الفحص والتشغيل دون اتصال بالإنترنت لا تغادر جهازك أبدًا.
  • يقوم واجهة سطر الأوامر (CLI) بإعادة كتابة الملفات محليًا؛ يقوم إجراء GitHub بالالتزام من المشغل الخاص بك باستخدام الرمز المميز الخاص بك.
  • تُخزن مفاتيح واجهة برمجة التطبيقات (API) كـ تجزئات؛ يُعرض السر مرة واحدة فقط.

القيود

  • النص المنسق يأخذ العناصر المضمنة المتداخلة حتى ثلاثة مستويات عمق (النص الغامق داخل رابط يصبح رسالة متداخلة). الخاص بالرابط title، مكتوبًا أو معينًا من التعليمات البرمجية، يبقى داخل مكون الجملة في React.
  • يتم التعرف على صيغ الجمع من خيارات السلاسل النصية المكونة من اثنتين بناءً على العدد (===/!== 1, > 1, < 2, Intl.PluralRules) وتساعد الصيغ الجمعية مع عدد وشكلين. كل إطار عمل يستخرج صيغ الجمع بطريقته الخاصة (Django's pluralize، Laravel's Str::plural، Kotlin's if … else) ويكتب صيغته الخاصة (<plurals>، اختلافات كتالوج السلاسل النصية، msgid_plural, trans_choice؛ Angular، الذي لا يملك شيئًا، يختار المفتاح مع مُنشأ pluralForm pipe). تحصل الجملة التي تحتوي على عدة أعداد على صيغة جمع لكل عدد في كل مكان ما عدا Django (الذي blocktranslate يأخذ واحدًا) و iOS؛ الصيغ الترتيبية تعمل في أطر عمل JavaScript و Angular، وليس في Flutter، Rails، Django، Laravel، Android أو iOS، التي لا تحتوي مكتبات i18n الخاصة بها على صيغ ترتيبية. على iOS، تحتاج صيغة الجمع إلى رقمها في النص ("\(n) items")، وهو ما يختلف به كتالوج السلاسل النصية.
  • تُترجم مكونات الفئة: من خلال withTranslation() عندما يكون الكلاس هو التصدير الافتراضي للملف، وإلا مع render() يعمل داخليًا <Translation>. تستخدم المنشئات والأعضاء الثابتة ومعالجات الأحداث i18next's t، لذا فإن النص الذي يخزنه المنشئ يتبع اللغة عند التركيب.
  • في نصوص Vue و Svelte، النسخة المستخرجة هي ما يظهر بوضوح: alert, confirm، والخبز المحمص والإشعارات، document.title، والثوابت التي يعرضها القالب (سلسلة نصية، ref('…')، كائن أو قائمة label/title الحقول، تم تمريرها إلى المكونات الفرعية المترجمة)، وما computed()، وظائف، $: و $derived إرجاع. الثابت النصي الذي يستخدمه البرنامج النصي نفسه يحتفظ بنصه، حيث قد يقارنه البرنامج النصي أو يرسله. في Svelte 4، يتم تحديث النص الذي ترجعه الدالة عند العرض التالي للمكون بعد تبديل اللغة.
  • تتم ترجمة قوالب Vue في Pug، #[…] العلامات المضمنة (ثلاثة مستويات عمق) و #{} القيم المضمنة. يتم تخطي القوالب في المعالجات المسبقة الأخرى (نادرة خارج Pug) والإبلاغ عنها.
  • لا يتم استخراج النسخ خارج المكونات (رسائل البريد الإلكتروني، نص SVG، الرسائل المبنية على الخادم)؛ تتم ترجمة مستندات Markdown و MDX بالكامل مع localize-dev content.
  • يقرأ طلب السحب للمعاينة ملفات الفرع الافتراضي؛ تُترك ملفات Git LFS والوحدات الفرعية.