Error proxy.ts en Next.js 16: missing expected function export
Soluciona el error de Next.js 16 "Proxy is missing expected function export name": causas probadas en 16.4.5, exports que compilan y next-intl.

Next.js 16 detiene el build con el error "Proxy is missing expected function export name" cuando proxy.ts no exporta una función llamada proxy ni una función por defecto. La causa habitual es un archivo renombrado desde middleware.ts que todavía dice export function middleware. Cambia el nombre de esa función a proxy, o expórtala por defecto, y el build pasa.
Reproducimos cada caso de esta página el 5 de noviembre de 2026 en una app limpia con Next.js 16.4.5, next-intl 4.14.9 y Turbopack (el bundler por defecto de Next.js 16), y copiamos los mensajes tal cual desde la terminal. Cada solución se volvió a compilar para confirmar que funciona.
Revisado en noviembre de 2026.
¿Qué dice exactamente el error?
Este es el mensaje completo de next build en Next.js 16.4.5. La frase que se busca, "expected function export name default or proxy function export", sale de su primera línea y de su última indicación.
▲ 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
El mismo error tiene otras dos redacciones, según cómo ejecutes la app:
# 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.]
Los tres significan lo mismo: Next.js abrió proxy.ts y no encontró ninguna función que pudiera llamar en cada petición.
¿Qué causa "Proxy is missing expected function export name"?
Next.js lee los exports de proxy.ts al compilar y busca una función llamada proxy o un export por defecto. Todo lo demás falla. Este es el caso más común, un archivo renombrado a mano:
// proxy.ts (renamed from middleware.ts, function not renamed)
import { NextResponse, type NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
return NextResponse.next();
}
Compilamos cada una de estas formas en Next.js 16.4.5. La columna de la derecha muestra lo que pasó.
| Contenido de proxy.ts | Resultado en 16.4.5 |
|---|---|
export function middleware() | El build falla: missing expected function export name |
export const middleware = ... | El build falla: mismo error |
Una función con otro nombre, como export function handler() | El build falla: mismo error |
Solo export const config = {...} | El build falla: mismo error |
| Un archivo vacío | El build falla: mismo error |
export const middleware = createMiddleware(routing) (next-intl) | El build falla: mismo error |
export { default as middleware } from 'next-intl/middleware' | El build falla: mismo error |
export * from './other-file' | El build falla: mismo error, aunque el otro archivo exporte proxy |
export { middleware as default } from './old-middleware' | Compila y luego falla en "Collecting page data" con "must export a function" |
export default { ... } (un objeto, no una función) | El build pasa, y luego cada petición devuelve 500 |
export const config = { runtime: 'edge' } | El build falla con otro error: Proxy does not support Edge runtime |
middleware.ts y proxy.ts juntos | El build falla: se detectan los dos archivos |
proxy.ts en la raíz mientras la app está en src/app | El build pasa, pero el proxy nunca se ejecuta |
Las tres últimas filas no son el error de export, pero aparecen durante la misma migración, así que las vemos más abajo.
Solución 1: exporta una función llamada proxy
Cambia el nombre de la función a proxy. Es la forma que usa la documentación de Next.js, y compila:
// 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).*)'],
};
La función puede ser async, y una función flecha asignada a export const proxy también funciona. Compilamos las dos:
// 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();
Usa una sola función por archivo. La documentación de Next.js dice que el archivo debe exportar una única función y que no se admiten varios proxies en el mismo archivo.
Solución 2: usa un export por defecto
Un export por defecto funciona se llame como se llame la función, y una función flecha anónima exportada por defecto también compila. Aun así, la guía de actualización de Next.js recomienda llamarla proxy, para que el nombre y el archivo coincidan:
// proxy.ts
import { NextResponse, type NextRequest } from 'next/server';
export default function proxy(request: NextRequest) {
return NextResponse.next();
}
Una trampa: el export por defecto tiene que ser una función. export default { matcher: ['/'] } pasó next build en nuestra prueba, y después cada página devolvió 500 con "The Proxy file "/proxy" must export a function named `proxy` or a default function." Algunos re-exports también fallan. Importa primero la función y luego expórtala:
// 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;
¿Cómo se escribe proxy.ts con next-intl?
createMiddleware() de next-intl devuelve una función, así que expórtala por defecto. Es la configuración de la documentación de next-intl, que también recuerda que proxy.ts se llamaba middleware.ts hasta 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); también compila, y es lo que escribe el codemod de Next.js cuando migra un archivo de next-intl. Estas formas fallan, porque la función no se llama proxy o Next.js no la ve al compilar:
// 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';
Para hacer tu propia comprobación antes de la redirección de idioma (inicio de sesión, una cabecera, una redirección), escribe una función proxy y llama desde dentro al handler de 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|.*\\..*).*)',
};
Compilamos este archivo, lo arrancamos con next start -p 3040 y enviamos tres peticiones. El proxy eligió el idioma e hizo la comprobación de la cuenta:
$ 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
Esa redirección es la que lleva al mismo visitante a una página en inglés o en árabe. Esta es la página de inicio de la plantilla de restaurante de Aniq UI en /en y en /ar:


Cuando las páginas en árabe cargan, el diseño también tiene que invertirse. Esa parte es CSS, no el proxy: la guía RTL de Tailwind CSS explica dir, las utilidades lógicas y la variante rtl:.
¿Dónde va proxy.ts: en la raíz o en src/?
Junto a tu carpeta app. La documentación de Next.js indica crearlo en la raíz del proyecto, o dentro de src si usas una, al mismo nivel que app o pages.
# Without a src folder # With a src folder
my-app/ my-app/
├── app/ ├── src/
├── proxy.ts │ ├── app/
└── package.json │ └── proxy.ts
└── package.json
Un archivo en el lugar equivocado no da ningún error. En nuestra prueba, un proxy.ts en la raíz de un proyecto con la app en src/app compiló sin problemas y nunca se ejecutó. Un proxy.ts dentro de la carpeta app se ignoró de la misma forma. La comprobación rápida está al final de la salida de next build. Cuando Next.js encuentra tu proxy, la lista de rutas termina con esta línea:
Route (app)
┌ ○ /
└ ○ /_not-found
ƒ Proxy (Middleware)
Si falta la línea ƒ Proxy (Middleware), Next.js no encontró el archivo. Si cambiaste pageExtensions en next.config, el nombre del archivo sigue esa regla, por ejemplo proxy.page.ts.
¿El matcher de config causa este error?
No. config es opcional, y un archivo que solo tiene config falla porque no hay función, no por el matcher. El matcher decide en qué rutas se ejecuta el proxy. Sin matcher, el proxy se ejecuta en cada petición, incluidos _next/static, las imágenes y los archivos de public/. Un patrón negativo los deja fuera:
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).*)',
],
};
Los valores del matcher deben ser constantes, porque Next.js los lee al compilar. La documentación dice que un valor construido con una variable se ignora. Cada source debe empezar por /.
¿Cómo migrar de middleware.ts a proxy.ts?
Ejecuta el codemod oficial desde la raíz del proyecto. Renombra el archivo y la función exportada:
npx @next/codemod@canary middleware-to-proxy .
Lo ejecutamos (versión 16.5.0-canary.41) sobre un middleware.ts en la raíz y sobre un src/middleware.ts con next-intl. Los dos archivos y las dos funciones se renombraron, y las dos apps compilaron:
// 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);
Solo actúa sobre una función llamada middleware. Cuando probamos un middleware.ts cuya función se llamaba handler, el codemod dejó el archivo como estaba, así que en ese caso renombra el archivo y la función a mano. El comando más amplio npx @next/codemod@canary upgrade latest también incluye el paso de middleware a proxy.
Dos cosas más durante la migración:
- middleware.ts sigue funcionando en 16.4.5, con un aviso. El build muestra el aviso de abajo y ejecuta el archivo. Planifica el cambio de nombre de todos modos, porque la convención está obsoleta.
- No mantengas los dos archivos. Con
middleware.tsyproxy.tsjuntos, el build se detiene.
⚠ 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
Las opciones de configuración que llevaban "middleware" en el nombre también cambiaron. Por ejemplo, skipMiddlewareUrlNormalize ahora es skipProxyUrlNormalize:
// next.config.ts
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
skipProxyUrlNormalize: true, // was skipMiddlewareUrlNormalize
};
export default nextConfig;
¿Puede proxy.ts usar el runtime Edge?
No. La guía de actualización a Next.js 16 dice que el runtime del proxy es nodejs, que no se puede configurar, y que las apps que necesitan el runtime Edge deben seguir usando middleware por ahora. Añadir export const config = { runtime: 'edge' } a proxy.ts detuvo nuestro build con este mensaje:
./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' };
Quita la línea runtime. Si de verdad dependes de Edge, mantén middleware.ts hasta que Next.js publique sus próximas instrucciones.
Comprobación en un minuto
- El archivo se llama
proxy.ts(o.js) y está junto aapp: en la raíz o ensrc/. - Exporta
function proxyo una función por defecto. No queda ningún nombremiddleware. - Con next-intl, la línea es
export default createMiddleware(routing);. - No hay un
middleware.tsal lado. configtiene unmatcherconstante y ningúnruntime.next buildtermina conƒ Proxy (Middleware), y una petición ennext startno devuelve 500.
Preguntas frecuentes
¿Por qué proxy.ts dice "missing expected function export name" después de actualizar a Next.js 16?
Porque se renombró el archivo, pero no la función. Next.js 16 solo acepta en proxy.ts una función llamada proxy o un export por defecto, así que export function middleware falla. Renómbrala a proxy, o ejecuta npx @next/codemod@canary middleware-to-proxy .
¿Puedo seguir usando middleware.ts en Next.js 16?
Sí, por ahora. En Next.js 16.4.5 un middleware.ts todavía compila y se ejecuta, con un aviso de obsolescencia. También es la opción documentada si necesitas el runtime Edge. Nunca lo dejes junto a un proxy.ts: el build se detiene cuando existen los dos.
¿next-intl funciona con proxy.ts?
Sí. La documentación de next-intl usa src/proxy.ts con export default createMiddleware(routing); y el matcher '/((?!api|trpc|_next|_vercel|.*\\..*).*)'. Lo compilamos y ejecutamos con next-intl 4.14.9 en Next.js 16.4.5.
¿Por qué el build pasa pero cada página devuelve 500?
Seguramente tu export por defecto no es una función, por ejemplo un objeto. El build lo aceptó en nuestra prueba, y luego cada petición falló con "The Proxy file "/proxy" must export a function named `proxy` or a default function." Exporta una función.
¿Dónde pongo proxy.ts si uso una carpeta src?
En src/proxy.ts, junto a src/app. Con esa estructura, un proxy.ts en la raíz se ignora sin ningún error, así que comprueba que next build muestre ƒ Proxy (Middleware).
¿El error es distinto con webpack?
Solo cambia la redacción. Con next build --webpack el mensaje es "The file "./proxy.ts" must export a function, either as a default export or as a named "proxy" export." La solución es la misma.
Conclusión
Este error siempre se reduce a una línea: el export. Llama a la función proxy o expórtala por defecto, deja el archivo junto a app y borra el antiguo middleware.ts. Con next-intl, esa línea es export default createMiddleware(routing);. Después comprueba que next build muestre el proxy y envía una petición real antes de desplegar.
Plantillas con proxy.ts y next-intl listos
Si prefieres empezar con un código donde esto ya funciona, todas las plantillas de pago de Aniq UI usan Next.js 16 con src/proxy.ts y next-intl, en inglés y en árabe con un diseño de derecha a izquierda real. Abrimos los repositorios el 5 de noviembre de 2026: cada app está en Next.js 16.3 o 16.4, y se usan las dos soluciones de esta guía. La landing page SaaS usa export default createMiddleware(routing), y la plantilla de restaurante usa export async function proxy.


Lo que cuesta cada una, en un solo pago, con el código fuente:
- Sitios web y tiendas (restaurante, inmobiliaria, LMS, e-commerce, alquiler vacacional, venta de entradas): $39.
- Landing pages (SaaS y Publino): $39.
- Dashboards de administración: desde $49 (el dashboard financiero cuesta $49, el dashboard de administración con IA y el de fitness $69).
- API backend: $99.
- Full stack (sitio, dashboard y API juntos): $149.
- Las 10 plantillas: el paquete, precio de lista $499. Consulta la página para ver la oferta actual.
Explora las plantillas y abre cualquier demo en árabe antes de comprar.
Guías relacionadas
- next-intl nextjs 16: Caché de componentes con root-params
- Guía RTL de Tailwind CSS: propiedades lógicas y la variante rtl:
- Cómo lanzar un sitio web SaaS en inglés y árabe con Next.js
- Plantillas de dashboard en árabe RTL para Next.js: 9 de Aniq UI
Fuentes
- Next.js: convención de archivo proxy.js (exports, matcher, runtime, migración)
- Next.js: cómo actualizar a la versión 16 (de middleware a proxy, runtime Edge, opciones renombradas)
- Next.js: Renaming Middleware to Proxy (el enlace del mensaje de error)
- next-intl: Proxy / middleware
- next-intl: configuración del App Router con enrutamiento i18n
Probado con Next.js 16.4.5, next-intl 4.14.9, React 19.3.1 y TypeScript 5.9.3 en Node.js 24.17.0. Revisado en noviembre de 2026.
También te puede interesar

Guía RTL de Tailwind CSS: propiedades lógicas y la variante rtl:
Crea diseños RTL con Tailwind CSS 4 y next-intl: dir y lang por idioma, utilidades lógicas, la variante rtl:, fuentes árabes y un checklist de pruebas.

Recursos para desarrolladores en plantillas Next.js: tipos, componentes, patrones y documentación
Qué incluye una plantilla premium de Next.js: tipos estrictos de TypeScript, una arquitectura de componentes organizada por funcionalidades, patrones de código reutilizables y documentación de inicio rápido, con una checklist para cualquier plantilla.

next-intl nextjs 16: Caché de componentes con root-params
Domina la integración de next-intl en nextjs 16 aprovechando next/root-params para habilitar la caché de componentes de forma segura sin prop-drilling de tu locale.