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

|
|
776
662
|
|
|
777
|
-

|
|
778
664
|
|
|
779
665
|
تأكد من أن تكوين TypeScript الخاص بك يتضمن الأنواع التي تم إنشاؤها تلقائيًا.
|
|
780
666
|
|
|
@@ -808,16 +694,14 @@ module.exports = aboutMetaContent;
|
|
|
808
694
|
يوفر هذا الامتداد:
|
|
809
695
|
|
|
810
696
|
- **الإكمال التلقائي** لمفاتيح الترجمة.
|
|
811
|
-
- **الكشف عن
|
|
812
|
-
- **معاينات
|
|
813
|
-
- **إجراءات سريعة** لإنشاء الترجمات
|
|
697
|
+
- **الكشف الفوري عن الأخطاء** للترجمات المفقودة.
|
|
698
|
+
- **معاينات مدمجة** للمحتوى المترجم.
|
|
699
|
+
- **إجراءات سريعة** لإنشاء وتحديث الترجمات بسهولة.
|
|
814
700
|
|
|
815
|
-
لمزيد من التفاصيل حول كيفية استخدام
|
|
701
|
+
لمزيد من التفاصيل حول كيفية استخدام الامتداد، راجع [توثيق امتداد Intlayer لـ VS Code](https://intlayer.org/doc/vs-code-extension).
|
|
816
702
|
|
|
817
703
|
---
|
|
818
704
|
|
|
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).
|
|
705
|
+
### التعمق أكثر
|
|
822
706
|
|
|
823
|
-
|
|
707
|
+
للتقدم أكثر، يمكنك تنفيذ [المحرر المرئي](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).
|