Fix for NextResponse.redirect going to wrong host (localhost:8080) on Railway, Vercel, or containerized deployments.
When deploying Next.js to Railway, Vercel, or similar containerized platforms,
request.url in Edge runtime or API routes can return the internal proxy URL
(e.g., http://localhost:8080) instead of the public domain (e.g., https://example.com).
This causes NextResponse.redirect(new URL(path, request.url)) to redirect users
to the internal URL, which fails with ERR_CONNECTION_REFUSED.
ERR_CONNECTION_REFUSED to localhost:8080 or similarFailed to fetch RSC payload followed by connection refusedhttps://localhost:8080/...new URL('/path', request.url) for redirectsReplace request.url with an environment variable for the public URL:
// Before (broken on containerized platforms):
return NextResponse.redirect(
new URL(`/not-found?code=${shortCode}`, request.url)
);
// After (works everywhere):
const baseUrl = process.env.NEXT_PUBLIC_APP_URL || "https://example.com";
return NextResponse.redirect(
new URL(`/not-found?code=${shortCode}`, baseUrl)
);
For reusable code, create a helper:
const getBaseUrl = () =>
process.env.NEXT_PUBLIC_APP_URL || "https://example.com";
ERR_CONNECTION_REFUSEDFile: app/[shortCode]/route.ts
// Add helper at module level
const getBaseUrl = () =>
process.env.NEXT_PUBLIC_APP_URL || "https://clicktowa.com";
export async function GET(request: NextRequest, { params }) {
const { shortCode } = await params;
const baseUrl = getBaseUrl();
// ... lookup logic ...
if (!link) {
// Use baseUrl instead of request.url
return NextResponse.redirect(
new URL(`/not-found?code=${encodeURIComponent(shortCode)}`, baseUrl)
);
}
// ... rest of handler
}
This issue occurs because containerized platforms route traffic through internal
load balancers/proxies. The request.url reflects the internal connection, not
the original public request.
Some platforms set headers like X-Forwarded-Host or X-Original-Host, but
these aren't automatically used by request.url.
The NEXT_PUBLIC_ prefix makes the variable available in both client and server
code, which is appropriate for the public URL.
Always provide a sensible fallback in case the env var isn't set.
This also affects request.headers.get('host') in some configurations—always
prefer explicit environment variables for public URLs.
NEXT_PUBLIC_APP_URL