منتجك يشتغل على جهازك، وبعد النشر يتعطّل جزء منه. تفتح Console وتلقى undefined في مكان رابط أو مفتاح، أو رسالة ReferenceError: process is not defined. الكود يقرأ إعداد من «متغيرات البيئة» (Environment Variables)، والإعداد ما وصل.
في درس يشتغل عندك ثم يتعطّل بعد النشر ذكرنا هالسبب باختصار. هنا نفصّله، لأنه من أكثر الأشياء اللي تضيّع يوم كامل، وفيه فخ أمني لازم تعرفه.
أول شي: الواجهة غير السيرفر
فيه نوعين من الكود في منتجك:
- كود الواجهة: يشتغل في متصفح الزائر. أي قيمة يقرأها تنكتب داخل ملفات الموقع وقت البناء، وأي أحد يقدر يشوفها.
- كود السيرفر: يشتغل في الاستضافة (Edge Functions، أو API routes، أو سيرفر Node). يقرأ قيمه وقت التشغيل، والزائر ما يشوفها.
أغلب مشاكل undefined تجي من الخلط بين الاثنين.
الأسباب الأشهر
1. اسم المتغير ما يبدأ بالبادئة الصح
أدوات البناء ما توصّل لكود الواجهة إلا المتغيرات اللي تبدأ ببادئة معيّنة، عشان ما تنكشف أسرارك بالغلط:
- مع Vite، وهو أساس أغلب مشاريع Lovable و Bolt: البادئة
VITE_، والقراءة بـimport.meta.env.VITE_API_URL. - مع Next.js، وهو أساس أغلب مشاريع v0: البادئة
NEXT_PUBLIC_، والقراءة بـprocess.env.NEXT_PUBLIC_API_URL. - مع Create React App القديم: البادئة
REACT_APP_.
متغير اسمه API_URL بدون بادئة يكون موجود في إعدادات الاستضافة، لكنه undefined في المتصفح.
2. process is not defined
process.env شي موجود في Node.js، ومو موجود في المتصفح. Next.js و Create React App يستبدلونه وقت البناء، لكن Vite لا. فإذا الذكاء الاصطناعي نقل كود من مشروع Next.js أو من مثال قديم إلى مشروع Vite، يطلع هذا الخطأ. الحل في Vite إنك تقرأ القيمة من import.meta.env.
3. أضفته بعد النشر وما أعدت البناء
قيم الواجهة تنكتب داخل الملفات وقت البناء. إذا أضفت متغير أو غيّرت قيمته في إعدادات الاستضافة، النسخة المنشورة ما تعرف عنه شي حتى تعيد النشر (Redeploy).
4. المتغير موجود في بيئة غير
في Vercel، كل متغير تختار له البيئات اللي يشتغل فيها: Production و Preview و Development. متغير مضاف لـ Preview فقط يشتغل في روابط المعاينة، ويطلع undefined على موقعك الحقيقي. نفس الفكرة موجودة في منصات ثانية بأسماء مختلفة.
5. أسرار السيرفر في المكان الغلط
إذا منتجك يستخدم Edge Functions في Supabase، أسرار هالدوال تنحفظ في إعدادات Supabase نفسه (Secrets)، مو في إعدادات Vercel أو Netlify. تضيف المفتاح في الاستضافة، والدالة على Supabase ما تشوفه أبد، فترجع خطأ. شرحنا شكل هالخطأ في درس Edge Function returned a non-2xx.
6. خطأ صغير في الاسم أو القيمة
حرف كبير بدل صغير (VITE_Api_Url غير VITE_API_URL)، أو مسافة زايدة، أو علامات تنصيص انحفظت داخل القيمة نفسها. ملف .env.local، وملف .env إذا كان مذكور في .gitignore، ما ينرفع للاستضافة، فلازم تنقل كل قيمة منها بيدك وتطابقها. وإذا كان .env مرفوع مع الكود، تأكد إنه ما فيه أي مفتاح سري.
كيف تتأكد بنفسك
- افتح ملف
.envعلى جهازك، أو اطلب من أداة الذكاء الاصطناعي قائمة بكل المتغيرات اللي يقرأها الكود. - افتح إعدادات النشر في الاستضافة، وقارن الأسماء حرف بحرف، وتأكد إن كل واحد مفعّل لبيئة Production.
- أعد النشر، ثم افتح الموقع واضغط F12، وفي تبويب Sources ابحث (Ctrl+Shift+F) عن القيمة اللي تتوقعها، مثل رابط السيرفر. إذا لقيتها، وصلت. إذا ما لقيتها، ما وصلت.
الفخ: لا تحل المشكلة بكشف أسرارك
لما مفتاح سري يطلع undefined في كود الواجهة، أسهل اقتراح من أداة الذكاء الاصطناعي: «غيّر اسمه إلى VITE_OPENAI_KEY». المشكلة تنحل فعلًا، لكن المفتاح صار مكتوب داخل ملفات موقعك، وأي زائر يقدر ياخذه ويصرف من حسابك. شرحنا إيش يصير بعدها في درس مفتاح OpenAI انكشف.
القاعدة البسيطة:
- قيم عامة، مثل رابط السيرفر أو مفتاح Supabase العام (anon key) اللي تحميه قواعد RLS: مكانها البادئة العامة، وعادي يشوفها الزائر.
- أي مفتاح يصرف من حسابك أو يتجاوز الصلاحيات، مثل مفتاح OpenAI، أو مفتاح الدفع السري، أو مفتاح
service_roleفي Supabase: مكانه السيرفر فقط، بدون بادئة عامة، والواجهة تطلب من السيرفر.
تبي أحد يرتّبها معك؟
إذا عندك مفاتيح كثيرة ومو متأكد أي واحد مكشوف وأي واحد في مكانه، الإصلاح المباشر ينقل الأسرار للسيرفر ويرتّب الإعدادات لكل بيئة. وإذا المشكلة متغير واحد ما تدري ليش ما يوصل، تكفيك مكالمة استشارية.