NextJS 15 + AuthV5在Bolt.new用npm登录时出现请求域错误
NextJS 15 + Auth.js V5 凭证登录报错:
headers was called outside a request scope 问题描述
在NextJS 15与Auth.js V5项目中,使用凭证登录时触发以下错误:
Error:
headerswas called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context
已完成的测试场景:
- 本地环境用
npm/bun运行:完全正常 - Vercel平台用
npm/bun部署运行:完全正常 - 仅在Bolt.new平台用
npm运行时出现该错误
相关简化代码
/auth/signin/page.ts
import { AuthForm } from "@/components/auth/auth-form"; import { login } from "@/app/actions/auth-actions"; export default function SignInPage() { return <AuthForm type="signin" action={login} />; }
auth-action.ts
"use server"; import { signIn, signOut } from "@/auth"; export const login = async (values: z.infer<typeof SignInSchema>) => { // ... 表单验证逻辑 try { await signIn("credentials", { email, password, redirectTo: DEFAULT_LOGIN_REDIRECT(existingUser.defaultWorkspaceId!), }); return { success: "Logged in!" }; } catch (error) { // ... 错误处理逻辑 }; }
表单客户端组件
"use client"; // ... 导入依赖 export function AuthForm({ type, action }: AuthFormProps) { // ... Formik/React Hook Form 初始化逻辑 function onSubmit(values: z.infer<typeof schema>) { setError(""); setSuccess(""); startTransition(() => { action(values).then((data) => { setError(data?.error); setSuccess(data?.success); }); }); } return ( <Form {...form}> <form onSubmit={form.handleSubmit(onSubmit)}> {/* ... 输入框、提交按钮等表单元素 */} </form> </Form> ); }
auth.ts
export const { handlers: { GET, POST }, auth, signIn, signOut, } = NextAuth({ pages: { signIn: "/auth/signin", error: "/auth/error", }, callbacks: { async signIn({ user, account }) { if (account?.provider !== "credentials") return true; const existingUser = await getUserById(user.id!); if (!existingUser || !existingUser?.emailVerified) return false; return true; }, // ... 其他回调逻辑 });
解决方案
结合场景差异(仅Bolt.new报错),核心原因是平台对NextJS请求上下文的处理或静态优化策略不同,以下是针对性修复步骤:
1. 强制登录页面动态渲染
Bolt.new可能默认对页面做了静态预渲染,导致页面在无请求上下文的环境下初始化,进而引发Server Action的上下文错误。在登录页面添加动态渲染指令:
// /auth/signin/page.ts import { AuthForm } from "@/components/auth/auth-form"; import { login } from "@/app/actions/auth-actions"; // 强制页面每次请求都动态渲染,确保请求上下文存在 export const dynamic = "force-dynamic"; export default function SignInPage() { return <AuthForm type="signin" action={login} />; }
2. 改用NextJS原生formAction调用Server Action
手动在startTransition中调用Server Action可能存在上下文传递问题,改用原生表单绑定方式:
// 表单客户端组件修改 export function AuthForm({ type, action }: AuthFormProps) { // ... 表单初始化逻辑 return ( <Form {...form}> <form action={action} onSubmit={form.handleSubmit((values) => { setError(""); setSuccess(""); })}> {/* ... 表单元素 */} <button type="submit">登录</button> </form> </Form> ); }
3. 检查redirectTo生成逻辑
确保DEFAULT_LOGIN_REDIRECT函数没有调用依赖请求上下文的API(如headers()、auth()),如果有这类逻辑,需移到Server Action的请求上下文内执行。
4. 验证Bolt.new的Node.js版本
确认Bolt.new使用的Node.js版本与本地/Vercel一致(NextJS 15推荐Node.js 18+),版本差异可能导致上下文处理不一致。
内容的提问来源于stack exchange,提问作者everspader
相关产品推荐
相关产品推荐

