الأدلة

كيف تصلح أخطاء 404 بعد النشر لموقعك أو تطبيقك

إذا كان تطبيقك يعمل محلياً لكن الصفحات تعطي 404 بعد النشر، فالسبب الأكثر شيوعاً هو غياب توجيه تطبيق الصفحة الواحدة (SPA): الخادم يبحث عن ملف اسمه /dashboard غير موجود، لأن هذا المسار موجود فقط داخل JavaScript. الحل قاعدة احتياطية تعيد index.html لمسارات التطبيق. الأسباب الأخرى تشمل ملفات مفقودة من مخرجات البناء، ومسارات حساسة لحالة الأحرف، والاختلاف في الشرطة المائلة في النهاية، ومسار أساسي (base path) خاطئ، وواجهات برمجية لم تُنشر أصلاً.

ابدأ بملاحظة الرابط الدقيق الذي يعطي 404، وكيف وصلت إليه. النمط يشير مباشرة إلى السبب.

الخطوة 1: حدّد النمط

ما تراهالسبب الأرجحانتقل إلى
الصفحة الرئيسية تعمل، والنقر على الروابط يعمل، لكن تحديث الصفحة أو فتح رابط مباشر يعطي 404لا توجد قاعدة احتياطية لـ SPAالخطوة 2
كل الصفحات تعطي 404، بما فيها الصفحة الرئيسيةنُشر المجلد الخطأ، أو لم يُنشر البناءالخطوة 3
الصفحات تُحمَّل، لكن الصور أو الخطوط أو السكربتات تعطي 404ملفات مفقودة من البناء، أو مسارات خاطئةالخطوة 4
يعمل مع /about/ ويفشل مع /about (أو العكس)التعامل مع الشرطة المائلة في النهايةالخطوة 5
/About يفشل لكن /about يعملالخادم حساس لحالة الأحرفالخطوة 4
الصفحة تُحمَّل، لكن طلبات البيانات إلى /api/... تعطي 404الواجهة البرمجية غير منشورة أو غير موجهةالخطوة 6
الروابط القديمة من موقع سابق تعطي 404إعادة توجيه مفقودةالخطوة 7
فقط على النطاق المخصصإعداد DNS أو النطاقالخطوة 8

لرؤية رمز الحالة الفعلي، افتح أدوات المطوّر (انقر بالزر الأيمن ← Inspect أو «فحص»)، واذهب إلى تبويب Network، وأعد التحميل، وانظر إلى حالة الطلب الأول.

الخطوة 2: أضف قاعدة الرجوع لـ SPA

هذه هي الحالة الكلاسيكية. في تطبيقات الصفحة الواحدة بـ React أو Vue أو Svelte، يملك الخادم عدداً محدوداً من الملفات الحقيقية: index.html وبعض ملفات JavaScript وCSS. المسارات مثل /dashboard أو /projects/42 يتولاها موجّه داخل المتصفح.

  • النقر على رابط يعمل: يغيّر الموجّه الرابط ويرسم الصفحة الجديدة دون أن يسأل الخادم.
  • تحديث الصفحة أو فتح رابط مباشرة يفشل: يطلب المتصفح من الخادم /dashboard، ولا يوجد هذا الملف، فيعيد الخادم 404.

الحل قاعدة تقول: إذا لم يطابق الطلب ملفاً حقيقياً، فأعد index.html بحالة 200، ودع الموجّه يتولى الباقي. الطريقة تعتمد على المزود (تحقق من الوثائق الحالية لمزودك، فالتفاصيل تتغير):

المزودقاعدة الرجوع المعتادة
Netlifyملف _redirects في المجلد المنشور يحوي /* /index.html 200
Vercelrewrite في vercel.json من كل المسارات إلى /index.html (إعدادات الأطر غالباً تتولى ذلك)
Cloudflare Pagesيقدم رجوعاً بنمط SPA افتراضياً إذا لم يوجد ملف 404.html في المستوى الأعلى
Nginxtry_files $uri $uri/ /index.html; داخل كتلة location /
Apacheقاعدة rewrite في .htaccess ترسل الطلبات غير الملفات إلى index.html
GitHub Pagesلا توجد إعادة كتابة من جهة الخادم؛ والحلول البديلة الشائعة هي التوجيه بالهاش، أو ملف 404.html يعيد التوجيه

تأكد أن القاعدة لا تبتلع الملفات الحقيقية: طلبات مثل /assets/app.js يجب أن تعيد ملف JavaScript الفعلي. إذا أعادت index.html بدلاً منه، ستحصل على صفحة فارغة مع خطأ «Failed to load module script». راجع إصلاح الصفحة البيضاء الفارغة.

أعطِ الموجّه أيضاً مساراً شاملاً (catch-all) حتى تعرض الروابط التي لا تطابق أي صفحة رسالة «الصفحة غير موجودة» ودية، بدلاً من لا شيء.

إذا لم تستطع تغيير إعدادات الخادم، فإن التوجيه بالهاش (روابط مثل /#/dashboard) يتجنب المشكلة، لأن الجزء الذي يأتي بعد # لا يُرسل إلى الخادم أبداً. هذا حل بديل وليس الخيار الأول: الروابط أقل جمالاً وأقل ودية لمحركات البحث.

الأطر التي تُولّد الصفحات على الخادم أو وقت البناء (Next.js وAstro وما شابهها) تملك عادةً ملفات حقيقية أو مسارات خادم لكل صفحة، لذلك هذه المشكلة أقل شيوعاً فيها. ما يعادلها هناك هو صفحة لم تُولَّد وقت البناء.

الخطوة 3: تحقق مما نُشر فعلاً

إذا كانت كل الصفحات تعطي 404، فالأرجح أن الخادم لا يقدم تطبيقك المبني.

  • المجلد الصحيح. يجب أن تنشر المنصة مخرجات البناء (عادةً dist لـ Vite، وbuild لـ Create React App، وout لتصدير Next.js الثابت)، لا جذر المشروع.
  • البناء اكتمل. اقرأ سجل النشر. إذا فشل البناء، فقد لا تنشر المنصة شيئاً، أو تنشر نسخة قديمة.
  • ملف index.html في المستوى الأعلى للمجلد المنشور، لا داخل مجلد فرعي.
  • المسار الأساسي متطابق. إذا كان التطبيق يُقدَّم من example.com/app/، فيجب بناؤه بذلك المسار الأساسي (خيار base في Vite، أو basename في React Router)، وإلا ستخطئ كل المسارات والأصول.

الخطوة 4: أصلح الملفات المفقودة والمسارات الخاطئة

عندما تُحمَّل الصفحات لكن الأصول تعطي 404:

  • حساسية حالة الأحرف. macOS وWindows يعاملان عادةً Logo.png وlogo.png كالملف نفسه. معظم خوادم Linux لا تفعل. اجعل كل مرجع مطابقاً لاسم الملف الفعلي حرفاً بحرف.
  • ملفات خارج البناء. في Vite، الملفات الموجودة في public/ تُنسخ كما هي وتُشار إليها من الجذر (/logo.png). الملفات المستوردة في الكود تُحزَم ضمن البناء. ملف موجود في مكان آخر من المشروع قد لا يُنشر أصلاً.
  • المسارات النسبية. images/photo.jpg يُحسب نسبةً إلى الرابط الحالي، لذا ينكسر على /blog/post-1. استخدم /images/photo.jpg.
  • ملفات مرفوعة محفوظة على القرص المحلي. إذا كُتبت ملفات المستخدمين المرفوعة إلى المجلد المحلي للخادم، فستختفي عند نشر نسخة جديدة. استخدم تخزين ملفات حقيقياً.

الخطوة 5: تعامل مع الشرطة المائلة في النهاية باتساق

/about و/about/ عنوانان مختلفان. تختلف المنصات في إضافة الشرطة المائلة أو حذفها، وعدم التطابق مع روابطك أو مع الموجّه قد يسبب 404 أو حلقات إعادة توجيه. اختر نمطاً واحداً، واجعل روابطك تستخدمه، واضبط المنصة لتعيد توجيه الشكل الآخر إليه. الاتساق يساعد محركات البحث أيضاً، التي قد ترى نسختين من كل صفحة.

الخطوة 6: أصلح واجهات البرمجة التي تعطي 404

إذا تُحمَّلت الصفحة لكن تبويب Network يُظهر طلبات /api/... تعيد 404:

  • الخلفية غير منشورة. الاستضافة الثابتة تقدم الملفات فقط؛ يجب أن تعمل الخلفية في مكان ما.
  • المسار موجَّه بشكل مختلف في الإنتاج. في التطوير، قد يحوّل وكيل (proxy) الطلبات من /api إلى خادم منفصل. في الإنتاج، تحتاج المنصة إلى إعادة توجيه مكافئة، أو يجب أن تستدعي الواجهة الأمامية العنوان الحقيقي للواجهة البرمجية.
  • قاعدة الرجوع التقطت الطلب. طلب الواجهة البرمجية الذي يعيد index.html بحالة 200 يعني أن قاعدة الرجوع واسعة جداً. استثنِ /api/* منها.

طلبات التطبيق المنشور إلى /api/orders تعطي 404، رغم أنها تعمل في المعاينة. تحقق من طريقة توجيه /api في المعاينة مقابل التطبيق المنشور، واجعل الواجهة الأمامية المنشورة تصل إلى الخلفية بالطريقة نفسها.

الخطوة 7: أعد توجيه الروابط القديمة

إذا انتقلت من موقع آخر أو أعدت هيكلة موقعك، فالروابط القديمة التي ما زال الناس ومحركات البحث يستخدمونها ستعطي 404. أضف إعادة توجيه 301 (دائمة) من كل رابط قديم إلى موقعه الجديد. احتفظ بقائمة واختبر عيّنة منها بعد الإطلاق. ويشرح دليلنا عن نقل موقع WordPress كيفية بناء هذه القائمة.

الخطوة 8: تحقق من النطاق

إذا كان التطبيق يعمل على عنوان المزود لكنه يعطي 404 على نطاقك المخصص، فقد يشير النطاق إلى مشروع خاطئ، أو قد لا يكون المزود قد ربط النطاق بموقعك بعد. تحقق من سجلات DNS وإعدادات النطاق لدى المزود. راجع كيف تربط نطاقاً مخصصاً.

اجعل صفحة 404 الحقيقية مفيدة

بعض حالات 404 صحيحة: شخص كتب الرابط بشكل خاطئ. اجعل تلك الصفحة مفيدة:

  • رسالة قصيرة، ورابط للصفحة الرئيسية والأقسام الأساسية
  • مربع بحث، إذا كان في الموقع بحث
  • الترويسة والتنقل نفسهما كبقية الموقع

حيثما يسمح إعدادك، أرجع حالة 404 حقيقية للصفحات غير الموجودة. رسالة «غير موجود» مع حالة 200 هي ما تسميه محركات البحث خطأً ناعماً (soft 404)، وقد يهدر وقت الزحف ويربك الفهرسة.

أخطاء شائعة

  • الاختبار بالنقر فقط. اختبر دائماً بلصق الروابط العميقة في نافذة جديدة وتحديثها.
  • قاعدة رجوع تلتقط كل شيء. الأصول وطلبات الواجهة البرمجية تعيد index.html، فتنتج صفحات فارغة وأخطاء API مربكة.
  • اختلاف في حالة الأحرف لا يظهر إلا على الخادم.
  • نشر مجلد المصدر بدلاً من مخرجات البناء.
  • إعادة هيكلة الروابط دون إعادة توجيه. كل رابط قديم يصبح 404.

حالات 404 في Mythex

في Mythex تنشر من مساحة العمل، والواجهات الأمامية الثابتة تُنشر كمواقع ثابتة. إذا أعطت صفحة منشورة 404، فأعطِ الوكيل الرابط الدقيق، وهل يحدث ذلك عند التحديث أم عند النقر، وما الذي يُظهره تبويب Network، واطلب منه فحص التوجيه. انشر مرة أخرى بعد الإصلاح، لأن التطبيق الحي نسخة لقطة حتى تعيد النشر. إذا غيّرت المشروع مؤخراً والموقع الحي يبدو قديماً، فانشر مرة أخرى وأعد التحميل بالكامل (hard refresh). استخدم Fix with AI في نافذة النشر إذا فشل البناء. راجع كيف تنشر واستكشاف أخطاء النشر في الوثائق، ودليلنا عن تصحيح تطبيق بُني بالذكاء الاصطناعي.

قائمة مراجعة 404

  • دوّنت الروابط الدقيقة التي تعطي 404، وهل ذلك عند النقر أم التحديث أم كليهما
  • قاعدة SPA تعيد index.html لمسارات التطبيق بحالة 200
  • القاعدة تستثني الملفات الحقيقية و/api/*
  • الموجّه لديه مسار شامل «غير موجود»
  • مجلد مخرجات البناء هو ما يُنشر، ونجح البناء
  • المسار الأساسي يطابق المكان الذي يُقدَّم منه التطبيق
  • حالة أحرف أسماء الملفات تطابق كل مرجع
  • مسارات الأصول تبدأ بـ /
  • نمط الشرطة المائلة في النهاية متسق
  • الواجهات البرمجية منشورة وموجّهة في الإنتاج
  • إعادة توجيه 301 للروابط القديمة
  • اختبرت الروابط العميقة بلصقها في نافذة جديدة

الأسئلة

لماذا أحصل على 404 عندما أحدّث صفحة في تطبيق React الخاص بي؟

في تطبيق الصفحة الواحدة (SPA)، المسارات مثل /dashboard موجودة فقط داخل JavaScript. النقر على رابط يعمل لأن الموجّه (router) يتولاه في المتصفح، لكن تحديث الصفحة يطلب من الخادم ملفاً باسم /dashboard غير موجود. الحل قاعدة احتياطية (fallback) تعيد index.html لمسارات التطبيق.

كيف أضيف قاعدة الرجوع إلى index.html في Netlify أو Vercel أو Nginx؟

في Netlify، أضف ملف _redirects يحوي السطر /* /index.html 200. وفي Vercel، أضف rewrite في vercel.json يوجّه كل المسارات إلى /index.html. وفي Nginx، استخدم try_files $uri $uri/ /index.html; داخل كتلة location. راجع وثائق المزود لديك، فالقواعد تتغير.

لماذا تعطي صوري أو ملفاتي 404 بعد النشر؟

غالباً لأن الملف غير موجود في مخرجات البناء، أو لأن حالة الأحرف في المسار لا تطابق الملف الفعلي (الخوادم كثيراً ما تفرّق بين الحروف الكبيرة والصغيرة بينما حاسوبك لا يفعل)، أو لأن المسار نسبي بينما يجب أن يبدأ بشرطة مائلة.

هل يجب أن تُرجع الصفحة المفقودة حالة 404 حقيقية؟

نعم. اعرض صفحة «غير موجود» مفيدة، لكن بحالة 404 حيثما يسمح إعدادك. محركات البحث تعتبر رسالة «غير موجود» مع حالة 200 خطأً ناعماً (soft 404)، وهذا يهدر وقت الزحف ويربك الفهرسة.

Mythex · Pricing · ابنِ أي شيء بالذكاء الاصطناعي · قوالب المواقع والتطبيقات · مقارنات Mythex · مصطلحات بناء التطبيقات بالذكاء الاصطناعي · أدوات مجانية لبناء التطبيقات بالذكاء الاصطناعي · English

English አማርኛ Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)