You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next 13.4调用getServerSession触发Dynamic server usage错误求助

问题解决:Next 13.4 中 RSC 调用 getServerSession 触发 Dynamic server usage: headers 错误

你遇到的核心问题是:Next.js 13.4 的 React Server Component(RSC,如 layout/page)默认会尝试静态渲染,但 getServerSession 需要访问请求头(headers)这类动态资源,静态渲染上下文无法提供,因此触发错误。以下是具体排查思路和解决方案:


解决方案 1:强制组件为动态渲染

在你的 RootLayout 所在文件顶部添加动态渲染标识,让 Next.js 明确该组件需要在每次请求时动态执行:

export const dynamic = "force-dynamic";

export default async function RootLayout({ children, params: { lng } }: Props) {
  // 原有代码保持不变
  const clients = await getClients()
  return (
    <>
      {/* ... */}
    </>
  )
}

添加后,组件会放弃静态渲染,完整访问请求上下文,getServerSession 就能正常获取 session。

解决方案 2:适配 App Router 的 authOptions 配置

确保你的 authOptions 完全兼容 App Router,避免配置缺失导致的上下文错误:

// authOptions 示例配置
import type { NextAuthOptions } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";

export const authOptions: NextAuthOptions = {
  providers: [
    CredentialsProvider({
      // 你的登录验证逻辑
      async authorize(credentials) {
        // 验证后返回包含 token 的用户对象
        return { id: "1", name: "User", token: "xxx" };
      },
    }),
  ],
  secret: process.env.NEXTAUTH_SECRET,
  session: {
    strategy: "jwt", // 推荐使用 JWT 策略,减少动态依赖
  },
  callbacks: {
    async jwt({ token, user }) {
      if (user) token.token = user.token; // 将用户 token 存入 JWT
      return token;
    },
    async session({ session, token }) {
      session.user.token = token.token; // 同步 token 到 session 对象
      return session;
    },
  },
};

确认 getServerSession 调用时正确传入了该配置,无参数遗漏。

解决方案 3:将动态逻辑拆分到客户端组件

如果不想让整个布局变为动态,可以把需要 session 的部分拆分到客户端组件中:

  1. 给 TeamSwitcher 添加客户端标识(文件顶部加 'use client')
  2. 在客户端组件中用 useSession 钩子获取 token 并请求数据:
'use client';

import { useSession } from "next-auth/react";
import { useEffect, useState } from "react";
import type { Client } from "@/types";

export function TeamSwitcher() {
  const { data: session } = useSession();
  const [clients, setClients] = useState<Client[]>([]);

  useEffect(() => {
    async function fetchClients() {
      if (!session?.user?.token) return;
      const res = await fetch("/api/clients", {
        headers: {
          accept: "application/json",
          token: session.user.token,
        },
      });
      const data = await res.json();
      setClients(data);
    }
    fetchClients();
  }, [session]);

  // 渲染 clients 逻辑
  return (
    <div>{clients.map(client => <div key={client.id}>{client.name}</div>)}</div>
  );
}

这样布局保持静态渲染,仅客户端组件处理动态数据请求。


排查思路

  • 检查组件静态化状态:Next.js 启动日志会标注哪些组件被静态化,确认你的布局是否被误判为静态。
  • 验证 getServerSession 调用时机:确保它只在服务器组件的顶层调用,不要嵌套到客户端组件或 useEffect 中。
  • 检查 API 路由配置:如果调用的是自身的 Next.js API 路由,确保该路由未被静态化(可添加 export const dynamic = "force-dynamic")。

内容的提问来源于stack exchange,提问作者Dan Castrillo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 20:12:47