Production build infinite loop
Answered
Transvaal lion posted this in #help-forum
Transvaal lionOP
I have a very simple nextjs app with just a single root endpoint and a middleware that delegates all the requests to root.
To call it one needs to do just
Whenever I am running
On the other hand, if I run
Why would that be?
To call it one needs to do just
curl -X GET localhost:3000/
.Whenever I am running
next start
, on the console I see that my endpoint is being constantly called. I see logs like "endpoint called" hundreds of times. On the other hand, if I run
next dev
, there is no such problem. Why would that be?
Answered by Transvaal lion
Alright, I solved it. The issue is that the middleware would catch every request and redirect it to root. I had to use
i.e.
NextResponse.next()
instead of NextResponse.rewrite()
in cases where the request was already at the root
. i.e.
export function middleware(request: NextRequest) {
const urlOriginal = extractUrlFrom(request)
const alreadyAtRoot = request.nextUrl.pathname === '/'
if (alreadyAtRoot) {
const response = NextResponse.next()
response.headers.set('x-original-url', urlOriginal)
return response
}
const urlRedirect = new URL('/', request.url)
const response = NextResponse.rewrite(urlRedirect)
response.headers.set('x-original-url', urlOriginal)
return response
}
7 Replies
show your middleware @Transvaal lion
Transvaal lionOP
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const urlRedirect = new URL('/', request.url)
const response = NextResponse.rewrite(urlRedirect)
const urlOriginal = extractUrlFrom(request)
response.headers.set('x-original-url', urlOriginal)
return response
}
export const config = {
matcher: '/(.*)',
}
function extractUrlFrom(request: NextRequest): string {
const hostname = request.headers.get('x-forwarded-host') ?? request.headers.get('host')
if (!hostname) {
throw new Error('No hostname found in request header')
}
return `${request.nextUrl.protocol}//${hostname}${request.nextUrl.pathname}`
}
I use it so that I can be able to delegate the whole URLs to my endpoint.
Nextjs for some reason truncates subdomains, plus it yields an error (rightfully so) when the URL tries to access an endpoint that does not exist. However, I don't want it to panic.
i.e. I need to forward paths like this
Nextjs for some reason truncates subdomains, plus it yields an error (rightfully so) when the URL tries to access an endpoint that does not exist. However, I don't want it to panic.
i.e. I need to forward paths like this
https://subsubdomain.subdomain.domain.localhost:3000/any/path/of/any/length
to my root endpoint /
.can you rename your middleware file to something like middleware-test and then check if it still happens
@Transvaal lion
Transvaal lionOP
Renaming the
I tried this and -as expected-, requests were sent directly to the endpoint, and the middleware was no longer used.
middleware.ts
to something else will stop being used by the app.I tried this and -as expected-, requests were sent directly to the endpoint, and the middleware was no longer used.
Transvaal lionOP
Alright, I solved it. The issue is that the middleware would catch every request and redirect it to root. I had to use
i.e.
NextResponse.next()
instead of NextResponse.rewrite()
in cases where the request was already at the root
. i.e.
export function middleware(request: NextRequest) {
const urlOriginal = extractUrlFrom(request)
const alreadyAtRoot = request.nextUrl.pathname === '/'
if (alreadyAtRoot) {
const response = NextResponse.next()
response.headers.set('x-original-url', urlOriginal)
return response
}
const urlRedirect = new URL('/', request.url)
const response = NextResponse.rewrite(urlRedirect)
response.headers.set('x-original-url', urlOriginal)
return response
}
Answer