@intlayer/docs 7.3.11 → 7.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/generated/docs.entry.cjs +19 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +19 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/intlayer_with_nuxt.md +294 -438
- package/docs/ar/intlayer_with_react_router_v7.md +33 -4
- package/docs/ar/intlayer_with_react_router_v7_fs_routes.md +516 -0
- package/docs/ar/intlayer_with_tanstack.md +2 -12
- package/docs/ar/intlayer_with_vite+vue.md +1 -0
- package/docs/de/intlayer_with_nuxt.md +284 -410
- package/docs/de/intlayer_with_react_router_v7.md +33 -4
- package/docs/de/intlayer_with_react_router_v7_fs_routes.md +573 -0
- package/docs/de/intlayer_with_tanstack.md +1 -0
- package/docs/de/intlayer_with_vite+vue.md +1 -0
- package/docs/en/intlayer_with_nuxt.md +237 -341
- package/docs/en/intlayer_with_react_router_v7.md +24 -0
- package/docs/en/intlayer_with_react_router_v7_fs_routes.md +570 -0
- package/docs/en/intlayer_with_tanstack.md +2 -12
- package/docs/en/intlayer_with_vite+vue.md +49 -48
- package/docs/en-GB/intlayer_with_nuxt.md +254 -378
- package/docs/en-GB/intlayer_with_react_router_v7.md +33 -4
- package/docs/en-GB/intlayer_with_react_router_v7_fs_routes.md +513 -0
- package/docs/en-GB/intlayer_with_tanstack.md +2 -12
- package/docs/en-GB/intlayer_with_vite+vue.md +1 -0
- package/docs/es/intlayer_with_nuxt.md +271 -390
- package/docs/es/intlayer_with_react_router_v7.md +33 -4
- package/docs/es/intlayer_with_react_router_v7_fs_routes.md +575 -0
- package/docs/es/intlayer_with_tanstack.md +1 -0
- package/docs/es/intlayer_with_vite+vue.md +1 -2
- package/docs/fr/intlayer_with_nuxt.md +278 -405
- package/docs/fr/intlayer_with_react_router_v7.md +34 -5
- package/docs/fr/intlayer_with_react_router_v7_fs_routes.md +574 -0
- package/docs/fr/intlayer_with_tanstack.md +1 -0
- package/docs/fr/intlayer_with_vite+vue.md +1 -0
- package/docs/hi/intlayer_with_nuxt.md +303 -447
- package/docs/hi/intlayer_with_react_router_v7.md +33 -4
- package/docs/hi/intlayer_with_react_router_v7_fs_routes.md +518 -0
- package/docs/hi/intlayer_with_tanstack.md +2 -12
- package/docs/hi/intlayer_with_vite+vue.md +1 -0
- package/docs/id/intlayer_with_nuxt.md +266 -395
- package/docs/id/intlayer_with_react_router_v7.md +29 -4
- package/docs/id/intlayer_with_react_router_v7_fs_routes.md +521 -0
- package/docs/id/intlayer_with_tanstack.md +2 -12
- package/docs/id/intlayer_with_vite+vue.md +1 -0
- package/docs/it/intlayer_with_nuxt.md +299 -423
- package/docs/it/intlayer_with_react_router_v7.md +33 -4
- package/docs/it/intlayer_with_react_router_v7_fs_routes.md +574 -0
- package/docs/it/intlayer_with_tanstack.md +1 -0
- package/docs/ja/intlayer_with_nuxt.md +309 -432
- package/docs/ja/intlayer_with_react_router_v7.md +33 -4
- package/docs/ja/intlayer_with_react_router_v7_fs_routes.md +574 -0
- package/docs/ja/intlayer_with_tanstack.md +2 -12
- package/docs/ja/intlayer_with_vite+vue.md +1 -0
- package/docs/ko/intlayer_with_nuxt.md +295 -422
- package/docs/ko/intlayer_with_react_router_v7.md +33 -4
- package/docs/ko/intlayer_with_react_router_v7_fs_routes.md +515 -0
- package/docs/ko/intlayer_with_tanstack.md +2 -12
- package/docs/ko/intlayer_with_vite+vue.md +1 -0
- package/docs/pl/intlayer_with_nuxt.md +273 -476
- package/docs/pl/intlayer_with_react_router_v7.md +32 -5
- package/docs/pl/intlayer_with_react_router_v7_fs_routes.md +615 -0
- package/docs/pl/intlayer_with_tanstack.md +2 -12
- package/docs/pl/intlayer_with_vite+vue.md +1 -0
- package/docs/pt/intlayer_with_nuxt.md +277 -420
- package/docs/pt/intlayer_with_react_router_v7.md +28 -0
- package/docs/pt/intlayer_with_tanstack.md +1 -0
- package/docs/ru/intlayer_with_nuxt.md +287 -425
- package/docs/ru/intlayer_with_react_router_v7.md +33 -4
- package/docs/ru/intlayer_with_react_router_v7_fs_routes.md +574 -0
- package/docs/ru/intlayer_with_tanstack.md +1 -0
- package/docs/ru/intlayer_with_vite+vue.md +1 -0
- package/docs/tr/intlayer_with_nuxt.md +313 -406
- package/docs/tr/intlayer_with_react_router_v7.md +33 -4
- package/docs/tr/intlayer_with_react_router_v7_fs_routes.md +572 -0
- package/docs/tr/intlayer_with_tanstack.md +2 -12
- package/docs/tr/intlayer_with_vite+vue.md +1 -0
- package/docs/vi/intlayer_with_nuxt.md +273 -418
- package/docs/vi/intlayer_with_react_router_v7.md +29 -4
- package/docs/vi/intlayer_with_react_router_v7_fs_routes.md +523 -0
- package/docs/vi/intlayer_with_tanstack.md +2 -12
- package/docs/vi/intlayer_with_vite+vue.md +1 -0
- package/docs/zh/intlayer_with_nuxt.md +300 -461
- package/docs/zh/intlayer_with_react_router_v7.md +33 -4
- package/docs/zh/intlayer_with_react_router_v7_fs_routes.md +516 -0
- package/docs/zh/intlayer_with_tanstack.md +2 -12
- package/docs/zh/intlayer_with_vite+vue.md +1 -0
- package/package.json +10 -11
- package/src/generated/docs.entry.ts +19 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-06-18
|
|
3
|
-
updatedAt: 2025-
|
|
4
|
-
title: كيفية ترجمة تطبيق Nuxt
|
|
5
|
-
description: اكتشف كيفية جعل
|
|
3
|
+
updatedAt: 2025-12-07
|
|
4
|
+
title: كيفية ترجمة تطبيق Nuxt و Vue الخاص بك – دليل i18n 2025
|
|
5
|
+
description: اكتشف كيفية جعل موقع Nuxt و Vue الخاص بك متعدد اللغات. اتبع الوثائق لتدويل (i18n) وترجمته.
|
|
6
6
|
keywords:
|
|
7
7
|
- التدويل
|
|
8
8
|
- التوثيق
|
|
@@ -14,16 +14,22 @@ slugs:
|
|
|
14
14
|
- doc
|
|
15
15
|
- environment
|
|
16
16
|
- nuxt-and-vue
|
|
17
|
-
applicationTemplate: https://github.com/aymericzip/intlayer-nuxt-template
|
|
17
|
+
applicationTemplate: https://github.com/aymericzip/intlayer-nuxt-4-template
|
|
18
|
+
youtubeVideo: https://www.youtube.com/watch?v=nhUcUAVQ6eQ
|
|
18
19
|
history:
|
|
20
|
+
- version: 7.3.11
|
|
21
|
+
date: 2025-12-07
|
|
22
|
+
changes: تحديث LocaleSwitcher، SEO، البيانات الوصفية
|
|
19
23
|
- version: 5.5.10
|
|
20
24
|
date: 2025-06-29
|
|
21
|
-
changes: بدء
|
|
25
|
+
changes: بدء السجل
|
|
22
26
|
---
|
|
23
27
|
|
|
24
|
-
#
|
|
28
|
+
# ترجمة موقع Nuxt و Vue الخاص بك باستخدام Intlayer | التدويل (i18n)
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
## جدول المحتويات
|
|
31
|
+
|
|
32
|
+
<TOC/>
|
|
27
33
|
|
|
28
34
|
## ما هو Intlayer؟
|
|
29
35
|
|
|
@@ -31,15 +37,36 @@ history:
|
|
|
31
37
|
|
|
32
38
|
مع Intlayer، يمكنك:
|
|
33
39
|
|
|
34
|
-
- **إدارة الترجمات بسهولة** باستخدام
|
|
35
|
-
-
|
|
36
|
-
- **ضمان دعم TypeScript** من خلال
|
|
37
|
-
- **الاستفادة من
|
|
40
|
+
- **إدارة الترجمات بسهولة** باستخدام قواميس تصريحية على مستوى المكونات.
|
|
41
|
+
- **تدويل البيانات الوصفية والمسارات والمحتوى بشكل ديناميكي**.
|
|
42
|
+
- **ضمان دعم TypeScript** من خلال أنواع مولدة تلقائيًا، مما يحسن الإكمال التلقائي واكتشاف الأخطاء.
|
|
43
|
+
- **الاستفادة من ميزات متقدمة**، مثل الكشف الديناميكي عن اللغة والتبديل بينها.
|
|
38
44
|
|
|
39
45
|
---
|
|
40
46
|
|
|
41
47
|
## دليل خطوة بخطوة لإعداد Intlayer في تطبيق Nuxt
|
|
42
48
|
|
|
49
|
+
<Tab defaultTab="video">
|
|
50
|
+
<TabItem label="فيديو" value="video">
|
|
51
|
+
|
|
52
|
+
<iframe title="كيفية ترجمة تطبيق Nuxt و Vue الخاص بك باستخدام Intlayer؟ اكتشف Intlayer" class="m-auto aspect-[16/9] w-full overflow-hidden rounded-lg border-0" allow="autoplay; gyroscope;" loading="lazy" width="1080" height="auto" src="https://www.youtube.com/embed/nhUcUAVQ6eQ?autoplay=0&origin=http://intlayer.org&controls=0&rel=1"/>
|
|
53
|
+
|
|
54
|
+
</TabItem>
|
|
55
|
+
<TabItem label="كود" value="code">
|
|
56
|
+
|
|
57
|
+
<iframe
|
|
58
|
+
src="https://stackblitz.com/github/aymericzip/intlayer-nuxt-4-template?embed=1&ctl=1&file=intlayer.config.ts"
|
|
59
|
+
className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full"
|
|
60
|
+
title="عرض توضيحي في CodeSandbox - كيفية تدويل تطبيقك باستخدام Intlayer"
|
|
61
|
+
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
|
62
|
+
loading="lazy"
|
|
63
|
+
/>
|
|
64
|
+
|
|
65
|
+
</TabItem>
|
|
66
|
+
</Tab>
|
|
67
|
+
|
|
68
|
+
راجع [قالب التطبيق](https://github.com/aymericzip/intlayer-nuxt-4-template) على GitHub.
|
|
69
|
+
|
|
43
70
|
### الخطوة 1: تثبيت التبعيات
|
|
44
71
|
|
|
45
72
|
قم بتثبيت الحزم اللازمة باستخدام npm:
|
|
@@ -61,13 +88,13 @@ yarn add --save-dev nuxt-intlayer
|
|
|
61
88
|
|
|
62
89
|
- **intlayer**
|
|
63
90
|
|
|
64
|
-
الحزمة الأساسية التي توفر أدوات التدويل لإدارة التكوين،
|
|
91
|
+
الحزمة الأساسية التي توفر أدوات التدويل لإدارة التكوين، الترجمة، [إعلان المحتوى](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ar/dictionary/content_file.md)، التحويل البرمجي، و[أوامر CLI](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ar/cli/index.md).
|
|
65
92
|
|
|
66
93
|
- **vue-intlayer**
|
|
67
|
-
الحزمة التي تدمج Intlayer مع تطبيق Vue.
|
|
94
|
+
الحزمة التي تدمج Intlayer مع تطبيق Vue. تحتوي على composables لمكونات Vue.
|
|
68
95
|
|
|
69
96
|
- **nuxt-intlayer**
|
|
70
|
-
وحدة Nuxt التي تدمج Intlayer مع تطبيقات Nuxt. توفر إعدادًا تلقائيًا،
|
|
97
|
+
وحدة Nuxt التي تدمج Intlayer مع تطبيقات Nuxt. توفر إعدادًا تلقائيًا، وmiddleware لاكتشاف اللغة، وإدارة الكوكيز، وإعادة توجيه URL.
|
|
71
98
|
|
|
72
99
|
### الخطوة 2: تكوين مشروعك
|
|
73
100
|
|
|
@@ -82,13 +109,10 @@ const config: IntlayerConfig = {
|
|
|
82
109
|
Locales.ENGLISH,
|
|
83
110
|
Locales.FRENCH,
|
|
84
111
|
Locales.SPANISH,
|
|
85
|
-
//
|
|
112
|
+
// لغات أخرى خاصة بك
|
|
86
113
|
],
|
|
87
114
|
defaultLocale: Locales.ENGLISH,
|
|
88
115
|
},
|
|
89
|
-
content: {
|
|
90
|
-
contentDir: ["."], // لأن Intlayer بشكل افتراضي سيراقب ملفات إعلان المحتوى من مجلد `./src`
|
|
91
|
-
},
|
|
92
116
|
};
|
|
93
117
|
|
|
94
118
|
export default config;
|
|
@@ -104,13 +128,10 @@ const config = {
|
|
|
104
128
|
Locales.ENGLISH,
|
|
105
129
|
Locales.FRENCH,
|
|
106
130
|
Locales.SPANISH,
|
|
107
|
-
//
|
|
131
|
+
// لغات أخرى خاصة بك
|
|
108
132
|
],
|
|
109
133
|
defaultLocale: Locales.ENGLISH,
|
|
110
134
|
},
|
|
111
|
-
content: {
|
|
112
|
-
contentDir: ["."],
|
|
113
|
-
},
|
|
114
135
|
};
|
|
115
136
|
|
|
116
137
|
export default config;
|
|
@@ -126,19 +147,16 @@ const config = {
|
|
|
126
147
|
Locales.ENGLISH,
|
|
127
148
|
Locales.FRENCH,
|
|
128
149
|
Locales.SPANISH,
|
|
129
|
-
//
|
|
150
|
+
// لغات أخرى خاصة بك
|
|
130
151
|
],
|
|
131
152
|
defaultLocale: Locales.ENGLISH,
|
|
132
153
|
},
|
|
133
|
-
content: {
|
|
134
|
-
contentDir: ["."],
|
|
135
|
-
},
|
|
136
154
|
};
|
|
137
155
|
|
|
138
156
|
module.exports = config;
|
|
139
157
|
```
|
|
140
158
|
|
|
141
|
-
> من خلال ملف التكوين هذا، يمكنك إعداد عناوين URL محلية، إعادة توجيه الوسيط، أسماء
|
|
159
|
+
> من خلال ملف التكوين هذا، يمكنك إعداد عناوين URL محلية، إعادة توجيه الوسيط، أسماء الكوكيز، موقع وامتداد إعلانات المحتوى الخاصة بك، تعطيل سجلات Intlayer في وحدة التحكم، والمزيد. للحصول على قائمة كاملة بالمعلمات المتاحة، راجع [توثيق التكوين](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ar/configuration.md).
|
|
142
160
|
|
|
143
161
|
### الخطوة 3: دمج Intlayer في تكوين Nuxt الخاص بك
|
|
144
162
|
|
|
@@ -153,247 +171,46 @@ export default defineNuxtConfig({
|
|
|
153
171
|
});
|
|
154
172
|
```
|
|
155
173
|
|
|
156
|
-
> تقوم وحدة `nuxt-intlayer` تلقائيًا بالتعامل مع دمج Intlayer مع Nuxt. فهي تقوم بإعداد بناء إعلان المحتوى، ومراقبة الملفات في وضع التطوير، وتوفير
|
|
174
|
+
> تقوم وحدة `nuxt-intlayer` تلقائيًا بالتعامل مع دمج Intlayer مع Nuxt. فهي تقوم بإعداد بناء إعلان المحتوى، ومراقبة الملفات في وضع التطوير، وتوفير middleware لاكتشاف اللغة، وإدارة التوجيه المحلي.
|
|
157
175
|
|
|
158
176
|
### الخطوة 4: إعلان المحتوى الخاص بك
|
|
159
177
|
|
|
160
178
|
قم بإنشاء وإدارة إعلانات المحتوى الخاصة بك لتخزين الترجمات:
|
|
161
179
|
|
|
162
|
-
```tsx fileName="
|
|
163
|
-
import {
|
|
180
|
+
```tsx fileName="content/home-page.content.ts" contentDeclarationFormat="typescript"
|
|
181
|
+
import { type Dictionary, t } from "intlayer";
|
|
164
182
|
|
|
165
|
-
const
|
|
166
|
-
key: "
|
|
183
|
+
const content = {
|
|
184
|
+
key: "home-page",
|
|
167
185
|
content: {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
es: "Edita <code>components/HelloWorld.vue</code> y guarda para probar HMR",
|
|
173
|
-
}),
|
|
174
|
-
checkOut: t({
|
|
175
|
-
ar: "تحقق من ",
|
|
176
|
-
en: "Check out ",
|
|
177
|
-
fr: "Vérifiez ",
|
|
178
|
-
es: "Compruebe ",
|
|
179
|
-
}),
|
|
180
|
-
nuxtIntlayer: t({
|
|
181
|
-
ar: "توثيق Nuxt Intlayer",
|
|
182
|
-
en: "Nuxt Intlayer documentation",
|
|
183
|
-
fr: "Documentation de Nuxt Intlayer",
|
|
184
|
-
es: "Documentación de Nuxt Intlayer",
|
|
185
|
-
}),
|
|
186
|
-
learnMore: t({
|
|
187
|
-
ar: "تعرف أكثر على Nuxt في ",
|
|
188
|
-
en: "Learn more about Nuxt in the ",
|
|
189
|
-
fr: "En savoir plus sur Nuxt dans la ",
|
|
190
|
-
es: "Aprenda más sobre Nuxt en la ",
|
|
186
|
+
title: t({
|
|
187
|
+
en: "Hello world",
|
|
188
|
+
fr: "Bonjour le monde",
|
|
189
|
+
es: "Hola mundo",
|
|
191
190
|
}),
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
es: "Documentación de Nuxt",
|
|
191
|
+
metaTitle: t({
|
|
192
|
+
en: "Welcome | My Application",
|
|
193
|
+
fr: "Bienvenue | Mon Application",
|
|
194
|
+
es: "Bienvenido | Mi Aplicación",
|
|
197
195
|
}),
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
fr: "Cliquez sur le logo Nuxt pour en savoir plus",
|
|
203
|
-
es: "Haga clic en el logotipo de Nuxt para obtener más información",
|
|
196
|
+
metaDescription: t({
|
|
197
|
+
en: "Discover your multilingual Nuxt app homepage powered by Intlayer.",
|
|
198
|
+
fr: "Découvrez la page d'accueil multilingue de votre application Nuxt propulsée par Intlayer.",
|
|
199
|
+
es: "Descubre la página de inicio multilingüe de tu aplicación Nuxt impulsada por Intlayer.",
|
|
204
200
|
}),
|
|
205
201
|
},
|
|
206
202
|
} satisfies Dictionary;
|
|
207
203
|
|
|
208
|
-
export default
|
|
204
|
+
export default content;
|
|
209
205
|
```
|
|
210
206
|
|
|
211
|
-
|
|
212
|
-
import { t } from "intlayer";
|
|
207
|
+
> يمكن تعريف إعلانات المحتوى الخاصة بك في أي مكان في تطبيقك طالما تم تضمينها في دليل `contentDir` (افتراضيًا، `./src`). ويجب أن تتطابق مع امتداد ملف إعلان المحتوى (افتراضيًا، `.content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}`).
|
|
213
208
|
|
|
214
|
-
|
|
215
|
-
const helloWorldContent = {
|
|
216
|
-
key: "helloworld",
|
|
217
|
-
content: {
|
|
218
|
-
count: t({
|
|
219
|
-
ar: "العدد هو ",
|
|
220
|
-
en: "count is ",
|
|
221
|
-
fr: "le compte est ",
|
|
222
|
-
es: "el recuento es ",
|
|
223
|
-
}),
|
|
224
|
-
edit: t({
|
|
225
|
-
ar: "حرر <code>components/HelloWorld.vue</code> واحفظ لاختبار HMR",
|
|
226
|
-
en: "Edit <code>components/HelloWorld.vue</code> and save to test HMR",
|
|
227
|
-
fr: "Éditez <code>components/HelloWorld.vue</code> et enregistrez pour tester HMR",
|
|
228
|
-
es: "Edita <code>components/HelloWorld.vue</code> y guarda para probar HMR",
|
|
229
|
-
}),
|
|
230
|
-
checkOut: t({
|
|
231
|
-
ar: "تحقق من ",
|
|
232
|
-
en: "Check out ",
|
|
233
|
-
fr: "Vérifiez ",
|
|
234
|
-
es: "Compruebe ",
|
|
235
|
-
}),
|
|
236
|
-
nuxtIntlayer: t({
|
|
237
|
-
ar: "توثيق Nuxt Intlayer",
|
|
238
|
-
en: "Nuxt Intlayer documentation",
|
|
239
|
-
fr: "Documentation de Nuxt Intlayer",
|
|
240
|
-
es: "Documentación de Nuxt Intlayer",
|
|
241
|
-
}),
|
|
242
|
-
learnMore: t({
|
|
243
|
-
ar: "تعرف أكثر على Nuxt في ",
|
|
244
|
-
en: "Learn more about Nuxt in the ",
|
|
245
|
-
fr: "En savoir plus sur Nuxt dans la ",
|
|
246
|
-
es: "Aprenda más sobre Nuxt en la ",
|
|
247
|
-
}),
|
|
248
|
-
nuxtDocs: t({
|
|
249
|
-
ar: "توثيق Nuxt",
|
|
250
|
-
en: "Nuxt Documentation",
|
|
251
|
-
fr: "Documentation Nuxt",
|
|
252
|
-
es: "Documentación de Nuxt",
|
|
253
|
-
}),
|
|
254
|
-
readTheDocs: t({
|
|
255
|
-
ar: "انقر على شعار Nuxt لمعرفة المزيد",
|
|
256
|
-
en: "Click on the Nuxt logo to learn more",
|
|
257
|
-
fr: "Cliquez sur le logo Nuxt pour en savoir plus",
|
|
258
|
-
es: "Haga clic en el logotipo de Nuxt para obtener más información",
|
|
259
|
-
}),
|
|
260
|
-
},
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
export default helloWorldContent;
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
```javascript fileName="components/helloWorld.content.cjs" contentDeclarationFormat="commonjs"
|
|
267
|
-
const { t } = require("intlayer");
|
|
268
|
-
|
|
269
|
-
/** @type {import('intlayer').Dictionary} */
|
|
270
|
-
const helloWorldContent = {
|
|
271
|
-
key: "helloworld",
|
|
272
|
-
content: {
|
|
273
|
-
count: t({
|
|
274
|
-
ar: "العدد هو ",
|
|
275
|
-
en: "count is ",
|
|
276
|
-
fr: "le compte est ",
|
|
277
|
-
es: "el recuento es ",
|
|
278
|
-
}),
|
|
279
|
-
edit: t({
|
|
280
|
-
ar: "حرر <code>components/HelloWorld.vue</code> واحفظ لاختبار HMR",
|
|
281
|
-
en: "Edit <code>components/HelloWorld.vue</code> and save to test HMR",
|
|
282
|
-
fr: "Éditez <code>components/HelloWorld.vue</code> et enregistrez pour tester HMR",
|
|
283
|
-
es: "Edita <code>components/HelloWorld.vue</code> y guarda para probar HMR",
|
|
284
|
-
}),
|
|
285
|
-
checkOut: t({
|
|
286
|
-
ar: "اطلع على ",
|
|
287
|
-
en: "Check out ",
|
|
288
|
-
fr: "Vérifiez ",
|
|
289
|
-
es: "Compruebe ",
|
|
290
|
-
}),
|
|
291
|
-
nuxtIntlayer: t({
|
|
292
|
-
ar: "توثيق Nuxt Intlayer",
|
|
293
|
-
en: "Nuxt Intlayer documentation",
|
|
294
|
-
fr: "Documentation de Nuxt Intlayer",
|
|
295
|
-
es: "وثائق Nuxt Intlayer",
|
|
296
|
-
}),
|
|
297
|
-
learnMore: t({
|
|
298
|
-
en: "تعرف أكثر على Nuxt في ",
|
|
299
|
-
fr: "En savoir plus sur Nuxt dans la ",
|
|
300
|
-
es: "Aprenda más sobre Nuxt en la ",
|
|
301
|
-
}),
|
|
302
|
-
nuxtDocs: t({
|
|
303
|
-
en: "وثائق Nuxt",
|
|
304
|
-
fr: "Documentation Nuxt",
|
|
305
|
-
es: "Documentación de Nuxt",
|
|
306
|
-
}),
|
|
307
|
-
readTheDocs: t({
|
|
308
|
-
en: "انقر على شعار Nuxt لمعرفة المزيد",
|
|
309
|
-
fr: "Cliquez sur le logo Nuxt pour en savoir plus",
|
|
310
|
-
es: "Haga clic en el logotipo de Nuxt para obtener más información",
|
|
311
|
-
}),
|
|
312
|
-
},
|
|
313
|
-
};
|
|
314
|
-
|
|
315
|
-
module.exports = helloWorldContent;
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
```json fileName="components/helloWorld.content.json" contentDeclarationFormat="json"
|
|
319
|
-
{
|
|
320
|
-
"$schema": "https://intlayer.org/schema.json",
|
|
321
|
-
"key": "helloworld",
|
|
322
|
-
"content": {
|
|
323
|
-
"count": {
|
|
324
|
-
"nodeType": "translation",
|
|
325
|
-
"translation": {
|
|
326
|
-
"ar": "العدد هو ",
|
|
327
|
-
"en": "count is ",
|
|
328
|
-
"fr": "le compte est ",
|
|
329
|
-
"es": "el recuento es "
|
|
330
|
-
}
|
|
331
|
-
},
|
|
332
|
-
"edit": {
|
|
333
|
-
"nodeType": "translation",
|
|
334
|
-
"translation": {
|
|
335
|
-
"ar": "حرر <code>components/HelloWorld.vue</code> واحفظ لاختبار HMR",
|
|
336
|
-
"en": "Edit <code>components/HelloWorld.vue</code> and save to test HMR",
|
|
337
|
-
"fr": "Éditez <code>components/HelloWorld.vue</code> et enregistrez pour tester HMR",
|
|
338
|
-
"es": "Edita <code>components/HelloWorld.vue</code> y guarda para probar HMR"
|
|
339
|
-
}
|
|
340
|
-
},
|
|
341
|
-
"checkOut": {
|
|
342
|
-
"nodeType": "translation",
|
|
343
|
-
"translation": {
|
|
344
|
-
"ar": "اطلع على ",
|
|
345
|
-
"en": "Check out ",
|
|
346
|
-
"fr": "Vérifiez ",
|
|
347
|
-
"es": "Compruebe "
|
|
348
|
-
}
|
|
349
|
-
},
|
|
350
|
-
"nuxtIntlayer": {
|
|
351
|
-
"nodeType": "translation",
|
|
352
|
-
"translation": {
|
|
353
|
-
"ar": "توثيق Nuxt Intlayer",
|
|
354
|
-
"en": "Nuxt Intlayer documentation",
|
|
355
|
-
"fr": "Documentation de Nuxt Intlayer",
|
|
356
|
-
"es": "Documentación de Nuxt Intlayer"
|
|
357
|
-
}
|
|
358
|
-
},
|
|
359
|
-
"learnMore": {
|
|
360
|
-
"nodeType": "translation",
|
|
361
|
-
"translation": {
|
|
362
|
-
"ar": "تعرف على المزيد حول Nuxt في ",
|
|
363
|
-
"en": "Learn more about Nuxt in the ",
|
|
364
|
-
"fr": "En savoir plus sur Nuxt dans la ",
|
|
365
|
-
"es": "Aprenda más sobre Nuxt en la "
|
|
366
|
-
}
|
|
367
|
-
},
|
|
368
|
-
"nuxtDocs": {
|
|
369
|
-
"nodeType": "translation",
|
|
370
|
-
"translation": {
|
|
371
|
-
"ar": "توثيق Nuxt",
|
|
372
|
-
"en": "Nuxt Documentation",
|
|
373
|
-
"fr": "Documentation Nuxt",
|
|
374
|
-
"es": "Documentación de Nuxt"
|
|
375
|
-
}
|
|
376
|
-
},
|
|
377
|
-
"readTheDocs": {
|
|
378
|
-
"nodeType": "translation",
|
|
379
|
-
"translation": {
|
|
380
|
-
"ar": "انقر على شعار Nuxt لمعرفة المزيد",
|
|
381
|
-
"en": "Click on the Nuxt logo to learn more",
|
|
382
|
-
"fr": "Cliquez sur le logo Nuxt pour en savoir plus",
|
|
383
|
-
"es": "Haga clic en el logotipo de Nuxt para obtener más información"
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
> يمكن تعريف إعلانات المحتوى الخاصة بك في أي مكان في تطبيقك طالما أنها مدرجة في دليل `contentDir` (افتراضيًا، `./src`). وتتطابق مع امتداد ملف إعلان المحتوى (افتراضيًا، `.content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}`).
|
|
391
|
-
|
|
392
|
-
> لمزيد من التفاصيل، راجع [توثيق إعلان المحتوى](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ar/dictionary/get_started.md).
|
|
209
|
+
> لمزيد من التفاصيل، راجع [توثيق إعلان المحتوى](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ar/dictionary/content_file.md).
|
|
393
210
|
|
|
394
211
|
### الخطوة 5: استخدام Intlayer في كودك
|
|
395
212
|
|
|
396
|
-
يمكنك الوصول إلى قواميس المحتوى الخاصة بك في جميع أنحاء تطبيق Nuxt الخاص بك باستخدام
|
|
213
|
+
يمكنك الوصول إلى قواميس المحتوى الخاصة بك في جميع أنحاء تطبيق Nuxt الخاص بك باستخدام الـ `useIntlayer` composable:
|
|
397
214
|
|
|
398
215
|
```vue fileName="components/HelloWorld.vue"
|
|
399
216
|
<script setup lang="ts">
|
|
@@ -431,7 +248,7 @@ const countRef = ref(0);
|
|
|
431
248
|
<checkOut />
|
|
432
249
|
<a href="https://nuxt.com/docs/getting-started/introduction" target="_blank"
|
|
433
250
|
>Nuxt</a
|
|
434
|
-
|
|
251
|
+
>، <nuxtIntlayer />
|
|
435
252
|
</p>
|
|
436
253
|
<p>
|
|
437
254
|
<learnMore />
|
|
@@ -446,82 +263,72 @@ const countRef = ref(0);
|
|
|
446
263
|
|
|
447
264
|
يقدم Intlayer واجهات برمجة تطبيقات مختلفة للوصول إلى المحتوى الخاص بك:
|
|
448
265
|
|
|
449
|
-
-
|
|
450
|
-
استخدم
|
|
266
|
+
- **بناء الجملة المعتمد على المكونات** (موصى به):
|
|
267
|
+
استخدم بناء الجملة `<myContent />`، أو `<Component :is="myContent" />` لعرض المحتوى كعقدة Intlayer. هذا يتكامل بسلاسة مع [المحرر المرئي](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ar/intlayer_visual_editor.md) و [نظام إدارة المحتوى (CMS)](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ar/intlayer_CMS.md).
|
|
451
268
|
|
|
452
|
-
-
|
|
269
|
+
- **بناء الجملة المعتمد على النص**:
|
|
453
270
|
استخدم `{{ myContent }}` لعرض المحتوى كنص عادي، بدون دعم المحرر المرئي.
|
|
454
271
|
|
|
455
|
-
-
|
|
272
|
+
- **بناء جملة HTML الخام**:
|
|
456
273
|
استخدم `<div v-html="myContent" />` لعرض المحتوى كـ HTML خام، بدون دعم المحرر المرئي.
|
|
457
274
|
|
|
458
|
-
-
|
|
459
|
-
|
|
460
|
-
- استخدم `const content = useIntlayer("myContent");` و `{{ content.myContent }}` / `<content.myContent />`.
|
|
461
|
-
- أو استخدم `const { myContent } = useIntlayer("myContent");` و `{{ myContent}}` / `<myContent/>` لتفكيك المحتوى.
|
|
275
|
+
- **بناء جملة التفكيك**:
|
|
276
|
+
الدالة القابلة للاستخدام `useIntlayer` تُرجع Proxy يحتوي على المحتوى. يمكن تفكيك هذا البروكسي للوصول إلى المحتوى مع الحفاظ على التفاعلية.
|
|
277
|
+
- استخدم `const content = useIntlayer("myContent");` و `{{ content.myContent }}` / `<content.myContent />`.
|
|
278
|
+
- أو استخدم `const { myContent } = useIntlayer("myContent");` و `{{ myContent}}` / `<myContent/>` لتفكيك المحتوى.
|
|
462
279
|
|
|
463
280
|
### (اختياري) الخطوة 6: تغيير لغة المحتوى الخاص بك
|
|
464
281
|
|
|
465
|
-
لتغيير لغة المحتوى الخاص بك، يمكنك استخدام الدالة `setLocale` المقدمة من
|
|
282
|
+
لتغيير لغة المحتوى الخاص بك، يمكنك استخدام الدالة `setLocale` المقدمة من الدالة القابلة للاستخدام `useLocale`. تتيح لك هذه الدالة تعيين لغة التطبيق وتحديث المحتوى وفقًا لذلك.
|
|
466
283
|
|
|
467
|
-
|
|
284
|
+
قم بإنشاء مكون للتبديل بين اللغات باستخدام `NuxtLink`. **استخدام الروابط بدلاً من الأزرار للتبديل بين اللغات هو أفضل ممارسة لتحسين محركات البحث وقابلية اكتشاف الصفحات**، حيث يسمح لمحركات البحث بفهرسة جميع النسخ المحلية من صفحاتك:
|
|
468
285
|
|
|
469
286
|
```vue fileName="components/LocaleSwitcher.vue"
|
|
470
|
-
<template>
|
|
471
|
-
<div class="locale-switcher">
|
|
472
|
-
<select v-model="selectedLocale" @change="changeLocale">
|
|
473
|
-
<option v-for="loc in availableLocales" :key="loc" :value="loc">
|
|
474
|
-
{{ getLocaleName(loc) }}
|
|
475
|
-
</option>
|
|
476
|
-
</select>
|
|
477
|
-
</div>
|
|
478
|
-
</template>
|
|
479
|
-
|
|
480
287
|
<script setup lang="ts">
|
|
481
|
-
import {
|
|
482
|
-
import { getLocaleName } from "intlayer";
|
|
288
|
+
import { getLocaleName, getLocalizedUrl } from "intlayer";
|
|
483
289
|
import { useLocale } from "vue-intlayer";
|
|
484
290
|
|
|
485
|
-
//
|
|
291
|
+
// Nuxt يقوم بالاستيراد التلقائي لـ useRoute
|
|
292
|
+
const route = useRoute();
|
|
486
293
|
const { locale, availableLocales, setLocale } = useLocale();
|
|
487
|
-
|
|
488
|
-
// تتبع اللغة المختارة باستخدام ref
|
|
489
|
-
const selectedLocale = ref(locale.value);
|
|
490
|
-
|
|
491
|
-
// تحديث اللغة عند تغيير الاختيار
|
|
492
|
-
const changeLocale = () => setLocale(selectedLocale.value);
|
|
493
|
-
|
|
494
|
-
// الحفاظ على تزامن selectedLocale مع اللغة العالمية
|
|
495
|
-
watch(
|
|
496
|
-
() => locale.value,
|
|
497
|
-
(newLocale) => {
|
|
498
|
-
selectedLocale.value = newLocale;
|
|
499
|
-
}
|
|
500
|
-
);
|
|
501
294
|
</script>
|
|
295
|
+
|
|
296
|
+
<template>
|
|
297
|
+
<nav class="locale-switcher">
|
|
298
|
+
<NuxtLink
|
|
299
|
+
v-for="localeEl in availableLocales"
|
|
300
|
+
:key="localeEl"
|
|
301
|
+
:to="getLocalizedUrl(route.fullPath, localeEl)"
|
|
302
|
+
class="locale-link"
|
|
303
|
+
:class="{ 'active-locale': localeEl === locale }"
|
|
304
|
+
@click="setLocale(localeEl)"
|
|
305
|
+
>
|
|
306
|
+
{{ getLocaleName(localeEl) }}
|
|
307
|
+
</NuxtLink>
|
|
308
|
+
</nav>
|
|
502
309
|
</template>
|
|
310
|
+
```
|
|
503
311
|
|
|
504
|
-
|
|
505
|
-
.locale-switcher {
|
|
506
|
-
margin: 1rem 0;
|
|
507
|
-
}
|
|
312
|
+
> استخدام `NuxtLink` مع سمات `href` الصحيحة (عبر `getLocalizedUrl`) يضمن أن محركات البحث يمكنها اكتشاف جميع النسخ اللغوية لصفحاتك. هذا أفضل من التبديل بين اللغات باستخدام جافا سكريبت فقط، والذي قد لا تتبعه عناكب محركات البحث.
|
|
508
313
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
314
|
+
بعد ذلك، قم بإعداد ملف `app.vue` لاستخدام التخطيطات:
|
|
315
|
+
|
|
316
|
+
```vue fileName="app.vue"
|
|
317
|
+
<template>
|
|
318
|
+
<NuxtLayout>
|
|
319
|
+
<NuxtPage />
|
|
320
|
+
</NuxtLayout>
|
|
321
|
+
</template>
|
|
515
322
|
```
|
|
516
323
|
|
|
517
|
-
|
|
324
|
+
### (اختياري) الخطوة 6ب: إنشاء تخطيط مع التنقل
|
|
518
325
|
|
|
519
|
-
|
|
326
|
+
تسمح تخطيطات Nuxt بتعريف هيكل مشترك لصفحاتك. قم بإنشاء تخطيط افتراضي يتضمن مفتاح تبديل اللغة والتنقل:
|
|
327
|
+
|
|
328
|
+
```vue fileName="layouts/default.vue"
|
|
520
329
|
<script setup lang="ts">
|
|
521
|
-
import
|
|
330
|
+
import Links from "~/components/Links.vue";
|
|
522
331
|
import LocaleSwitcher from "~/components/LocaleSwitcher.vue";
|
|
523
|
-
|
|
524
|
-
const content = useIntlayer("app"); // إنشاء ملف إعلان intlayer ذي الصلة
|
|
525
332
|
</script>
|
|
526
333
|
|
|
527
334
|
<template>
|
|
@@ -530,44 +337,84 @@ const content = useIntlayer("app"); // إنشاء ملف إعلان intlayer ذ
|
|
|
530
337
|
<LocaleSwitcher />
|
|
531
338
|
</header>
|
|
532
339
|
<main>
|
|
533
|
-
<
|
|
340
|
+
<slot />
|
|
534
341
|
</main>
|
|
342
|
+
|
|
343
|
+
<Links href="/">الرئيسية</Links>
|
|
344
|
+
<Links href="/about">حول</Links>
|
|
535
345
|
</div>
|
|
536
346
|
</template>
|
|
537
347
|
```
|
|
538
348
|
|
|
349
|
+
مكون `Links` (الموضح أدناه) يضمن أن روابط التنقل الداخلية تتم ترجمتها تلقائيًا.
|
|
350
|
+
|
|
539
351
|
### (اختياري) الخطوة 7: إضافة التوجيه المحلي إلى تطبيقك
|
|
540
352
|
|
|
541
|
-
يتولى Nuxt تلقائيًا التعامل مع التوجيه المحلي عند استخدام وحدة `nuxt-intlayer`.
|
|
353
|
+
يتولى Nuxt تلقائيًا التعامل مع التوجيه المحلي عند استخدام وحدة `nuxt-intlayer`. هذا ينشئ مسارات لكل لغة تلقائيًا بناءً على هيكل دليل الصفحات الخاص بك.
|
|
542
354
|
|
|
543
355
|
مثال:
|
|
544
356
|
|
|
545
357
|
```plaintext
|
|
546
358
|
pages/
|
|
547
|
-
├── index.vue →
|
|
548
|
-
├── about.vue → /about
|
|
359
|
+
├── index.vue → /, /fr, /es
|
|
360
|
+
├── about.vue → /about, /fr/about, /es/about
|
|
549
361
|
└── contact/
|
|
550
|
-
└── index.vue → /contact
|
|
362
|
+
└── index.vue → /contact, /fr/contact, /es/contact
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
لإنشاء صفحات محلية، ببساطة قم بإنشاء ملفات Vue الخاصة بك في دليل `pages/`. فيما يلي مثالان لصفحات:
|
|
366
|
+
|
|
367
|
+
**صفحة الرئيسية (`pages/index.vue`):**
|
|
368
|
+
|
|
369
|
+
```vue fileName="pages/index.vue"
|
|
370
|
+
<script setup lang="ts">
|
|
371
|
+
import { useIntlayer } from "vue-intlayer";
|
|
372
|
+
|
|
373
|
+
const content = useIntlayer("home-page");
|
|
374
|
+
|
|
375
|
+
useHead({
|
|
376
|
+
title: content.metaTitle.value,
|
|
377
|
+
meta: [
|
|
378
|
+
{
|
|
379
|
+
name: "description",
|
|
380
|
+
content: content.metaDescription.value,
|
|
381
|
+
},
|
|
382
|
+
],
|
|
383
|
+
});
|
|
384
|
+
</script>
|
|
385
|
+
|
|
386
|
+
<template>
|
|
387
|
+
<h1><content.title /></h1>
|
|
388
|
+
</template>
|
|
551
389
|
```
|
|
552
390
|
|
|
553
|
-
|
|
391
|
+
**صفحة حول (`pages/about.vue`):**
|
|
554
392
|
|
|
555
393
|
```vue fileName="pages/about.vue"
|
|
556
394
|
<script setup lang="ts">
|
|
557
395
|
import { useIntlayer } from "vue-intlayer";
|
|
558
396
|
|
|
559
|
-
const content = useIntlayer("about");
|
|
397
|
+
const content = useIntlayer("about-page");
|
|
398
|
+
|
|
399
|
+
useHead({
|
|
400
|
+
title: content.metaTitle.raw, // استخدم .raw للوصول إلى النص الأساسي
|
|
401
|
+
meta: [
|
|
402
|
+
{
|
|
403
|
+
name: "description",
|
|
404
|
+
content: content.metaDescription.raw, // استخدم .raw للوصول إلى النص الأساسي
|
|
405
|
+
},
|
|
406
|
+
],
|
|
407
|
+
});
|
|
560
408
|
</script>
|
|
561
409
|
|
|
562
410
|
<template>
|
|
563
|
-
<
|
|
564
|
-
<h1>{{ content.title }}</h1>
|
|
565
|
-
<p>{{ content.description }}</p>
|
|
566
|
-
</div>
|
|
411
|
+
<h1><content.title /></h1>
|
|
567
412
|
</template>
|
|
568
413
|
```
|
|
569
414
|
|
|
570
|
-
|
|
415
|
+
> ملاحظة: يتم استيراد `useHead` تلقائيًا في Nuxt. يمكنك الوصول إلى قيم المحتوى باستخدام `.value` (تفاعلي) أو `.raw` (نص بدائي) حسب حاجتك.
|
|
416
|
+
|
|
417
|
+
سيقوم موديل `nuxt-intlayer` تلقائيًا بـ:
|
|
571
418
|
|
|
572
419
|
- اكتشاف اللغة المفضلة للمستخدم
|
|
573
420
|
- التعامل مع تبديل اللغة عبر عنوان URL
|
|
@@ -575,219 +422,230 @@ const content = useIntlayer("about");
|
|
|
575
422
|
- إدارة ملفات تعريف الارتباط الخاصة باللغة
|
|
576
423
|
- إعادة توجيه المستخدمين إلى عنوان URL المحلي المناسب
|
|
577
424
|
|
|
578
|
-
### (اختياري) الخطوة 8: إنشاء مكون رابط محلي
|
|
579
|
-
|
|
580
|
-
لضمان أن تنقل تطبيقك يحترم اللغة الحالية، يمكنك إنشاء مكون مخصص باسم `LocalizedLink`. يقوم هذا المكون تلقائيًا بإضافة بادئة اللغة الحالية إلى عناوين URL الداخلية.
|
|
425
|
+
### (اختياري) الخطوة 8: إنشاء مكون رابط محلي اللغة
|
|
581
426
|
|
|
582
|
-
|
|
583
|
-
<template>
|
|
584
|
-
<NuxtLink :to="localizedHref" v-bind="$attrs">
|
|
585
|
-
<slot />
|
|
586
|
-
</NuxtLink>
|
|
587
|
-
</template>
|
|
427
|
+
لضمان أن تنقل تطبيقك يحترم اللغة الحالية، يمكنك إنشاء مكون مخصص `Links`. يقوم هذا المكون تلقائيًا بإضافة بادئة للروابط الداخلية باستخدام اللغة الحالية، وهو أمر ضروري لـ **تحسين محركات البحث (SEO) وقابلية اكتشاف الصفحات**.
|
|
588
428
|
|
|
429
|
+
```vue fileName="components/Links.vue"
|
|
589
430
|
<script setup lang="ts">
|
|
590
|
-
import { computed } from "vue";
|
|
591
431
|
import { getLocalizedUrl } from "intlayer";
|
|
592
432
|
import { useLocale } from "vue-intlayer";
|
|
593
433
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
},
|
|
599
|
-
});
|
|
434
|
+
interface Props {
|
|
435
|
+
href: string;
|
|
436
|
+
locale?: string;
|
|
437
|
+
}
|
|
600
438
|
|
|
601
|
-
const
|
|
439
|
+
const props = defineProps<Props>();
|
|
602
440
|
|
|
603
|
-
|
|
604
|
-
const isExternalLink = computed(() => /^https?:\/\//.test(props.to || ""));
|
|
441
|
+
const { locale: currentLocale } = useLocale();
|
|
605
442
|
|
|
606
|
-
//
|
|
607
|
-
const
|
|
608
|
-
|
|
609
|
-
);
|
|
443
|
+
// حساب المسار النهائي
|
|
444
|
+
const finalPath = computed(() => {
|
|
445
|
+
// 1. التحقق مما إذا كانت الرابط خارجي
|
|
446
|
+
const isExternal = /^https?:\/\//.test(props.href || "");
|
|
447
|
+
|
|
448
|
+
// 2. إذا كان خارجيًا، إرجاعه كما هو (NuxtLink يتولى توليد وسم <a>)
|
|
449
|
+
if (isExternal) return props.href;
|
|
450
|
+
|
|
451
|
+
// 3. إذا كان الرابط داخليًا، قم بتعريب الـ URL
|
|
452
|
+
const targetLocale = props.locale || currentLocale.value;
|
|
453
|
+
return getLocalizedUrl(props.href, targetLocale);
|
|
454
|
+
});
|
|
610
455
|
</script>
|
|
456
|
+
|
|
457
|
+
<template>
|
|
458
|
+
<NuxtLink :to="finalPath" v-bind="$attrs">
|
|
459
|
+
<slot />
|
|
460
|
+
</NuxtLink>
|
|
461
|
+
</template>
|
|
611
462
|
```
|
|
612
463
|
|
|
613
464
|
ثم استخدم هذا المكون في جميع أنحاء تطبيقك:
|
|
614
465
|
|
|
615
|
-
```vue fileName="
|
|
466
|
+
```vue fileName="layouts/default.vue"
|
|
467
|
+
<script setup lang="ts">
|
|
468
|
+
import Links from "~/components/Links.vue";
|
|
469
|
+
import LocaleSwitcher from "~/components/LocaleSwitcher.vue";
|
|
470
|
+
</script>
|
|
471
|
+
|
|
616
472
|
<template>
|
|
617
473
|
<div>
|
|
618
|
-
<
|
|
619
|
-
|
|
620
|
-
</
|
|
621
|
-
<
|
|
622
|
-
|
|
623
|
-
</
|
|
474
|
+
<header>
|
|
475
|
+
<LocaleSwitcher />
|
|
476
|
+
</header>
|
|
477
|
+
<main>
|
|
478
|
+
<slot />
|
|
479
|
+
</main>
|
|
480
|
+
|
|
481
|
+
<Links href="/">الرئيسية</Links>
|
|
482
|
+
<Links href="/about">حول</Links>
|
|
624
483
|
</div>
|
|
625
484
|
</template>
|
|
626
|
-
|
|
627
|
-
<script setup lang="ts">
|
|
628
|
-
import { useIntlayer } from "vue-intlayer";
|
|
629
|
-
import LocalizedLink from "~/components/LocalizedLink.vue";
|
|
630
|
-
|
|
631
|
-
const content = useIntlayer("home");
|
|
632
|
-
</script>
|
|
633
485
|
```
|
|
634
486
|
|
|
487
|
+
> باستخدام `NuxtLink` مع المسارات المترجمة، تضمن أن:
|
|
488
|
+
>
|
|
489
|
+
> - محركات البحث يمكنها الزحف وفهرسة جميع إصدارات لغات صفحاتك
|
|
490
|
+
> - يمكن للمستخدمين مشاركة عناوين URL المترجمة مباشرة
|
|
491
|
+
> - يعمل سجل المتصفح بشكل صحيح مع عناوين URL التي تحتوي على بادئة اللغة
|
|
492
|
+
|
|
635
493
|
### (اختياري) الخطوة 9: التعامل مع البيانات الوصفية وتحسين محركات البحث (SEO)
|
|
636
494
|
|
|
637
|
-
يوفر Nuxt قدرات ممتازة لتحسين محركات
|
|
495
|
+
يوفر Nuxt قدرات ممتازة لتحسين محركات البحث عبر الـ `useHead` composable (يتم استيراده تلقائيًا). يمكنك استخدام Intlayer للتعامل مع البيانات الوصفية المترجمة باستخدام accessor `.raw` أو `.value` للحصول على القيمة النصية الأولية:
|
|
638
496
|
|
|
639
497
|
```vue fileName="pages/about.vue"
|
|
640
498
|
<script setup lang="ts">
|
|
641
|
-
import {
|
|
642
|
-
import { getIntlayer } from "intlayer";
|
|
643
|
-
import { useLocale } from "vue-intlayer";
|
|
499
|
+
import { useIntlayer } from "vue-intlayer";
|
|
644
500
|
|
|
645
|
-
|
|
646
|
-
const content =
|
|
501
|
+
// يتم استيراد useHead تلقائيًا في Nuxt
|
|
502
|
+
const content = useIntlayer("about-page");
|
|
647
503
|
|
|
648
|
-
|
|
649
|
-
title: content.
|
|
650
|
-
|
|
504
|
+
useHead({
|
|
505
|
+
title: content.metaTitle.raw, // استخدم .raw للوصول إلى القيمة النصية الأولية
|
|
506
|
+
meta: [
|
|
507
|
+
{
|
|
508
|
+
name: "description",
|
|
509
|
+
content: content.metaDescription.raw, // استخدم .raw للوصول إلى القيمة النصية الأولية
|
|
510
|
+
},
|
|
511
|
+
],
|
|
651
512
|
});
|
|
652
513
|
</script>
|
|
653
514
|
|
|
654
515
|
<template>
|
|
655
|
-
<
|
|
656
|
-
<h1>{{ content.pageTitle }}</h1>
|
|
657
|
-
<p>{{ content.pageContent }}</p>
|
|
658
|
-
</div>
|
|
516
|
+
<h1><content.title /></h1>
|
|
659
517
|
</template>
|
|
660
518
|
```
|
|
661
519
|
|
|
662
|
-
|
|
520
|
+
> بدلاً من ذلك، يمكنك استخدام الدالة `import { getIntlayer } from "intlayer"` للحصول على المحتوى بدون تفاعل Vue.
|
|
521
|
+
|
|
522
|
+
> **الوصول إلى قيم المحتوى:**
|
|
523
|
+
>
|
|
524
|
+
> - استخدم `.raw` للحصول على القيمة النصية الأولية (غير تفاعلية)
|
|
525
|
+
> - استخدم `.value` للحصول على القيمة التفاعلية
|
|
526
|
+
> - استخدم بناء جملة المكون `<content.key />` لدعم محرر المرئيات
|
|
663
527
|
|
|
664
|
-
|
|
528
|
+
قم بإنشاء إعلان المحتوى المقابل:
|
|
529
|
+
|
|
530
|
+
```ts fileName="pages/about-page.content.ts" contentDeclarationFormat="typescript"
|
|
665
531
|
import { t, type Dictionary } from "intlayer";
|
|
666
|
-
import type { useSeoMeta } from "nuxt/app";
|
|
667
532
|
|
|
668
|
-
const
|
|
669
|
-
key: "about-
|
|
533
|
+
const aboutPageContent = {
|
|
534
|
+
key: "about-page",
|
|
670
535
|
content: {
|
|
671
|
-
|
|
672
|
-
ar: "معلومات عنا - شركتي",
|
|
536
|
+
metaTitle: t({
|
|
673
537
|
en: "About Us - My Company",
|
|
674
538
|
fr: "À Propos - Ma Société",
|
|
675
539
|
es: "Acerca de Nosotros - Mi Empresa",
|
|
540
|
+
ar: "معلومات عنا - شركتي",
|
|
676
541
|
}),
|
|
677
|
-
|
|
678
|
-
ar: "تعرف على المزيد عن شركتنا ورسالتنا",
|
|
542
|
+
metaDescription: t({
|
|
679
543
|
en: "Learn more about our company and our mission",
|
|
680
544
|
fr: "En savoir plus sur notre société et notre mission",
|
|
681
545
|
es: "Conozca más sobre nuestra empresa y nuestra misión",
|
|
546
|
+
ar: "تعرف أكثر على شركتنا ومهمتنا",
|
|
547
|
+
}),
|
|
548
|
+
title: t({
|
|
549
|
+
en: "About Us",
|
|
550
|
+
fr: "À Propos",
|
|
551
|
+
es: "Acerca de Nosotros",
|
|
552
|
+
ar: "معلومات عنا",
|
|
682
553
|
}),
|
|
683
554
|
},
|
|
684
|
-
} satisfies Dictionary
|
|
555
|
+
} satisfies Dictionary;
|
|
685
556
|
|
|
686
|
-
export default
|
|
557
|
+
export default aboutPageContent;
|
|
687
558
|
```
|
|
688
559
|
|
|
689
|
-
```
|
|
560
|
+
```javascript fileName="pages/about-page.content.mjs" contentDeclarationFormat="esm"
|
|
690
561
|
import { t } from "intlayer";
|
|
691
562
|
|
|
692
563
|
/** @type {import('intlayer').Dictionary} */
|
|
693
|
-
const
|
|
694
|
-
key: "about-
|
|
564
|
+
const aboutPageContent = {
|
|
565
|
+
key: "about-page",
|
|
695
566
|
content: {
|
|
696
|
-
|
|
697
|
-
zh: "关于我们 - 我的公司",
|
|
698
|
-
ar: "معلومات عنا - شركتي",
|
|
567
|
+
metaTitle: t({
|
|
699
568
|
en: "About Us - My Company",
|
|
700
569
|
fr: "À Propos - Ma Société",
|
|
701
570
|
es: "Acerca de Nosotros - Mi Empresa",
|
|
702
571
|
}),
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
ar: "تعرف على المزيد عن شركتنا ورسالتنا",
|
|
706
|
-
en: "Learn more about our company and our mission",
|
|
572
|
+
metaDescription: t({
|
|
573
|
+
en: "تعرف أكثر على شركتنا ومهمتنا",
|
|
707
574
|
fr: "En savoir plus sur notre société et notre mission",
|
|
708
575
|
es: "Conozca más sobre nuestra empresa y nuestra misión",
|
|
709
576
|
}),
|
|
577
|
+
title: t({
|
|
578
|
+
en: "معلومات عنا",
|
|
579
|
+
fr: "À Propos",
|
|
580
|
+
es: "Acerca de Nosotros",
|
|
581
|
+
}),
|
|
710
582
|
},
|
|
711
583
|
};
|
|
712
584
|
|
|
713
|
-
export default
|
|
585
|
+
export default aboutPageContent;
|
|
714
586
|
```
|
|
715
587
|
|
|
716
|
-
```
|
|
588
|
+
```javascript fileName="pages/about-page.content.cjs" contentDeclarationFormat="commonjs"
|
|
717
589
|
const { t } = require("intlayer");
|
|
718
590
|
|
|
719
591
|
/** @type {import('intlayer').Dictionary} */
|
|
720
|
-
const
|
|
721
|
-
key: "about-
|
|
592
|
+
const aboutPageContent = {
|
|
593
|
+
key: "about-page",
|
|
722
594
|
content: {
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
ar: "معلومات عنا - شركتي",
|
|
726
|
-
en: "About Us - My Company",
|
|
595
|
+
metaTitle: t({
|
|
596
|
+
en: "معلومات عنا - شركتي",
|
|
727
597
|
fr: "À Propos - Ma Société",
|
|
728
598
|
es: "Acerca de Nosotros - Mi Empresa",
|
|
729
599
|
}),
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
ar: "تعرف أكثر على شركتنا ورسالتنا",
|
|
733
|
-
en: "Learn more about our company and our mission",
|
|
600
|
+
metaDescription: t({
|
|
601
|
+
en: "تعرف أكثر على شركتنا ورسالتنا",
|
|
734
602
|
fr: "En savoir plus sur notre société et notre mission",
|
|
735
603
|
es: "Conozca más sobre nuestra empresa y nuestra misión",
|
|
736
604
|
}),
|
|
605
|
+
title: t({
|
|
606
|
+
en: "معلومات عنا",
|
|
607
|
+
fr: "À Propos",
|
|
608
|
+
es: "Acerca de Nosotros",
|
|
609
|
+
}),
|
|
737
610
|
},
|
|
738
611
|
};
|
|
739
612
|
|
|
740
|
-
module.exports =
|
|
613
|
+
module.exports = aboutPageContent;
|
|
741
614
|
```
|
|
742
615
|
|
|
743
|
-
```json fileName="pages/about-
|
|
616
|
+
```json fileName="pages/about-page.content.json" contentDeclarationFormat="json"
|
|
744
617
|
{
|
|
745
|
-
"
|
|
618
|
+
"$schema": "https://intlayer.org/schema.json",
|
|
619
|
+
"key": "about-page",
|
|
746
620
|
"content": {
|
|
747
|
-
"
|
|
621
|
+
"metaTitle": {
|
|
748
622
|
"nodeType": "translation",
|
|
749
|
-
"
|
|
750
|
-
"
|
|
751
|
-
"ar": "معلومات عنا - شركتي",
|
|
752
|
-
"en": "About Us - My Company",
|
|
623
|
+
"translation": {
|
|
624
|
+
"en": "معلومات عنا - شركتي",
|
|
753
625
|
"fr": "À Propos - Ma Société",
|
|
754
626
|
"es": "Acerca de Nosotros - Mi Empresa"
|
|
755
627
|
}
|
|
756
628
|
},
|
|
757
|
-
"
|
|
629
|
+
"metaDescription": {
|
|
758
630
|
"nodeType": "translation",
|
|
759
|
-
"
|
|
760
|
-
"
|
|
761
|
-
"ar": "تعرف على المزيد حول شركتنا ورسالتنا",
|
|
762
|
-
"en": "Learn more about our company and our mission",
|
|
631
|
+
"translation": {
|
|
632
|
+
"en": "تعرف أكثر على شركتنا ورسالتنا",
|
|
763
633
|
"fr": "En savoir plus sur notre société et notre mission",
|
|
764
634
|
"es": "Conozca más sobre nuestra empresa y nuestra misión"
|
|
765
635
|
}
|
|
636
|
+
},
|
|
637
|
+
"title": {
|
|
638
|
+
"nodeType": "translation",
|
|
639
|
+
"translation": {
|
|
640
|
+
"en": "معلومات عنا",
|
|
641
|
+
"fr": "À Propos",
|
|
642
|
+
"es": "Acerca de Nosotros"
|
|
643
|
+
}
|
|
766
644
|
}
|
|
767
645
|
}
|
|
768
646
|
}
|
|
769
647
|
```
|
|
770
648
|
|
|
771
|
-
### تكوين TypeScript
|
|
772
|
-
|
|
773
|
-
يستخدم Intlayer تعزيز الوحدات (module augmentation) للاستفادة من TypeScript وجعل قاعدة الشيفرة الخاصة بك أقوى.
|
|
774
|
-
|
|
775
|
-

|
|
776
|
-
|
|
777
|
-

|
|
778
|
-
|
|
779
|
-
تأكد من أن تكوين TypeScript الخاص بك يتضمن الأنواع التي تم إنشاؤها تلقائيًا.
|
|
780
|
-
|
|
781
|
-
```json5 fileName="tsconfig.json"
|
|
782
|
-
{
|
|
783
|
-
// ... تكوينات TypeScript الحالية الخاصة بك
|
|
784
|
-
"include": [
|
|
785
|
-
// ... تكوينات TypeScript الحالية الخاصة بك
|
|
786
|
-
".intlayer/**/*.ts", // تضمين الأنواع التي تم إنشاؤها تلقائيًا
|
|
787
|
-
],
|
|
788
|
-
}
|
|
789
|
-
```
|
|
790
|
-
|
|
791
649
|
### تكوين Git
|
|
792
650
|
|
|
793
651
|
يوصى بتجاهل الملفات التي يتم إنشاؤها بواسطة Intlayer. هذا يسمح لك بتجنب الالتزام بها في مستودع Git الخاص بك.
|
|
@@ -808,16 +666,14 @@ module.exports = aboutMetaContent;
|
|
|
808
666
|
يوفر هذا الامتداد:
|
|
809
667
|
|
|
810
668
|
- **الإكمال التلقائي** لمفاتيح الترجمة.
|
|
811
|
-
- **الكشف عن
|
|
812
|
-
- **معاينات
|
|
813
|
-
- **إجراءات سريعة** لإنشاء الترجمات
|
|
669
|
+
- **الكشف الفوري عن الأخطاء** للترجمات المفقودة.
|
|
670
|
+
- **معاينات مدمجة** للمحتوى المترجم.
|
|
671
|
+
- **إجراءات سريعة** لإنشاء وتحديث الترجمات بسهولة.
|
|
814
672
|
|
|
815
|
-
لمزيد من التفاصيل حول كيفية استخدام
|
|
673
|
+
لمزيد من التفاصيل حول كيفية استخدام الامتداد، راجع [توثيق امتداد Intlayer لـ VS Code](https://intlayer.org/doc/vs-code-extension).
|
|
816
674
|
|
|
817
675
|
---
|
|
818
676
|
|
|
819
|
-
###
|
|
820
|
-
|
|
821
|
-
للتقدم أكثر، يمكنك تنفيذ [المحرر المرئي](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ar/intlayer_visual_editor.md) أو إخراج المحتوى الخاص بك باستخدام [نظام إدارة المحتوى (CMS)](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ar/intlayer_CMS.md).
|
|
677
|
+
### التعمق أكثر
|
|
822
678
|
|
|
823
|
-
|
|
679
|
+
للتقدم أكثر، يمكنك تنفيذ [المحرر المرئي](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ar/intlayer_visual_editor.md) أو تعريض محتواك باستخدام [نظام إدارة المحتوى (CMS)](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ar/intlayer_CMS.md).
|