تحسين محركات البحث في Angular
كيفية جعل تطبيقات Angular قابلة للزحف والفهرسة — مقارنة @angular/ssr بالتصيير المسبق والتصيير الهجين، وhydration، وخدمتي Title وMeta، وتوجيه History API، واختبار ما يصيّره Googlebot فعلًا.
اللغات
تحسين محركات البحث في Angular هو قرار واحد أساسًا: أرسل HTML حقيقيًا بدل shell مصيَّر من جهة العميل. يدمج Angular الحديث (v17+) SSR في CLI عبر @angular/ssr — صَيِّر المسارات الثابتة مسبقًا، والمسارات الديناميكية من الخادم، واستخدم hydration كي لا يُهدر HTML. ثم طبّق الأساسيات: عناوين وأوصاف فريدة عبر خدمتي Title وMeta في Angular، وتوجيه HTML5 History (من دون عناوين hash)، وروابط <a href> حقيقية، وتحقق باستخدام URL Inspection. التصيير الديناميكي حل التفافي لا استراتيجية — وAngularJS إطار مختلف.
الخلاصة — يبني Angular الصفحة في المتصفح باستخدام JavaScript افتراضيًا، لذلك يكون HTML الخام الذي يراه محرك البحث أولًا شبه فارغ. والحل هو إرسال HTML حقيقي مكتمل — باستخدام التصيير من جانب الخادم المدمج في Angular (
@angular/ssr) أو التصيير المسبق. ثم عالج الأساسيات: عنوان ووصف فريدان لكل صفحة، وعناوين URL نظيفة (بلا#)، وروابط حقيقية من نوع<a href>.
المشكلة في جملة واحدة
يرسل تطبيق Angular الافتراضي إلى المتصفح غلاف HTML صغيرًا — وهو عمليًا <div> فارغ — مع حزمة JavaScript كبيرة. يشغّل المتصفح JavaScript، ثم تمتلئ الصفحة بالمحتوى. وهذا ما يسمى التصيير من جانب العميل (CSR).
المشكلة أن محرك البحث عندما ينزّل عنوان URL لأول مرة يرى الغلاف الفارغ. تستطيع Google تشغيل JavaScript لرؤية المحتوى الحقيقي، لكنها تفعل ذلك لاحقًا في خطوة منفصلة، وليس دائمًا بصورة موثوقة. Evidence for this claim Google can render JavaScript but processes rendering as a stage after crawling. Scope: Google Search rendering; other crawler behavior is not covered by this record. Confidence: high · Verified: Google: JavaScript SEO basics أما برامج الزحف الأخرى — Bing والروبوتات التي تقف خلف معاينات الشبكات الاجتماعية — فكثيرًا ما لا تستطيع تشغيل JavaScript أصلًا. لذلك لا ترى شيئًا.
الحل: أرسل HTML مكتملًا
بدل أن تجعل المتصفح (أو برنامج الزحف) يبني الصفحة، ابنها مسبقًا أو على خادم وأرسل HTML كاملًا. يمنحك Angular طريقتين أساسيتين:
- التصيير من جانب الخادم (SSR) — يشغّل خادم Angular عند كل طلب ويرسل الصفحة الكاملة. مناسب للمحتوى الذي يتغير كثيرًا. Evidence for this claim Angular supports server-side rendering and build-time prerendering through its SSR tooling. Scope: Current Angular SSR and prerender features. Confidence: high · Verified: Angular: Server-side and hybrid rendering
- التصيير المسبق — يبني Angular ملفات HTML ثابتة لصفحاتك وقت البناء، فلا تحتاج إلى خادم. وهو الخيار الأسرع، وممتاز لمقالات المدونة وصفحات التسويق.
يبني Angular الحديث (الإصدار 17 وما بعده) الطريقتين داخل حزمة الأدوات نفسها. أضفهما بأمر واحد: ng add @angular/ssr. وربما سمعت الاسم القديم Angular Universal — فقد كانت الفكرة نفسها كإضافة منفصلة. أدمج Angular هذه الوظيفة في النواة في v17 وأعاد تسميتها.
الأساسيات الأخرى
- امنح كل صفحة عنوانًا ووصفًا فريدين. لن يفعل Angular ذلك نيابةً عنك — اضبطهما في الكود باستخدام خدمتي
TitleوMetaالمدمجتين. ومن دون ذلك تشترك كل صفحة في عنوان واحد. - استخدم عناوين URL نظيفة، لا عناوين hash. ينشئ التوجيه الافتراضي في Angular عناوين جميلة مثل
/products/shoes. تجنب النمط الأقدم ذي «الهاش» (/#/products) — فلا تستطيع محركات البحث التعامل بصورة موثوقة مع الجزء الواقع بعد#. - استخدم روابط حقيقية. يجب أن يكون التنقل روابط
<a href>حقيقية، لا أزرارًا أو معالجات نقر، وإلا فلن تستطيع Google اتباعها.
الخطأ الأكبر الذي يرتكبه معظم الناس
«لا تستطيع Google فهرسة Angular» خرافة — فهي تستطيع تصيير JavaScript. لكنه أبطأ وأقل موثوقية من إرسال HTML حقيقي فحسب، كما أن برامج الزحف غير التابعة لـGoogle لا تستطيع ذلك أصلًا. لذلك صير على الخادم أو صير مسبقًا أي شيء تريد العثور عليه.
هل تريد النسخة الأعمق — التصيير الهجين لكل مسار، والترطيب، وخدمات SEO مع الكود، وكيف تختبر ما تراه Google فعلًا؟ انتقل إلى علامة التبويب المتقدمة.
Evidence for this claim Modern Angular documents @angular/ssr as its server-side and hybrid rendering package. Scope: Current Angular documentation; historical Angular Universal details are not required for this claim. Confidence: high · Verified: Angular: Server-side and hybrid renderingالخلاصة — Angular SEO قرار معماري واحد يرتدي قبعات كثيرة: أدخل HTML حقيقيًا في الاستجابة بدل غلاف مصير على العميل. يدمج Angular الحديث (v17+) SSR في CLI بوصفه
@angular/ssr(الخليفة المعاد تسميته والمدمج لـAngular Universal). صير المسارات الثابتة مسبقًا، وصير الديناميكية على الخادم، وامزج بينها بالتصيير الهجين، ثم رطّب الصفحة كي يُعاد استخدام HTML الخادم لا بناؤه من جديد. وبعد ذلك عالج الأساسيات: عناوين/أوصاف فريدة عبر خدمتيTitle/Meta(أوTitleStrategyفي الموجّه)، وتوجيه HTML5 History — لا تستخدمHashLocationStrategyمطلقًا — وروابط حقيقية من نوع<a href>، وJSON-LD يحقن بأمان، والتحقق عبر URL Inspection. والتصيير الديناميكي حل التفافي تقر به Google، لا استراتيجية.
المشكلة في الإعداد الافتراضي: التصيير من جانب العميل
يأتي بناء Angular الجاهز بملف index.html يحتوي جسمه عمليًا على <app-root></app-root> مع وسوم script. ومن دون تنفيذ JavaScript لا يرى برنامج الزحف عناوين أو نصًا أو روابط — إذ يتجمع المحتوى في المتصفح بعد تحميل الحزمة. وهذه هي المشكلة الأساسية نفسها التي أصفها في JavaScript SEO: انتقل الويب بعيدًا عن HTML البسيط، وCSR هو الطرف الأكثر مخاطرة من ذلك الطيف.
(تعكس تفاصيل التطبيق في هذا الدليل — واجهات RenderMode ومرشحات hydrate وإعادة الأحداث — Angular v22. والميزات الخاصة بالإصدارات أدناه مؤرخة: إعادة تسمية SSR في v17، وإعادة الأحداث في v18، والترطيب التدريجي في v19–v20.)
ينشئ CSR ثلاث مشكلات SEO متميزة:
- فهرسة متأخرة وأقل موثوقية. تعالج Google تطبيقات JS في ثلاث مراحل — “Crawling, Rendering, and Indexing” (ترجمة) «الزحف والتصيير والفهرسة» — ويؤجل التصيير إلى قائمة انتظار. ولا يصبح محتواك موجودًا للفهرسة حتى تنفذ تلك المرحلة.
- Core Web Vitals أسوأ. يتضرر LCP لأن المتصفح يجب أن ينزل حزمة قبل رسم محتوى ذي معنى وينفذها.
- ترى برامج الزحف غير التابعة لـGoogle الغلاف. فـBingbot أقل اتساقًا بكثير في تصيير JS، وبرامج زحف معاينات الشبكات الاجتماعية/الروابط لا تصير عادةً على الإطلاق — لذلك لا تصل وسوم Open Graph والمحتوى المحقون من جانب العميل إليها.
كيف يتعامل Googlebot فعلًا مع تطبيق Angular؟
Googlebot دائم التجدد — فهو يصير باستخدام إصدار حالي من محرك V8 في Chrome ويتحدث مع إصدارات Chrome. Evidence for this claim Googlebot uses an evergreen version of Chromium for rendering. Scope: Google Search rendering engine; this does not remove application-level rendering risks. Confidence: high · Verified: Google: Evergreen Googlebot لذلك يستطيع تشغيل Angular. لكن لسلوكه حدودًا صلبة يجدر أن تصمم حولها:
- التصيير موضوع في قائمة انتظار، لا فوري. توثق Google مراحل الزحف والتصيير والفهرسة المنفصلة، ولا تنشر جدولًا ثابتًا للمدة التي يحتاجها التصيير ليلحق بالزحف. والاختصار المتداول لهذا هو «موجتان» — يفهرس HTML الخام أولًا (غلاف فارغ في CSR Angular)، ثم يفهرس DOM المصيّر لاحقًا عندما تنفذ تلك المرحلة. يتجاوز SSR/التصيير المسبق الانتظار: يكون HTML كاملًا عند الجلب الأول، فلا توجد مرحلة تصيير منفصلة تنتظرها تلك المادة.
- المصيّر عديم الحالة. لا ملفات تعريف ارتباط ولا
localStorageولاsessionStorageتنتقل بين عمليات التحميل؛ ويرفض مطالبات الأذونات. لا تجعل المحتوى مشروطًا بحالة العميل. - لا ينقر ولا يمرر الصفحة، ويصير عند نافذة عرض عالية جدًا. ولن يرى المحتوى الموجود خلف تفاعل.
- تُخزن الموارد مؤقتًا بشدة — استخدم أسماء ملفات تحمل بصمة المحتوى (مثل
main.<hash>.jsالافتراضي في Angular) حتى لا تُقدم حزم محدثة قديمة.
@angular/ssr — ماهيته وتاريخ التسمية
يشغّل التصيير من جانب الخادم Angular على خادم Node عند كل طلب ويعيد HTML مصيرًا بالكامل، ثم يرطّبه المتصفح (يربط معالجات الأحداث بـDOM الموجود بدل إعادة التصيير). ويحصل كل برنامج زحف — Googlebot وBingbot والروبوتات الاجتماعية — على HTML كامل من الطلب الأول، من دون الحاجة إلى موجة ثانية.
تسبب التسمية ارتباكًا، لذلك كن دقيقًا: كان Angular Universal حل SSR التاريخي، يُشحن كحزمة خارجية (@nguniversal/express-engine). ومع Angular v17 (نوفمبر 2023) دُمج SSR مباشرةً في Angular CLI وApplication Builder وأعيدت تسميته @angular/ssr؛ ومستودع Angular Universal الآن في وضع الصيانة. Evidence for this claim Modern Angular documents @angular/ssr as its server-side and hybrid rendering package. Scope: Current Angular documentation; historical Angular Universal details are not required for this claim. Confidence: high · Verified: Angular: Server-side and hybrid rendering والإعداد الآن أمر واحد:
# New project with SSR enabled
ng new my-app --ssr
# Add SSR to an existing project
ng add @angular/ssrهذا يستبدل ng add @nguniversal/express-engine القديم. الفكرة نفسها، لكن الأدوات أصبحت من الدرجة الأولى.
التصيير المسبق (التوليد الثابت / SSG)
ينشئ التصيير المسبق HTML ثابتًا للمسارات وقت البناء، فلا يعمل خادم وقت الطلب — ويمكنك النشر على CDN. ويمنح أسرع TTFB/FCP/LCP وأقل كلفة تشغيلية. وفي v17+ تضبطه لكل مسار عبر ملف مسارات خادم (app.routes.server.ts) باستخدام RenderMode.Prerender، وينتج outputMode: 'static' تطبيقًا ثابتًا بالكامل.
القيد هو أن البيانات يجب أن تكون متاحة وقت البناء، ولا يوجد محتوى لكل مستخدم، كما تعني المواقع الكبيرة جدًا عمليات بناء بطيئة. وهو مثالي لصفحات التسويق والوثائق ومقالات المدونة — أي المحتوى الذي يحتاج أكثر من غيره إلى الترتيب والاستشهاد.
التصيير الهجين — اختر نمطًا لكل مسار
أكبر تقدم منذ v17+ هو أن نمط التصيير قرار لكل مسار، تضبطه في app.routes.server.ts:
RenderMode.Prerender— مسارات ثابتة (الرئيسية، وعن، ومقالات المدونة).RenderMode.Server— مسارات ديناميكية لكل طلب (نتائج البحث ولوحات البيانات ذات البيانات الجديدة).RenderMode.Client— مسارات داخلية فقط لا تريد فهرستها أصلًا (واجهات الإدارة والشاشات التي تتطلب تسجيل الدخول). ويكون CSR مناسبًا فعلًا هنا.
هذه قاعدة القرار عمليًا: صير مسبقًا ما هو ثابت، وصير على الخادم ما يجب أن يكون جديدًا، ولا تعد إلى التصيير من جانب العميل إلا فيما ينبغي ألا يدخل الفهرس.
الترطيب — والمطب الذي يحطم CLS
في SSR الساذج عيب: يرسل الخادم HTML، ثم يرميه المتصفح ويعيد التصيير من الصفر، مما يسبب وميضًا وعملًا مهدورًا. ويصلح الترطيب ذلك — إذ يستعيد المتصفح التطبيق المصير من الخادم ويعيد استخدام DOM المطابق بدل هدمه وإعادة إنشائه، ولا يضيف إلا التفاعلية. فعّله في app.config.ts:
provideClientHydration()المتطلب السابق: الترطيب رفيق من جانب العميل لـSSR، وليس مفتاحًا مستقلًا. لا تفعل provideClientHydration() شيئًا إلا على مسار مصير على الخادم (أو مصير مسبقًا) بالفعل — ولا تستطيع تحويل غلاف مسار RenderMode.Client إلى HTML خادم. فعّل SSR/التصيير المسبق للمسار أولًا.
توجد قدرتان أحدث مهمتان لتجربة المستخدم المجاورة لـSEO — ولا تغير أي منهما فهرسة البحث:
- إعادة الأحداث (v18+): تلتقط تفاعلات المستخدم المدعومة التي تحدث قبل انتهاء الترطيب، ثم تعيدها بعد اكتماله. وتقلل النقرات المفقودة لأنواع التفاعل التي تدعمها؛ وهي ميزة UX/تفاعلية لا SEO، ولا تؤثر في ما تفهرسه Google.
- الترطيب التدريجي (معاينة مطور في v19، مستقر في v20): يعتمد معًا على SSR والترطيب والعروض القابلة للتأجيل وإعادة الأحداث — وليس ميزة مستقلة. وتدعمه كتل
@deferذات محفزات ترطيب تتحكم في الحدود التي تبقى غير مرطبة عند التصيير الأولي؛ وتبقى حدودhydrate neverغير مرطبة عند التحميل الأول، لكنها لا تُمنع بالضرورة من تحميل تبعياتها في تصييرات العميل اللاحقة (مثل تغيير المسار). وأثره المتعلق بـSEO غير مباشر: قد يساعد ترطيب JavaScript أقل في البداية LCP، لكن إعداد المحفز تفصيل تصيير لا آلية توقيت للزحف.
المطب الحرج: يؤدي وضع @if (isPlatformBrowser(...)) مباشرةً في القالب إلى جعل الخادم والعميل يصيران ترميزًا مختلفًا — أي عدم تطابق في الترطيب — مما ينتج تحركًا في التخطيط ويضر CLS. استخدم afterNextRender() للعمل الخاص بالمتصفح بدل تفرع القالب حسب المنصة.
العناوين ووسوم meta — خدمات Angular المدمجة
لا يستطيع Angular ربط النص داخل عنصر <title> مباشرةً، لذلك تدير وسوم الرأس عبر خدمتين من @angular/platform-browser:
Title—setTitle()/getTitle().Meta—addTag()وaddTags()وupdateTag()وgetTag()وremoveTag()، مع محددات مثلname='description'أوproperty='og:title'.
لا تحتاج إلى مكتبة خارجية للأساسيات. وخدمة SEO مشتركة هي النمط الأنظف:
@Injectable({ providedIn: 'root' })
export class SeoService {
private title = inject(Title);
private meta = inject(Meta);
updatePage(title: string, description: string) {
this.title.setTitle(title);
this.meta.updateTag({ name: 'description', content: description });
this.meta.updateTag({ property: 'og:title', content: title });
}
}للعناوين تحديدًا، يتيح TitleStrategy في الموجّه (Angular v14+) ضبط title مباشرةً في إعداد المسار، فيُحدّث عنوان الصفحة تلقائيًا عند التنقل — من دون كود لكل مكوّن. ولا تضبط document.title = ... يدويًا؛ استخدم خدمة Title كي تعمل بصورة صحيحة تحت SSR.
بنية عناوين URL
- استخدم توجيه HTML5 History API الافتراضي (
PathLocationStrategy) — عناوين نظيفة مثل/products/shoes. ويحتاج إلى<base href="/">فيindex.html. - لا تستخدم
HashLocationStrategy/useHash: trueللمحتوى العام. تُزال معرفات الأجزاء بعد#قبل طلب HTTP، فلا يراها الخادم ولا يستطيع Googlebot حل#/productsبصورة موثوقة — وقد ينهار موقعك كله إلى عنوان URL واحد. - استخدم روابط
<a href>حقيقية للتنقل، بما فيها المسارات المحملة كسولًا. التحميل الكسول جيد للأداء، لكن الروابط إلى تلك المسارات يجب أن تبقى مراسي قابلة للزحف، لا معالجات نقر.
البيانات المنظمة (JSON-LD)
تدعم Google حقن JSON-LD باستخدام JavaScript. والنمط المتين في Angular هو خدمة تنشئ <script type="application/ld+json"> وتضيفه إلى document.head، باستخدام رمز حقن Angular DOCUMENT بدل لمس document عالميًا (مما يكسر العمل على الخادم). أبقِ كل schema في مكان واحد — لا تقسّمه بين HTML الثابت وDOM المصير — وتحقق باستخدام اختبار النتائج الغنية وURL Inspection.
التصيير الديناميكي — حل التفافي قديم، لا خطة
يقدم التصيير الديناميكي نسخة مصيرة مسبقًا للروبوتات (عبر Puppeteer أو Rendertron أو prerender.io) وتطبيق SPA كاملًا للمستخدمين. وتوضح Google أن “dynamic rendering is a workaround and not a long-term solution,” (ترجمة) «التصيير الديناميكي حل التفافي وليس حلًا طويل الأمد»، وأن هناك “better solutions than dynamic rendering” (ترجمة) «حلولًا أفضل من التصيير الديناميكي» — وهي التصيير من جانب الخادم أو التصيير الثابت أو الترطيب. وهو ليس إخفاءً تلقائيًا ما دمت تقدم محتوى متشابهًا جوهريًا، لكنه يضيف خادم تصيير آخر، ويخاطر بانجراف المحتوى، ولا يفعل شيئًا لـCore Web Vitals لدى المستخدمين الحقيقيين. وفي بناء Angular جديد، استخدم @angular/ssr أو التصيير المسبق بدلًا منه.
أخطاء SEO الشائعة في Angular
- توجيه hash (عناوين
#) — يبدو الموقع كله عنوان URL واحدًا. - لا استدعاءات لـ
Title/Meta— تشترك كل صفحة في عنوان ووصف واحد. - لا SSR/تصيير مسبق — لا يوجد المحتوى إلا بعد موجة التصيير المؤجلة.
- حظر
.js/.cssفيrobots.txt— لا تستطيع Google التصيير وتفهرس غلافًا فارغًا. - إعادة
200في عرض غير موجود — خطأ 404 ناعم؛ أعد404حقيقيًا أو أضفnoindex. - استخدام
document.title = ...بدل خدمةTitle. - وضع
isPlatformBrowser()داخل@ifفي القالب — عدم تطابق الترطيب → CLS. - لمس
window/localStorage/documentفي كود يعمل على الخادم — تعطل SSR. - تقسيم schema بين HTML الخام وDOM المصير.
- الاختبار في التطوير المحلي بدل URL Inspection — اعتماد على الافتراضات لا Googlebot.
اختبار Angular من أجل SEO
- URL Inspection (Search Console) هو مصدر الحقيقة: يعرض منظور الصفحة التي زُحفت، أي HTML المصير — DOM بعد أن شغّل Googlebot JavaScript — وهو ما يُفهرس، إلى جانب رسائل وحدة JS والموارد المحجوبة. شغّل Live Test لتصيير عند الطلب.
- استخدم
curlلجلب عنوان URL لترى HTML الخام قبل JS — فالغلاف الفارغ يعني CSR بلا SSR. - اختبار النتائج الغنية يتحقق من البيانات المنظمة.
- Ahrefs Site Audit (مع تشغيل تصيير JS) وScreaming Frog (وضع JS) يقارنان DOM الخام بالمصير على نطاق واسع.
- Lighthouse / PageSpeed Insights لقياس أثر خيار التصيير في Core Web Vitals.
Angular ليس سيئًا لـSEO — بل مختلف. أدخل HTML حقيقيًا في الاستجابة، وأدر وسوم الرأس، وأبقِ عناوين URL والروابط قابلة للزحف، ودع أدوات Google نفسها تفصل في المخرج المصير. يقع هذا الموضوع إلى جانب JavaScript SEO وأسئلة تصيير CMS عديم الرأس في هذا العنقود — والدرس الأساسي واحد بينها جميعًا: نمط التصيير يقرر كل شيء تقريبًا.
ملخص بالذكاء الاصطناعي
خلاصة مكثفة للنسخة المتقدمة:
- الإعداد الافتراضي في Angular هو التصيير من جانب العميل (CSR) — غلاف HTML شبه فارغ. وهذا يعني فهرسة متأخرة/غير موثوقة، وLCP أسوأ، وبرامج الزحف غير التابعة لـGoogle (Bing والشبكات الاجتماعية) لا ترى شيئًا.
- Googlebot دائم التجدد ويصير JS، لكن التصيير موضوع في قائمة انتظار («موجتان» — HTML الخام أولًا وDOM المصير لاحقًا، بلا جدول ثابت)، وعديم الحالة (لا ملفات تعريف ارتباط/تخزين)، ولا ينقر/يمرر الصفحة، ويخزن الموارد بشدة. يتجاوز SSR/التصيير المسبق الانتظار — يكون HTML كاملًا عند الجلب الأول، فلا توجد مرحلة تصيير منفصلة تنتظرها.
@angular/ssrهو الإصلاح الحديث — SSR مدمج في Angular CLI منذ v17، مستبدلًا Angular Universal الذي كانت صيانته خارجية (@nguniversal/express-engine). الإعداد:ng new --ssrأوng add @angular/ssr.- التصيير المسبق (HTML ثابت وقت البناء) هو الأسرع والقابل للنشر على CDN — والأفضل لمحتوى التسويق/المدونة/الوثائق الثابت؛ لكنه محدود ببيانات وقت البناء.
- التصيير الهجين يضبط النمط لكل مسار في
app.routes.server.ts:RenderMode.Prerender(ثابت)، وRenderMode.Server(ديناميكي)، وRenderMode.Client(صفحات داخلية غير مفهرسة). - الترطيب (
provideClientHydration()) يعيد استخدام HTML الخادم في مسار مصير مسبقًا/على الخادم بالفعل — ولا ينشئ HTML خادم لمسار CSR. وتلتقط إعادة الأحداث (v18+) تفاعلات ما قبل الترطيب المدعومة وتعيدها بعده؛ ويعتمد الترطيب التدريجي (معاينة v19 / مستقر v20) على SSR + الترطيب + العروض القابلة للتأجيل + إعادة الأحداث معًا، باستخدام محفزات ترطيب@deferللتحكم في الحدود غير المرطبة عند التحميل الأولي (hydrate neverلا يمنع التحميل اللاحق من جانب العميل). ولا يغير أي منهما فهرسة البحث. تجنبisPlatformBrowser()في@ifالقالب — فهو يسبب عدم تطابق الترطيب → CLS؛ واستخدمafterNextRender(). - استخدم خدمتي
TitleوMetaالمدمجتين (لا مكتبة خارجية لازمة)؛ وتضبطTitleStrategyفي الموجّه (v14+) العناوين لكل مسار تلقائيًا. - استخدم توجيه HTML5 History، ولا تستخدم عناوين hash (
#)؛ ويجب أن يكون التنقل مراسي<a href>حقيقية. ويمكن حقن JSON-LD عبر رمزDOCUMENT. - التصيير الديناميكي حل التفافي لا استراتيجية — توصي Google بـSSR/التصيير الثابت/الترطيب بدلًا منه.
- اختبر عبر URL Inspection (HTML المصير) و
curl(HTML الخام) واختبار النتائج الغنية وبرنامج زحف يصير JS. وAngularJS ≠ Angular — لا تنطبق نصائح AngularJS القديمة.
الوثائق الرسمية
وثائق أولية من Google وAngular.
- فهم أساسيات JavaScript SEO — مراحل الزحف ← التصيير ← الفهرسة، وروابط
<a href>القابلة للزحف، وتحذيرات توجيه الأجزاء، وأخطاء «غير موجود» الناعمة، والبيانات المنظمة المحقونة بـJS. - التصيير الديناميكي (حل التفافي) — لماذا هو حل التفافي، ودقة الإخفاء، وبدائل SSR/التصيير الثابت/الترطيب.
- التصيير على الويب (web.dev — Addy Osmani وJason Miller) — تعريفات SSR وCSR والتصيير الثابت والترطيب ومقايضات الأداء.
- أداة URL Inspection — كيفية رؤية HTML المصير الذي تفهرسه Google فعلًا، ورسائل وحدة JS.
Angular
- Angular — التصيير من جانب الخادم والهجين (SSR) — دليل
@angular/ssrالرسمي ومسارات الخادم وRenderMode. - Angular — خدمة
Title—setTitle()/getTitle(). - Angular — خدمة
Meta—addTag()وupdateTag()والمحددات. - Angular — مرجع الموجّه —
PathLocationStrategyمقابل توجيه hash، وTitleStrategy. - تقديم Angular v17 (مدونة فريق Angular) — تحول SSR إلى ميزة CLI من الدرجة الأولى.
- Angular Universal (وضع الصيانة) — الحزمة التاريخية التي حلت محلها
@angular/ssr.
اقتباسات من المصدر
تصريحات مسجلة من Google ومن كتاباتي. كل رابط لمحرك بحث يقفز إلى المقطع المقتبس في صفحة المصدر.
Google — كيف تعالج تطبيقات JavaScript
- “Google processes JavaScript web apps in three main phases: 1. Crawling 2. Rendering 3. Indexing.” (ترجمة) «تعالج Google تطبيقات الويب التي تستخدم JavaScript في ثلاث مراحل رئيسية: 1. الزحف 2. التصيير 3. الفهرسة.» — وثائق Google Search Central. انتقل إلى الاقتباس
- “Google can only discover your links if they are <a> HTML elements with an href attribute.” (ترجمة) «لا تستطيع Google اكتشاف روابطك إلا إذا كانت عناصر HTML من نوع <a> ذات سمة href.» — وثائق Google Search Central. انتقل إلى الاقتباس
Google — التصيير الديناميكي حل التفافي
- “Dynamic rendering was a workaround and not a long-term solution for problems with JavaScript-generated content in search engines.” (ترجمة) «كان التصيير الديناميكي حلًا التفافيًا لا حلًا طويل الأمد لمشكلات المحتوى المنشأ بـJavaScript في محركات البحث.» — وثائق Google Search Central. انتقل إلى الاقتباس
web.dev — تفضيل SSR / التصيير الثابت (Addy Osmani وJason Miller)
- “Rendering an app on the server to send HTML, rather than JavaScript, to the client.” (ترجمة) «تصيير تطبيق على الخادم لإرسال HTML إلى العميل بدلًا من JavaScript.» — تعريف التصيير من جانب الخادم. انتقل إلى الاقتباس
Patrick Stox (من عملي — JavaScript SEO: دليل حاسم)
- “JavaScript is not bad for SEO, and it’s not evil. It’s just different from what many SEOs are used to.” (ترجمة) «JavaScript ليس سيئًا لـSEO وليس شريرًا. إنه مختلف فحسب عما اعتاد عليه كثير من مختصي SEO.»
- “Any kind of SSR, static rendering, and prerendering setup is going to be fine for search engines.” (ترجمة) «أي إعداد لـSSR أو التصيير الثابت أو التصيير المسبق سيكون مناسبًا لمحركات البحث.»
قائمة تحقق Angular SEO
مرور سريع للتأكد من أن تطبيق Angular قابل للزحف والفهرسة:
- يُقدم المحتوى العام بوصفه HTML حقيقيًا عبر
@angular/ssr(SSR) أو التصيير المسبق، لا CSR كاملًا. - يُضبط نمط التصيير لكل مسار في
app.routes.server.ts— صير المسارات الثابتة مسبقًا، والديناميكية على الخادم، والداخلية غير المفهرسة على العميل فقط. - الترطيب مفعّل (
provideClientHydration())، ولا يستخدم أي قالبisPlatformBrowser()داخل@if(استخدمafterNextRender()بدلًا منه). - تضبط كل صفحة عنوانًا فريدًا (عبر خدمة
TitleأوTitleStrategyفي الموجّه) ووصفًا فريدًا (عبر خدمةMeta). - تُضبط وسوم Open Graph / Twitter Card عبر خدمة
Metaلمعاينات الشبكات الاجتماعية. - يستخدم التوجيه HTML5 History API (الافتراضي) مع
<base href="/">— لاHashLocationStrategy/useHash: true. - يستخدم كل تنقل مراسي
<a href>حقيقية، بما فيها الروابط إلى المسارات المحملة كسولًا. - لا يحظر
robots.txtموارد.jsأو.css. - تعيد عروض «غير موجود» من جانب العميل
404حقيقيًا أو تحملnoindex(لا أخطاء «غير موجود» ناعمة). - لا يصل الكود الذي يعمل على الخادم إلى
window/localStorage/document(استخدم رمزDOCUMENT/حواجز المنصة). - يوجد JSON-LD في مكان واحد ويجتاز اختبار النتائج الغنية.
- تحققت من HTML المصير في URL Inspection — لا من التطوير المحلي فقط.
النماذج الذهنية
1. أدخل HTML حقيقيًا في الاستجابة. تعود كل مشكلة SEO في Angular تقريبًا إلى سؤال واحد: هل يحصل برنامج الزحف على HTML مكتمل في الجلب الأول، أم على غلاف يجب أن يصيره؟ يجيب SSR والتصيير المسبق «نعم». ويجيب CSR «في النهاية، وربما». ابدأ كل تدقيق من هنا.
2. قاعدة قرار التصيير لكل مسار.
- المحتوى الثابت (الرئيسية وعن والمدونة والوثائق) →
RenderMode.Prerender. - المحتوى الديناميكي الذي يجب أن يبقى جديدًا (البحث والبيانات الحية) →
RenderMode.Server. - الصفحات الداخلية/المحمية التي لا تريد فهرستها →
RenderMode.Clientمناسب.
3. «Angular Universal» و@angular/ssr الفكرة نفسها في عصرين مختلفين.
كان Universal حزمة خارجية؛ فاستوعب v17 SSR داخل CLI وأعاد تسميته. إذا كنت على Angular حديث، فأنت تريد @angular/ssr — ومستودع Universal في وضع الصيانة.
4. رطّب، ولا تعِد التصيير.
يرسل SSR الساذج HTML ثم يرميه. ويعيد provideClientHydration() استخدامه — لكن فقط على مسار مصير مسبقًا/على الخادم، ولا ينشئ HTML خادم لمسار CSR. وتقتطع إعادة الأحداث والترطيب التدريجي (@defer) جزءًا من JavaScript الأولي. لا تفرّع القالب على isPlatformBrowser() — فذلك يسبب عدم تطابق الترطيب ومشكلة CLS.
5. وسوم الرأس مسؤوليتك، لا مسؤولية Angular.
لا توجد Yoast هنا. اضبط العناوين والأوصاف عمدًا باستخدام خدمتي Title/Meta (أو TitleStrategy)، لكل صفحة. و«تشترك كل الصفحات في عنوان واحد» هو الفشل الافتراضي، لا سوء حظ.
6. صمّم لروبوت عديم الحالة على عناوين URL نظيفة.
استخدم توجيه History API وروابط <a href> حقيقية، ولا تعتمد على ملفات تعريف الارتباط/التخزين، ولا تضع المحتوى خلف نقرة. ثم دع URL Inspection — لا حاسوبك المحمول — يخبرك بما صُيّر.
Angular SEO — ورقة غش
أنماط التصيير
| النمط | أين يُبنى HTML | SEO | الأفضل لـ | إعداد Angular |
|---|---|---|---|---|
| التصيير المسبق (SSG) | وقت البناء → ملفات ثابتة | ✅ الأفضل | تسويق/مدونة/وثائق ثابتة | RenderMode.Prerender |
| SSR | الخادم، عند كل طلب | ✅ ممتاز | محتوى ديناميكي يجب أن يبقى جديدًا | RenderMode.Server / @angular/ssr |
| العميل (CSR) | المتصفح | ⚠️ محفوف بالمخاطر | صفحات داخلية/محمية (غير مفهرسة) | RenderMode.Client |
| التصيير الديناميكي | خادم روبوت منفصل | حل التفافي فقط | تطبيقات قديمة لا يمكن ترحيلها | Puppeteer / Rendertron / prerender.io |
أوامر الإعداد
| الهدف | الأمر |
|---|---|
| مشروع جديد مع SSR | ng new my-app --ssr |
| إضافة SSR إلى مشروع قائم | ng add @angular/ssr |
| تفعيل الترطيب | provideClientHydration() في app.config.ts |
قواعد سريعة للرأس والتوجيه
- العناوين/الأوصاف: خدمتا Angular
Title+Meta(لا مكتبة خارجية لازمة). - عناوين تلقائية لكل مسار:
TitleStrategyفي الموجّه (v14+) عبر خاصيةtitleفي المسار. - التوجيه: HTML5 History API +
<base href="/">. لا تستخدمuseHash: true. - الروابط: مراسي
<a href>حقيقية — حتى المسارات المحملة كسولًا. - JSON-LD: احقنه عبر رمز
DOCUMENT؛ وأبقِه في مكان واحد.
التسمية
- Angular Universal = الحزمة الخارجية القديمة (
@nguniversal/express-engine)، في وضع الصيانة. @angular/ssr= SSR نفسه، مدمج في CLI منذ v17.- AngularJS (v1.x) ≠ Angular (v2+) — إطاران مختلفان؛ لا تنطبق نصائح AngularJS القديمة.
المطبات
isPlatformBrowser()في@ifالقالب → عدم تطابق الترطيب → CLS. استخدمafterNextRender().window/localStorage/documentعلى الخادم → تعطل SSR.- حظر
.js/.cssفي robots.txt → لا تستطيع Google التصيير.
تحقّق مما إذا كان تطبيق Angular يُصيَّر فعليًا على الخادم
أسرع طريقة لمعرفة ما إذا كان عنوان URL يستخدم CSR أو SSR/التصيير المسبق هي جلب HTML الخام (قبل تشغيل أي JavaScript) والبحث عن المحتوى الحقيقي. يعيد تطبيق Angular الذي يستخدم CSR عنصر <app-root> شبه فارغ؛ أما التطبيق الذي يستخدم SSR/التصيير المسبق فيعيد ترميزًا مكتملًا.
macOS / Linux
# Raw HTML as the server sends it — this is the "first fetch", pre-JS
curl -sL -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" \
https://example.com/page/ -o raw.html
# Is your real headline in the raw HTML? Empty result = CSR with no SSR
grep -o "Your headline text" raw.html
# A near-empty <app-root> is the tell-tale CSR signature
grep -o "<app-root></app-root>" raw.htmlWindows (PowerShell)
$ua = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
Invoke-WebRequest -Uri "https://example.com/page/" -UserAgent $ua -OutFile raw.html
Select-String -Path raw.html -Pattern "Your headline text"
Select-String -Path raw.html -Pattern "<app-root></app-root>"إذا كان العنوان مفقودًا ورأيت <app-root> عاريًا، فالمحتوى يعتمد على التصيير — أضف SSR أو التصيير المسبق. (ولرؤية DOM «المصيَّر»، استخدم URL Inspection’s “View Crawled Page → rendered HTML” في فحص عنوان URL؛ لا يستطيع curl العادي تشغيل JavaScript.)
تأكّد من أنك لا تحظر JavaScript وCSS الخاصَّين بـ Angular في robots.txt
macOS / Linux
curl -sL https://example.com/robots.txt | grep -iE "disallow.*\.(js|css)|Disallow:\s*/(assets|dist|main)"إذا طابق Disallow حزمة JavaScript الخاصة بك، فلن يستطيع Google تصيير الصفحة بصورة صحيحة — وهذا خطأ في الغالب.
أدوات تصحيح أخطاء Angular SEO
- URL Inspection (Google Search Console) — مصدر الحقيقة. شغّل Live Test، ثم اقرأ rendered HTML (DOM بعد تشغيل Googlebot لشفرة Angular)، وscreenshot، وpage resources (ما تم تحميله مقابل ما تم حجبه)، وJavaScript console messages.
- Rich Results Test — تأكّد من وجود JSON-LD في المخرجات المصيَّرة بعد أي تغيير في التصيير.
curl— يجلب HTML الخام قبل JavaScript لتمييز CSR (عنصر<app-root>فارغ) من SSR/التصيير المسبق.- Ahrefs Site Audit (مع تفعيل تصيير JavaScript) — يزحف باستخدام Chrome بلا واجهة ويقارن DOM الخام بالمصيَّر، كاشفًا البيانات الوصفية المفقودة، والروابط الأساسية المعطوبة، ومشكلات قابلية الفهرسة على نطاق واسع.
- Screaming Frog SEO Spider (وضع تصيير JavaScript) — يقارن المحتوى الخام بالمصيَّر لكل عنوان URL.
- Lighthouse / PageSpeed Insights — يقيس أثر استراتيجية التصيير في Core Web Vitals (CSR مقابل SSR مقابل التصيير المسبق).
- Angular CLI / DevTools — تأكّد من ضبط
outputModeومسارات الخادم وعمليات hydration كما تتوقع.
مصادر تستحق وقتك
كتاباتي ذات الصلة
- تحسين محركات البحث في JavaScript: دليل شامل — دليلي الكامل إلى التصيير، وتكافؤ DOM، وقاعدة التوجيه الأكثر تقييدًا، وإعدادات التصيير الآمنة. وتحسين Angular لمحركات البحث تطبيق محدد لكل ما يرد هنا.
- دليل المبتدئين إلى تحسين محركات البحث التقني — يشرح موضع التصيير والزحف ضمن الصورة الأكبر.
محاضراتي
- تحسين محركات البحث في JavaScript — Ungagged 2019 (SlideShare) — سلوك Googlebot في التصيير عديم الحالة، وإطار العرض، والتخزين المؤقت، إلى جانب أساليب التصيير في تلك الحقبة. (إخلاء مسؤولية دائم: توصية التصيير الديناميكي في ذلك العرض قديمة الآن — فقد وصفها Google منذ ذلك الحين بأنها حل التفافي.)
من أرجاء المجال
- التصيير على الويب (web.dev) — المقال المرجعي لـ Addy Osmani وJason Miller حول SSR وCSR والتصيير الثابت ومفاضلات hydration.
- التصيير من جهة الخادم والتصيير الهجين (SSR) (angular.dev) — الدليل الرسمي لـ
@angular/ssr: مسارات الخادم، وRenderMode، والتصيير المسبق، وhydration. - تقديم Angular v17 (مدونة فريق Angular) — الإصدار الذي جعل SSR ميزة أساسية في CLI وقدّم حزمة
@angular/ssr. - Angular Universal (في وضع الصيانة) (GitHub) — حزمة SSR التاريخية التي استبدلتها
@angular/ssr، ومفيدة لفهم إعادة التسمية. - دليل Angular SEO (Search Engine Journal، Jamie Indigo) — شرح كلاسيكي للفهرسة على موجتين؛ قوي في الأساسيات رغم أنه يسبق إعادة تسمية v17.
- دليل Angular SSR (Angular Architects، Alexander Thalhammer، مارس 2025) — دليل إعداد غني بعينات الشفرة؛ طابق عينات الشفرة مع وثائق
@angular/ssrالرسمية للتحقق من تغييرات API منذ نشره. - r/TechSEO — مجتمع تصحيح أخطاء التصيير والفهرسة.
أنماط Angular SEO المضادة
أخطاء ملموسة أراها مرارًا في تطبيقات Angular — كل واحدة منها عادة تستحق التحقق منها مباشرة، لا مجرد اعتبارها مخاطرة نظرية.
شحن بنية تعتمد على CSR فقط واعتبارها منتهية
لا يتضمن ناتج ng new الافتراضي SSR أو التصيير المسبق. إنها أسرع طريقة لبدء مشروع، وأسهل طريقة للانتهاء إلى عنصر <app-root> فارغ عند الطلب الأول. لماذا هذا خطأ: لا يحتوي HTML الخام الذي يراه الزاحف على محتوى، لذلك تعتمد الفهرسة بالكامل على مرحلة التصيير المؤجلة لدى Google — ولا تحصل برامج الزحف الأخرى على فرصة ثانية إطلاقًا. افعل بدلًا من ذلك: أضف @angular/ssr في بداية المشروع (ng new my-app --ssr)، أو شغّل ng add @angular/ssr على مشروع قائم، قبل شحن أي شيء تريد أن يعثر عليه المستخدمون.
استخدام HashLocationStrategy للمسارات العامة
لا يزال التوجيه باستخدام hash (useHash: true، مثل عناوين URL من الشكل /#/products/shoes) افتراضيًا في بعض دروس Angular القديمة والقوالب الجاهزة. لماذا هذا خطأ: يُجرَّد كل ما بعد # من جهة العميل قبل أن يصل الطلب إلى الخادم أصلًا، لذلك لا يرى الخادم — ولا Googlebot — سوى عنوان URL واحد للتطبيق كله. افعل بدلًا من ذلك: استخدم توجيه HTML5 History API الافتراضي (PathLocationStrategy) مع <base href="/"> في index.html.
تفريع القالب بناءً على isPlatformBrowser()
يبدو تغليف المحتوى داخل @if (isPlatformBrowser(platformId)) طريقة بديهية لحماية الشفرة الخاصة بالمتصفح. لماذا هذا خطأ: يصيّر الخادم فرعًا ويصيّر العميل الفرع الآخر أثناء hydration، وهذا عدم تطابق في hydration — يتعين على Angular تسوية الفرق، والنتيجة المرئية هي إزاحة في التخطيط تظهر بوصفها CLS. افعل بدلًا من ذلك: استخدم afterNextRender() للأعمال الخاصة بالمتصفح كي يصيَّر القالب نفسه بصورة متطابقة على الخادم والعميل.
ضبط document.title مباشرةً بدلًا من استخدام خدمة Title
يعمل ذلك في بيئة التطوير المحلية، ولذلك فهو اختصار سهل اللجوء إليه. لماذا هذا خطأ: لا يتوافق الوصول المباشر إلى DOM، مثل document.title = '...'، جيدًا مع SSR — فلا يوجد كائن global باسم document على الخادم بالمعنى نفسه الموجود في المتصفح، كما تفقد مزايا دمج الموجّه مع معالجة العناوين الخاصة بـ Angular. افعل بدلًا من ذلك: احقن خدمة Angular Title (setTitle())، أو اضبط العناوين لكل مسار باستخدام TitleStrategy الخاص بالموجّه.
لمس window أو localStorage أو document في شفرة تعمل أثناء SSR
يعمل المكوّن أو الخدمة التي تقرأ localStorage أو تتحقق من window.innerWidth وقت الإنشاء بصورة جيدة في المتصفح، لكنها تعطل التصيير على الخادم. لماذا هذا خطأ: لا يوجد أي من هذه الكائنات العامة في عملية Node التي تشغّل بنية SSR، ولذلك يفشل التصيير ويعيد الطلب إما استجابة خطأ أو استجابة فارغة بصمت. افعل بدلًا من ذلك: ضع تلك الشفرة خلف afterNextRender()، أو احقن رمز Angular DOCUMENT بدلًا من الكائن العام، واختبر بنية SSR محليًا (ng build ثم تقديم مخرجات SSR)، لا بمجرد ng serve.
معاملة التصيير الديناميكي بوصفه حلًا دائمًا
يحل إنشاء Puppeteer أو خدمة مثل Rendertron لتقديم لقطة مصيَّرة مسبقًا إلى برامج الزحف الأعراضَ المباشرة. لماذا هذا خطأ: إنه نظام إضافي يجب صيانته، وقد يبتعد عن المحتوى الذي يراه المستخدمون الفعليون، وقد قال Google صراحةً إنه حل التفافي لا حل طويل الأجل. افعل بدلًا من ذلك: انقل التطبيق إلى @angular/ssr أو التصيير المسبق كي يحصل كل طالب — روبوتًا كان أم إنسانًا — على HTML حقيقي متطابق من المسار نفسه.
ما وضع التصيير الذي ينبغي أن يستخدمه هذا المسار؟
يتيح لك Angular v17+ ضبط وضع التصيير لكل مسار في app.routes.server.ts. والسؤال ليس «هل أستخدم SSR أم التصيير المسبق للتطبيق كله؟» — بل يُطرح لكل مسار على حدة.
Choosing a rendering mode for an Angular route
مطالبات لأعمال Angular SEO
مطالبات جاهزة للنسخ لمهام Angular SEO المحددة في هذا المقال. ألصق الإدخال الموصوف وتحقق من الناتج وفق حكمك — فهي توفر الوقت في الأجزاء الميكانيكية، لكنها لا تغني عن الاختبار باستخدام فحص عنوان URL.
1. قارن HTML الخام بالـ HTML المصيَّر لمسار
ألصق ناتج curl -sL <url> (HTML الخام) ولوحة “rendered HTML” من اختبار Live Test في URL Inspection (أو زحف Ahrefs/Screaming Frog مع تصيير JavaScript) لعنوان URL نفسه.
Here is the raw HTML for [URL] (fetched with curl, before JavaScript runs):
[paste raw HTML]
Here is the rendered HTML for the same URL (from Google Search Console URL
Inspection's Live Test, or a JS-rendering crawler):
[paste rendered HTML]
Compare the two. List: (1) content present in rendered but missing from raw —
this is what depends on client-side rendering, (2) any <title>, meta description,
or JSON-LD that differs between the two versions, (3) whether the raw HTML shows
a near-empty <app-root> (a sign of CSR with no SSR/prerendering).توقّع أن تحصل على قائمة قصيرة بما يعتمد على CSR، وبأي انجراف في العنوان أو البيانات الوصفية أو المخطط بين النسختين الخام والمصيَّرة — وهذان هما أول أمرين يستحقان الإصلاح.
2. راجع تطبيق خدمة Title/Meta
ألصق خدمة Angular SeoService (أو ما يعادلها) التي تستدعي خدمتي Title وMeta.
Here is an Angular service that sets page titles and meta tags:
[paste the service's TypeScript code]
Check it against these rules: (1) titles are set via the Title service's
setTitle(), never document.title directly, (2) description is set with
meta.updateTag({ name: 'description', ... }) not addTag() (which can duplicate
the tag on repeat calls), (3) Open Graph tags use the property selector, not
name, (4) nothing in this code reads window/localStorage/document directly in a
way that would break during SSR. Flag any line that violates one of these and
suggest the fix.توقّع نتيجة نجاح/فشل سطرًا بسطر مقابل القواعد الأربع، مع مقطع مصحح لأي شيء يعلَّم على أنه مخالف.
3. راجع app.routes.server.ts بحثًا عن أخطاء وضع التصيير
ألصق ملف إعداد مسارات الخادم لديك.
Here is my Angular app.routes.server.ts, which sets RenderMode per route:
[paste the file]
For each route, tell me: is RenderMode.Prerender used on anything that depends
on per-request or per-user data (a mistake — it would bake stale/wrong data into
the static build)? Is RenderMode.Client used on anything that looks like public,
indexable content (a missed-SEO-opportunity)? Is RenderMode.Server used on fully
static content where Prerender would be faster and cheaper? List each route with
its current mode and whether it matches the decision rule: static data →
Prerender, must-be-fresh → Server, non-indexed internal → Client.توقّع حكمًا لكل مسار يعلّم على أي مسار لا يتوافق RenderMode الخاص به مع ما يحتاجه المسار فعلًا.
اختبر نفسك: Angular SEO
خمسة أسئلة سريعة حول جعل تطبيقات Angular قابلة للزحف والفهرسة. اختر إجابة لكل سؤال، ثم تحقق منها.
سجل التغييرات
تم التحديث في 22 أغسطس 2026.
ملخص تحريري وتفاصيل التغيير المسجلة.تفاصيل التغيير
-
تفاصيل التغيير متاحة حاليًا باللغة الإنجليزية.
-
تفاصيل التغيير متاحة حاليًا باللغة الإنجليزية.
-
تفاصيل التغيير متاحة حاليًا باللغة الإنجليزية.
المقارنة الكاملة غير متاحة — لم تُؤرشف لقطة سابقة لهذه المراجعة.
تم التحديث في 8 أغسطس 2026.
ملخص تحريري وتفاصيل التغيير المسجلة.تفاصيل التغيير
-
تفاصيل التغيير متاحة حاليًا باللغة الإنجليزية.
المقارنة الكاملة غير متاحة — لم تُؤرشف لقطة سابقة لهذه المراجعة.
تم التحديث في 17 يوليو 2026.
ملخص تحريري وتفاصيل التغيير المسجلة.تفاصيل التغيير
-
تفاصيل التغيير متاحة حاليًا باللغة الإنجليزية.
-
تفاصيل التغيير متاحة حاليًا باللغة الإنجليزية.
-
تفاصيل التغيير متاحة حاليًا باللغة الإنجليزية.
المقارنة الكاملة غير متاحة — لم تُؤرشف لقطة سابقة لهذه المراجعة.