تفتح منتجك من الرئيسية، وتتنقل بين الصفحات عادي. بعدها ترسل لعميل رابط مثل /dashboard، أو تضغط تحديث وأنت في صفحة داخلية، وتطلع صفحة بيضاء فيها 404: NOT_FOUND ورمز طويل تحته. هذي رسالة Vercel، و Netlify يعرض رسالة مشابهة «Page not found». المعنى باختصار: الاستضافة دوّرت على ملف بهالاسم وما لقته.
ليش الرئيسية تشتغل والباقي لا
أغلب المنتجات اللي تطلع من Bolt، ومشاريع Lovable اللي انبنت قبل 13 مايو 2026، ومن v0 لما يكون المشروع React مع Vite، تطبيقات «صفحة وحدة» (SPA). يعني فيه ملف واحد اسمه index.html، والتنقل بين الصفحات يصير داخل المتصفح: الكود يقرأ الرابط ويعرض الصفحة المناسبة بدون ما يطلب شي من السيرفر. مشاريع Lovable الأحدث مبنية على TanStack Start وتنرسم على السيرفر، فتحتاج استضافة تشغّل سيرفر، وقاعدة التوجيه اللي تحت مو لها.
لما تضغط رابط داخل الموقع، المتصفح ما يطلب صفحة جديدة، فكل شي يشتغل. لكن لما تفتح /dashboard مباشرة أو تحدّث الصفحة، المتصفح يطلب من الاستضافة ملف اسمه dashboard. ما فيه ملف بهالاسم، لأن كل الصفحات ساكنة داخل index.html، فترجع الاستضافة 404.
في المعاينة داخل Lovable أو Bolt ما تشوف المشكلة، لأن سيرفر التطوير عندهم يرجّع index.html لأي رابط تلقائيًا. الاستضافة الحقيقية ما تسوي هذا إلا إذا قلت لها.
كيف تتأكد إن هذي مشكلتك
- افتح الرئيسية، واضغط رابط لصفحة داخلية من داخل الموقع. إذا فتحت، كمّل.
- وأنت على نفس الصفحة، اضغط تحديث (F5). إذا طلعت 404، هذي هي المشكلة.
- إذا الرئيسية نفسها تطلع 404، المشكلة غير: غالبًا مجلد المخرجات (Output Directory) في إعدادات النشر غلط. مشاريع Vite تطلّع ملفاتها في مجلد
dist، وإذا الاستضافة تدوّر في مجلد ثاني ما تلقى شي.
ملاحظة: إذا منتجك مبني بـ Next.js، مثل أغلب مشاريع v0، هذي المشكلة غالبًا ما تصيبك بهالشكل، لأن Next.js يعرف صفحاته على السيرفر. 404 هناك معناه إن الصفحة فعلًا ما انبنت، أو إن اسم مجلدها غلط.
الحل الصح: قاعدة توجيه وحدة
المطلوب إنك تقول للاستضافة: «أي رابط ما له ملف، رجّع index.html، والكود يتصرّف». هذي اسمها قاعدة rewrite، وكل منصة لها مكانها:
- Vercel: ملف اسمه
vercel.jsonفي جذر المشروع، فيه قاعدة rewrites ترجّع الروابط لـ/index.html. أبسط شكل لها:{"rewrites":[{"source":"/(.*)","destination":"/index.html"}]}. - Netlify: ملف اسمه
_redirectsداخل مجلدpublic، فيه سطر واحد:/* /index.html 200. الرقم 200 مهم: معناه «اعرض index.html» مو «حوّل له». - Cloudflare Pages: إذا مشروعك ما فيه ملف
404.html، يتعامل معه كتطبيق صفحة وحدة تلقائيًا.
بعد ما تضيف القاعدة، أعد النشر وجرّب الخطوات فوق مرة ثانية. وجرّب بعد في نافذة خاصة (Incognito)، عشان تتأكد إنك ما تشوف نسخة قديمة محفوظة في متصفحك.
ليش تهمّك حتى لو ما أحد اشتكى
ممكن تقول: «المستخدمين يدخلون من الرئيسية، عادي». لكن روابط كثيرة تفتح صفحة داخلية مباشرة: رابط تأكيد الإيميل، ورابط إعادة كلمة السر، ورابط الرجوع من صفحة الدفع، والرابط اللي يرسله عميل لصاحبه. كل هذي تطلع 404 لو القاعدة ناقصة، وأغلب الناس ما يشتكون، يطلعون فقط.
انتبه لروابط الـ API
Vercel و Netlify يقدّمون الملفات والدوال الموجودة فعلًا قبل القاعدة، فالقاعدة ما تمسك إلا رابط ما وراه شي. لكن لو طلب بيانات مثل /api/orders راح للاستضافة وما فيه دالة بهالاسم، لأن سيرفرك في مكان ثاني أو الدالة ما انرفعت، القاعدة ترجّع له index.html. لو صار هذا، الكود يستقبل صفحة HTML بدل البيانات، ويطلع لك خطأ ثاني شكله Unexpected token '<'، شرحناه في درس Unexpected token. لهذا خلّ القاعدة تستثني مسار الـ API إذا عندك واحد، وبعد التعديل جرّب صفحة فيها بيانات، مو الرئيسية فقط.
الحلول اللي لا تعتمد عليها
أدوات الذكاء الاصطناعي أحيانًا تقترح تغيّر طريقة التوجيه إلى HashRouter، فتصير روابطك مثل /#/dashboard. هذا يخفي المشكلة، لكنه يخلّي روابطك غريبة، ومحركات البحث تتعامل مع موقعك كله كأنه صفحة وحدة، فتخسر ظهور صفحاتك الداخلية في Google.
واقتراح ثاني نشوفه: صفحة 404 مخصّصة تحوّل الزائر للرئيسية. المستخدم ما يوصل للصفحة اللي طلبها، والرابط اللي أرسلته لعميلك ما يشتغل، فهذا مو حل.
إذا عدّلت وما زالت
إذا أضفت القاعدة وما زالت 404، أو طلع لك خطأ جديد بعدها، خلّ مهندس يشوفه معك في مكالمة استشارية: نشارك الشاشة ونوصل للسبب، ويوصلك التسجيل وخطوات مكتوبة. وللأسباب الثانية اللي تخلّي المنتج يشتغل عندك ويتعطّل بعد النشر، شوف يشتغل عندك ثم يتعطّل بعد النشر؟.