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

Next.js 13 + next-auth:useSession与SessionProvider使用报错问题

解决Next.js App Router中NextAuth的SessionProvider配置问题

问题现象

在迁移至App Router的新项目中开发登录页面时遇到两个错误:

  • 不添加"use client"时,报错:Error: React Context is unavailable in Server Components
  • 添加"use client"后,报错:Error: [next-auth]: useSession must be wrapped in a <SessionProvider />

原项目中_app.js的SessionProvider迁移到根layout.tsx后未生效,现有代码存在App Router适配问题。

核心原因

App Router的根layout.tsx默认是服务器组件,无法直接使用客户端的Context Provider;同时旧Pages Router的getLayout方式在App Router中不再适用,页面不会自动关联自定义布局中的SessionProvider。

修复方案

1. 创建独立的SessionProvider客户端组件

新建components/SessionProviderWrapper.tsx,将SessionProvider封装为客户端组件:

"use client";

import { SessionProvider } from "next-auth/react";
import { ReactNode } from "react";

type Props = {
  children: ReactNode;
};

export default function SessionProviderWrapper({ children }: Props) {
  return <SessionProvider>{children}</SessionProvider>;
}

2. 修改根layout.tsx

在根布局中引入并使用上述客户端组件,确保所有页面都被SessionProvider包裹:

import Image from 'next/image'
import { ReactNode } from "react";
import "./globals.css";
import Link from "next/link";
import SessionProviderWrapper from './components/SessionProviderWrapper';

type Props = {
  children: ReactNode;
};

export default function RootLayout({ children }: Props) {
  return (
    <html lang="en">
      <head />
      <body>
        <SessionProviderWrapper>
          <div className="mx-auto">
            <div className="flex flex-row flex-wrap">
              <aside className="w-full sm:w-1/3 md:w-1/5 xl:w-1/6 border-r-2 border-[#F845C6]">
                <div className="sticky top-0 p-4 w-full">
                  <ul className="flex flex-col overflow-hidden">
                    <li className="m-5 text-center">
                      <Link href="/login">LOGO</Link>
                    </li>
                    <li className="m-5 text-center">
                      <Link href="/">Dashboard</Link>
                    </li>
                    <li className="m-5 text-center">
                      <Link href="/tasks">Tasks</Link>
                    </li>
                    <li className="m-5 text-center">
                      <Link href="/reporting">Reporting</Link>
                    </li>
                  </ul>
                </div>
              </aside>

              <div className="w-full sm:w-2/3 md:w-4/5 xl:w-5/6">{children}</div>
            </div>
          </div>
        </SessionProviderWrapper>
      </body>
    </html>
  );
}

3. 简化Login页面代码

移除Pages Router遗留的getLayout相关代码,App Router会自动使用根布局:

"use client";
import React from 'react'
import { useSession, signIn, signOut } from 'next-auth/react'

export default function Login() {
  const { data: session } = useSession();

  if (session) {
    return (
      <div style={{ fontFamily: 'sans-serif', margin: '10px 20px' }}>
        <p>欢迎,{session.user.name}</p>
        <img src={session.user.image} alt="用户头像" style={{ borderRadius: '15px', width: '80px', margin: '10px' }} />
        <button onClick={() => signOut()}>退出登录</button>
      </div>
    );
  } else {
    return (
      <div>
        <p>请登录</p>
        <button onClick={() => signIn("google", { callbackUrl: '/account' })}>使用Google登录</button>
      </div>
    );
  }
}

关键修复点说明

  • 将SessionProvider单独封装为客户端组件,规避App Router根布局的服务器组件限制
  • 根布局通过客户端组件包裹所有内容,确保全局能访问Session Context
  • 废弃Pages Router的getLayout模式,遵循App Router的自动布局关联规则

内容的提问来源于stack exchange,提问作者atomic-ag

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 14:25:37