server actions redirect issue
I have a login page in a [domain]/login/page.tsx that calls a server action.
revalidatePath("/");
redirect('/?test=test');
// tried also
// redirect('http://tenant1.localhost:3000?test=test');
In the login page of a site e.g: http://tenant1.localhost:3000/login
when you successfully logged in it does redirect to http://tenant1.localhost:3000/ but the page shown is the home page of the platform not the tenant but when you refresh manually you get the home page of the tenant.
I have added a console.log in the middleware.
export default async function middleware(req: NextRequest) {
const url = req.nextUrl;
// Get hostname of request (e.g. demo.vercel.pub, demo.localhost:3000)
let hostname = req.headers
.get("host")!
.replace(".localhost:3000", `.${clientEnv.NEXT_PUBLIC_ROOT_DOMAIN}`);
const searchParams = req.nextUrl.searchParams.toString();
// Get the pathname of the request (e.g. /, /about, /blog/first-post)
const path = `${url.pathname}${
searchParams.length > 0 ? `?${searchParams}` : ""
}`;
console.log({ hostname, path });
//...
}
Same log output for redirect("/?test=test") and redirect('http://tenant1.localhost:3000?test=test')
{ hostname: 'org1.localhost:3000', path: '/login' }
{ hostname: 'localhost:3000', path: '/?test=test' }
POST /login 303 in 168ms
{ hostname: 'org1.localhost:3000', path: '/?test=test' }
so it looks like the issue is that redirect in server actions does not care about the subdomain.
Only tested this locally on next v14.2.3
Looks to be related to this issue https://github.com/vercel/next.js/issues/65893#issue-2303215033
does not make sense but the solution here amazingly worked for me. https://github.com/vercel/next.js/issues/65893#issuecomment-2132081500
redirect("./");
does not make sense but the solution here amazingly worked for me. vercel/next.js#65893 (comment)
redirect("./");
This solution is flawed when the server action is triggered from a differently nested path you'll be redirected to the current path which would result in 404.
e.g: logout action has redirect('./login')
if logout action is triggered at /profile or / you're redirected to /login but if logout action is triggered at /profile/activity you're redirected to /profile/login.
better solution I found is to use .get("x-forwarded-host") instead of .get("host")
// Get hostname of request (e.g. demo.vercel.pub, demo.localhost:3000)
const hostname = req.headers
.get("x-forwarded-host")!
.replace(".localhost:3000", `.${clientEnv.NEXT_PUBLIC_ROOT_DOMAIN}`);
👋 We've updated this repo to have a more simplified example + a new guide:
- https://github.com/vercel/platforms/pull/451
- https://vercel.com/guides/nextjs-multi-tenant-application