حل خطأ proxy.ts في Next.js 16: Missing Expected Function Export
حل خطأ «Proxy is missing expected function export name» في Next.js 16: كل الأسباب التي جربناها على 16.4.5، والتصدير الصحيح، وإعداد next-intl.

يوقف Next.js 16 عملية البناء برسالة الخطأ «Proxy is missing expected function export name» عندما لا يصدّر ملف proxy.ts دالة اسمها proxy ولا دالة افتراضية (default export). والسبب المعتاد ملف أُعيدت تسميته من middleware.ts وما زال يحتوي على export function middleware. غيّر اسم هذه الدالة إلى proxy، أو اجعلها التصدير الافتراضي، فينجح البناء.
أعدنا إنتاج كل حالة في هذه الصفحة يوم 5 نوفمبر 2026 في تطبيق جديد فارغ يعمل بـ Next.js 16.4.5 وnext-intl 4.14.9 وTurbopack (أداة البناء الافتراضية في Next.js 16)، ونسخنا الرسائل كما ظهرت في الطرفية. ثم بنينا كل حل من جديد للتأكد من أنه يعمل.
تمت المراجعة في نوفمبر 2026.
ماذا تقول رسالة الخطأ بالضبط؟
هذه الرسالة كاملة كما يطبعها next build في Next.js 16.4.5. والعبارة التي يبحث عنها المطورون «expected function export name default or proxy function export» مأخوذة من سطرها الأول ومن آخر تلميح فيها.
▲ Next.js 16.4.5 (Turbopack)
Creating an optimized production build ...
> Build error occurred
Error: Turbopack build failed with 1 error:
./proxy.ts
Error: Proxy is missing expected function export name
This function is what Next.js runs for every request handled by this proxy (previously called middleware).
Why this happens:
- You are migrating from `middleware` to `proxy`, but haven't updated the exported function.
- The file exists but doesn't export a function.
- The export is not a function (e.g., an object or constant).
- There's a syntax error preventing the export from being recognized.
To fix it:
- Ensure this file has either a default or "proxy" function export.
Learn more: https://nextjs.org/docs/messages/middleware-to-proxy
ولنفس الخطأ صيغتان أخريان، بحسب طريقة تشغيل التطبيق:
# next build --webpack, and next dev
Error: The file "./proxy.ts" must export a function, either as a default export or as a named "proxy" export.
# next start or next dev, when a request reaches a proxy that exports no function
⨯ [Error: The Proxy file "/proxy" must export a function named `proxy` or a default function.]
والمعنى في الثلاث واحد: فتح Next.js ملف proxy.ts ولم يجد فيه دالة يستطيع استدعاءها مع كل طلب.
ما سبب خطأ «Proxy is missing expected function export name»؟
يقرأ Next.js ما يصدّره proxy.ts وقت البناء، ويبحث عن دالة اسمها proxy أو عن تصدير افتراضي. أي شيء آخر يفشل. وهذه أكثر صورة شائعة، ملف غُيّر اسمه يدويًا:
// proxy.ts (renamed from middleware.ts, function not renamed)
import { NextResponse, type NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
return NextResponse.next();
}
بنينا كل شكل من هذه الأشكال على Next.js 16.4.5. والعمود الثاني يبيّن ما حدث.
| محتوى proxy.ts | النتيجة على 16.4.5 |
|---|---|
export function middleware() | يفشل البناء: missing expected function export name |
export const middleware = ... | يفشل البناء: الخطأ نفسه |
دالة باسم آخر، مثل export function handler() | يفشل البناء: الخطأ نفسه |
export const config = {...} وحده | يفشل البناء: الخطأ نفسه |
| ملف فارغ | يفشل البناء: الخطأ نفسه |
export const middleware = createMiddleware(routing) (next-intl) | يفشل البناء: الخطأ نفسه |
export { default as middleware } from 'next-intl/middleware' | يفشل البناء: الخطأ نفسه |
export * from './other-file' | يفشل البناء: الخطأ نفسه، حتى لو كان الملف الآخر يصدّر proxy |
export { middleware as default } from './old-middleware' | ينجح التجميع (compile)، ثم يفشل عند مرحلة «Collecting page data» برسالة «must export a function» |
export default { ... } (كائن وليس دالة) | ينجح البناء، ثم يعيد كل طلب الخطأ 500 |
export const config = { runtime: 'edge' } | يفشل البناء بخطأ مختلف: Proxy does not support Edge runtime |
middleware.ts وproxy.ts معًا | يفشل البناء: اكتُشف الملفان |
proxy.ts في الجذر بينما التطبيق في src/app | ينجح البناء، لكن الـ proxy لا يعمل أبدًا |
الأسطر الثلاثة الأخيرة ليست خطأ التصدير نفسه، لكنها تظهر أثناء الانتقال نفسه، لذلك نشرحها في الأسفل.
الحل 1: صدّر دالة اسمها proxy
غيّر اسم الدالة إلى proxy. هذا هو الشكل الذي تستخدمه وثائق Next.js، وينجح معه البناء:
// proxy.ts
import { NextResponse, type NextRequest } from 'next/server';
export function proxy(request: NextRequest) {
return NextResponse.next();
}
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};
يمكن أن تكون الدالة async، وتعمل أيضًا الدالة السهمية المسندة إلى export const proxy. بنينا الاثنتين:
// Pick one. Each of these also builds on Next.js 16.4.5.
export async function proxy(request: NextRequest) {
return NextResponse.next();
}
// or
export const proxy = (request: NextRequest) => NextResponse.next();
دالة واحدة في كل ملف. تقول وثائق Next.js إن الملف يجب أن يصدّر دالة واحدة، وإن وجود أكثر من proxy في ملف واحد غير مدعوم.
الحل 2: استخدم التصدير الافتراضي
التصدير الافتراضي يعمل مهما كان اسم الدالة، وحتى الدالة السهمية المجهولة المصدّرة افتراضيًا ينجح معها البناء. ومع ذلك يوصي دليل الترقية في Next.js بتسميتها proxy، ليتطابق اسمها مع اسم الملف:
// proxy.ts
import { NextResponse, type NextRequest } from 'next/server';
export default function proxy(request: NextRequest) {
return NextResponse.next();
}
انتبه لفخ واحد: التصدير الافتراضي يجب أن يكون دالة. في اختبارنا مرّ export default { matcher: ['/'] } من next build، ثم أعادت كل صفحة الخطأ 500 مع الرسالة «The Proxy file "/proxy" must export a function named `proxy` or a default function.». وبعض صيغ إعادة التصدير تفشل أيضًا. استورد الدالة أولًا ثم صدّرها:
// Fails at "Collecting page data" on Next.js 16.4.5
export { middleware as default } from './old-middleware';
// Builds: import first, then export
import { middleware } from './old-middleware';
export default middleware;
كيف أكتب proxy.ts مع next-intl؟
الدالة createMiddleware() في next-intl تعيد دالة، فصدّرها كتصدير افتراضي. هذا هو الإعداد الموجود في وثائق next-intl، والتي تذكر أيضًا أن proxy.ts كان اسمه middleware.ts حتى Next.js 16:
// src/i18n/routing.ts
import { defineRouting } from 'next-intl/routing';
export const routing = defineRouting({
locales: ['en', 'ar'],
defaultLocale: 'en',
});
// src/proxy.ts
import createMiddleware from 'next-intl/middleware';
import { routing } from './i18n/routing';
export default createMiddleware(routing);
export const config = {
// Skip /api, /trpc, /_next, /_vercel and any path with a dot (files)
matcher: '/((?!api|trpc|_next|_vercel|.*\\..*).*)',
};
الصيغة export const proxy = createMiddleware(routing); ينجح معها البناء أيضًا، وهي ما يكتبه codemod الخاص بـ Next.js عندما ينقل ملف next-intl. أما هذه الأشكال فتفشل، لأن الدالة ليست باسم proxy أو لأن Next.js لا يراها وقت البناء:
// src/proxy.ts: these three fail with "missing expected function export name"
export const middleware = createMiddleware(routing);
export { default as middleware } from 'next-intl/middleware';
export * from './intl-proxy';
لتشغيل فحص خاص بك قبل إعادة التوجيه حسب اللغة (تسجيل الدخول، أو ترويسة، أو إعادة توجيه)، اكتب دالة proxy واستدعِ معالج next-intl من داخلها:
// src/proxy.ts: your own check first, then next-intl
import createMiddleware from 'next-intl/middleware';
import { NextResponse, type NextRequest } from 'next/server';
import { routing } from './i18n/routing';
const handleI18nRouting = createMiddleware(routing);
export function proxy(request: NextRequest) {
const isAccount = request.nextUrl.pathname.includes('/account');
const hasSession = request.cookies.has('session');
if (isAccount && !hasSession) {
return NextResponse.redirect(new URL('/en/login', request.url));
}
return handleI18nRouting(request);
}
export const config = {
matcher: '/((?!api|trpc|_next|_vercel|.*\\..*).*)',
};
بنينا هذا الملف، وشغّلناه بالأمر next start -p 3040، وأرسلنا ثلاثة طلبات. اختار الـ proxy اللغة ونفّذ فحص الحساب:
$ curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' http://localhost:3040/
307 http://localhost:3040/en
$ curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' -H 'Accept-Language: ar' http://localhost:3040/
307 http://localhost:3040/ar
$ curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' http://localhost:3040/en/account
307 http://localhost:3040/en/login
إعادة التوجيه هذه هي التي ترسل الزائر نفسه إلى صفحة بالإنجليزية أو بالعربية. هذه الصفحة الرئيسية لقالب المطعم من Aniq UI على /en وعلى /ar:


بعد أن تُحمَّل الصفحات العربية، يجب أن ينقلب التخطيط أيضًا. وهذا عمل CSS وليس عمل الـ proxy: يشرح دليل RTL في Tailwind CSS ضبط dir والأدوات المنطقية والمتغيّر rtl:.
أين أضع proxy.ts: في الجذر أم في src/؟
بجانب مجلد app. تقول وثائق Next.js أن تنشئه في جذر المشروع، أو داخل src إن كنت تستخدمه، بحيث يكون في نفس مستوى app أو pages.
# Without a src folder # With a src folder
my-app/ my-app/
├── app/ ├── src/
├── proxy.ts │ ├── app/
└── package.json │ └── proxy.ts
└── package.json
الملف في المكان الخطأ لا يعطي أي رسالة خطأ. في اختبارنا، ملف proxy.ts في جذر مشروع تطبيقه في src/app نجح بناؤه ولم يعمل أبدًا. وملف proxy.ts داخل مجلد app تجاهله Next.js بالطريقة نفسها. والفحص السريع في نهاية مخرجات next build: عندما يجد Next.js الـ proxy تنتهي قائمة المسارات بهذا السطر:
Route (app)
┌ ○ /
└ ○ /_not-found
ƒ Proxy (Middleware)
إذا لم يظهر السطر ƒ Proxy (Middleware) فـ Next.js لم يجد الملف. وإذا غيّرت pageExtensions في next.config فاسم الملف يتبعها، مثل proxy.page.ts.
هل يسبب matcher في config هذا الخطأ؟
لا. config اختياري، والملف الذي لا يحتوي إلا على config يفشل لأنه بلا دالة، لا بسبب الـ matcher. الـ matcher يحدد المسارات التي يعمل عليها الـ proxy. ومن دونه يعمل الـ proxy على كل طلب، بما في ذلك _next/static والصور وملفات public/. والنمط السالب يستبعدها:
export const config = {
matcher: [
// Everything except API routes, static files, image optimization and metadata files
'/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)',
],
};
يجب أن تكون قيم الـ matcher ثابتة، لأن Next.js يقرؤها وقت البناء. وتقول الوثائق إن القيمة المبنية من متغير يتم تجاهلها. ويجب أن يبدأ كل source بالرمز /.
كيف أنتقل من middleware.ts إلى proxy.ts؟
شغّل الـ codemod الرسمي من جذر المشروع. يغيّر اسم الملف واسم الدالة المصدّرة:
npx @next/codemod@canary middleware-to-proxy .
شغّلناه (الإصدار 16.5.0-canary.41) على middleware.ts في الجذر وعلى src/middleware.ts يستخدم next-intl. تغيّر اسم الملفين واسم الدالتين، ونجح بناء التطبيقين:
// middleware.ts -> proxy.ts
- export function middleware(request: NextRequest) {
+ export function proxy(request: NextRequest) {
// src/middleware.ts -> src/proxy.ts
- export const middleware = createMiddleware(routing);
+ export const proxy = createMiddleware(routing);
لا يعمل إلا على دالة اسمها middleware. عندما جرّبناه على middleware.ts دالته اسمها handler، ترك الملف كما هو، فغيّر في هذه الحالة اسم الملف واسم الدالة يدويًا. والأمر الأشمل npx @next/codemod@canary upgrade latest يتضمن أيضًا خطوة الانتقال من middleware إلى proxy.
أمران آخران أثناء الانتقال:
- ما زال middleware.ts يعمل في 16.4.5 مع تحذير. يطبع البناء التحذير التالي ثم يشغّل الملف. خطّط لتغيير الاسم مع ذلك، لأن هذه التسمية أصبحت مهجورة (deprecated).
- لا تُبقِ الملفين معًا. مع وجود
middleware.tsوproxy.tsجنبًا إلى جنب يتوقف البناء.
⚠ The "middleware" file convention is deprecated. Please use "proxy" instead.
To migrate automatically, run:
npx @next/codemod@canary middleware-to-proxy .
Learn more: https://nextjs.org/docs/messages/middleware-to-proxy
Error: Both middleware file "./middleware.ts" and proxy file "./proxy.ts" are detected. Please use "./proxy.ts" only. Learn more: https://nextjs.org/docs/messages/middleware-to-proxy
وتغيّرت أيضًا أسماء خيارات الإعداد التي كانت تحتوي على كلمة middleware. مثلًا أصبح skipMiddlewareUrlNormalize باسم skipProxyUrlNormalize:
// next.config.ts
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
skipProxyUrlNormalize: true, // was skipMiddlewareUrlNormalize
};
export default nextConfig;
هل يمكن أن يستخدم proxy.ts بيئة Edge؟
لا. يقول دليل الترقية إلى Next.js 16 إن بيئة تشغيل الـ proxy هي nodejs ولا يمكن تغييرها، وإن التطبيقات التي تحتاج إلى بيئة Edge عليها أن تبقى على middleware حاليًا. إضافة export const config = { runtime: 'edge' } إلى proxy.ts أوقفت البناء عندنا بهذه الرسالة:
./proxy.ts:7:14
Error: Next.js can't recognize the exported `config` field in route. Proxy does not support Edge runtime.
> 7 | export const config = { runtime: 'edge' };
احذف سطر runtime. وإذا كنت تعتمد فعلًا على Edge، فأبقِ middleware.ts إلى أن ينشر Next.js تعليماته اللاحقة.
قائمة فحص في دقيقة واحدة
- اسم الملف
proxy.ts(أو.js) وهو بجانبapp: في الجذر أو داخلsrc/. - يصدّر
function proxyأو دالة افتراضية، ولم يبقَ فيه اسمmiddleware. - مع next-intl يكون السطر
export default createMiddleware(routing);. - لا يوجد ملف
middleware.tsبجانبه. - في
configقيمةmatcherثابتة ولا يوجدruntime. - تنتهي مخرجات
next buildبالسطرƒ Proxy (Middleware)، والطلب فيnext startلا يعيد 500.
الأسئلة الشائعة
لماذا يظهر خطأ «missing expected function export name» في proxy.ts بعد الترقية إلى Next.js 16؟
لأن اسم الملف تغيّر ولم يتغيّر اسم الدالة. لا يقبل Next.js 16 في proxy.ts إلا دالة اسمها proxy أو تصديرًا افتراضيًا، لذلك يفشل export function middleware. غيّر اسمها إلى proxy، أو شغّل npx @next/codemod@canary middleware-to-proxy .
هل يمكنني الإبقاء على middleware.ts في Next.js 16؟
نعم، حاليًا. في Next.js 16.4.5 ما زال middleware.ts ينجح بناؤه ويعمل، مع تحذير بأنه مهجور. وهو أيضًا الخيار الموثّق إذا كنت تحتاج إلى بيئة Edge. لكن لا تتركه أبدًا بجانب proxy.ts: يتوقف البناء عند وجود الملفين.
هل يعمل next-intl مع proxy.ts؟
نعم. تستخدم وثائق next-intl الملف src/proxy.ts مع export default createMiddleware(routing); والـ matcher '/((?!api|trpc|_next|_vercel|.*\\..*).*)'. بنيناه وشغّلناه مع next-intl 4.14.9 على Next.js 16.4.5.
لماذا ينجح البناء ثم تعيد كل صفحة الخطأ 500؟
غالبًا لأن التصدير الافتراضي ليس دالة، بل كائنًا مثلًا. قبله البناء في اختبارنا، ثم فشل كل طلب مع الرسالة «The Proxy file "/proxy" must export a function named `proxy` or a default function.». صدّر دالة بدلًا منه.
أين أضع proxy.ts إذا كنت أستخدم مجلد src؟
في src/proxy.ts بجانب src/app. في هذا التنظيم يتجاهل Next.js أي proxy.ts في الجذر دون رسالة خطأ، فتأكد أن next build يعرض ƒ Proxy (Middleware).
هل يختلف الخطأ مع webpack؟
تختلف الصياغة فقط. مع next build --webpack تكون الرسالة «The file "./proxy.ts" must export a function, either as a default export or as a named "proxy" export.». والحل نفسه.
الخلاصة
يعود هذا الخطأ دائمًا إلى سطر واحد: سطر التصدير. سمِّ الدالة proxy أو صدّرها افتراضيًا، وأبقِ الملف بجانب app، واحذف middleware.ts القديم. ومع next-intl يكون هذا السطر export default createMiddleware(routing);. بعد ذلك تأكد أن next build يعرض الـ proxy، وأرسل طلبًا حقيقيًا قبل النشر.
قوالب فيها proxy.ts وnext-intl جاهزان
إذا فضّلت أن تبدأ من كود يعمل فيه كل هذا مسبقًا، فكل قوالب Aniq UI المدفوعة تعمل على Next.js 16 مع src/proxy.ts وnext-intl، بالإنجليزية والعربية مع تخطيط حقيقي من اليمين إلى اليسار. فتحنا المستودعات يوم 5 نوفمبر 2026: كل تطبيق فيها على Next.js 16.3 أو 16.4، والحلّان المشروحان هنا مستخدمان فيها. صفحة هبوط SaaS تستخدم export default createMiddleware(routing)، وقالب المطعم يستخدم export async function proxy.


سعر كل نوع، بدفعة واحدة، مع الكود المصدري:
- المواقع والمتاجر (مطاعم، عقارات، منصات تعليم، متاجر إلكترونية، تأجير سياحي، بيع تذاكر الفعاليات): $39.
- صفحات الهبوط (SaaS وPublino): $39.
- لوحات التحكم: من $49 (لوحة التحكم المالية بسعر $49، ولوحة التحكم بالمساعد الذكي ولوحة اللياقة البدنية بسعر $69).
- الـ API الخلفي: $99.
- Full Stack (الموقع ولوحة التحكم والـ API معًا): $149.
- القوالب العشرة كلها: الحزمة، بسعر قائمة $499. راجع الصفحة لمعرفة العرض الحالي.
تصفّح القوالب وافتح أي عرض حي بالعربية قبل الشراء.
أدلة ذات صلة
- next-intl nextjs 16: تخزين المكونات مؤقتًا مع root-params
- دليل RTL في Tailwind CSS: الخصائص المنطقية والمتغيّر rtl:
- كيف تطلق موقع SaaS بالإنجليزية والعربية باستخدام Next.js
- قوالب لوحات تحكم عربية بـ Next.js تدعم RTL: 9 لوحات من Aniq UI
المصادر
- Next.js: اصطلاح الملف proxy.js (التصدير، الـ matcher، بيئة التشغيل، الانتقال)
- Next.js: الترقية إلى الإصدار 16 (من middleware إلى proxy، بيئة Edge، الخيارات التي تغيّر اسمها)
- Next.js: Renaming Middleware to Proxy (الرابط الموجود في رسالة الخطأ)
- next-intl: Proxy / middleware
- next-intl: إعداد App Router مع توجيه i18n
اختُبر مع Next.js 16.4.5 وnext-intl 4.14.9 وReact 19.3.1 وTypeScript 5.9.3 على Node.js 24.17.0. تمت المراجعة في نوفمبر 2026.
قد يعجبك أيضًا

دليل RTL في Tailwind CSS: الخصائص المنطقية والمتغيّر rtl:
ابنِ واجهات RTL باستخدام Tailwind CSS 4 وnext-intl: ضبط dir وlang لكل لغة، والأدوات المنطقية، والمتغيّر rtl:، والخطوط العربية، وقائمة اختبار.

أفضل خطوط عربية للمواقع (2026): 12 خطًا جربناها في لوحة تحكم
أفضل خطوط عربية للويب جربناها في لوحة تحكم حقيقية: 12 خطًا مجانيًا، والأوزان والأرقام وارتفاع السطر والخط اللاتيني المناسب، وطريقة إضافتها في Next.js.

موارد المطوّرين في قوالب Next.js: الأنواع والمكوّنات والأنماط والتوثيق
ما الذي يأتي داخل قالب Next.js مميز: أنواع TypeScript صارمة، وبنية مكوّنات قائمة على الميزات، وأنماط شيفرة قابلة لإعادة الاستخدام، وتوثيق للبدء السريع، مع قائمة تحقق لفحص أي قالب.