Desplegar Next.js + Express en Vercel: el bug del bucle 308
Mario Rojas
1 min de lectura

Tenía el frontend (Next.js) y el backend (Express) en dos proyectos de Vercel. Todo funcionaba en local, pero en producción el login fallaba con un mensaje genérico: "No se pudo conectar con el servidor".
La configuración
Next.js reenviaba las llamadas /api/* al backend con un rewrite:
async rewrites() {
return [{ source: "/api/:path*", destination: `${API_URL}/api/:path*` }];
}
El síntoma
En la pestaña Network el navegador mostraba la misma petición una y otra vez:
GET /api/users/profile 308 → Location: /api/users/profile
GET /api/users/profile 308 → Location: /api/users/profile
...
Un bucle infinito hasta que el navegador se rendía.
La causa
La variable API_URL en Vercel tenía una barra al final:
API_URL=https://mi-backend.vercel.app/
Así que el destino quedaba con doble barra: https://mi-backend.vercel.app//api/users/profile. El backend respondía con una redirección relativa a /api/users/profile, el navegador la resolvía sobre el dominio del frontend… y volvía a entrar al rewrite.
Lo curioso: las páginas que pedían datos desde el servidor funcionaban, porque fetch en Node seguía la redirección hacia el backend. Solo fallaba lo que pasaba por el navegador.
La solución
Normalizar la URL en el código para que una barra de más no rompa nada:
const API_URL = (process.env.API_URL || "http://localhost:5000").replace(/\/+$/, "");
Y corregir la variable en Vercel.
Lo que aprendí
- Los rewrites se calculan en el build: si cambias la variable, hay que volver a desplegar.
- Ante un error genérico, ve a la pestaña Network y mira el status real.
- Probar los endpoints con
curl -Ite dice en segundos si hay redirecciones raras.