Issue with useSession in App Router
Answered
American posted this in #help-forum
AmericanOP
When logging the session data (session.data.user) returned by useSession in the console, I am seeing the default values (name, email, image) even tho I extended the type in a
i can see this in the devtools console:
Reloading the page or navigating between pages shows the same as above in the console. But when switching to another tab and navigating back to the website tab, the correct session data is being populated:
This happens only in production and I did not have the issue in the pages router. My next message shows how I include the next auth SessionProvider in my app
next-auth.d.ts file like so:declare module "next-auth" {
/**
* Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
*/
interface Session {
user: {
accessToken: string;
refreshToken: string;
expiresIn: number;
id: string;
username: string;
email: string;
verified: boolean;
...i can see this in the devtools console:
{ "name": "example", "email": "example@gmail.com", "image": "https://cdn.discordapp.com/embed/avatars/0.png" }Reloading the page or navigating between pages shows the same as above in the console. But when switching to another tab and navigating back to the website tab, the correct session data is being populated:
{ "accessToken": "(token)", "id": "exampleID", username": "example" , ... } This happens only in production and I did not have the issue in the pages router. My next message shows how I include the next auth SessionProvider in my app
Answered by American
Solved by moving and exporting
authOptions out of api/auth/[...nextauth]/route.ts to a seperate file in src/components/utils/auth-options and importing it in the root layout to pass it to getServerSession() like so:import "./css/style.css";
import { Inter } from "next/font/google";
import Theme from "./theme-provider";
import LoginModal from "@/components/modals/login-modal";
import RegisterModal from "@/components/modals/register-modal";
import ForgotPasswordModal from "@/components/modals/forgot-password-modal";
import ResetPasswordModal from "@/components/modals/reset-password-modal";
import VerifyAccount from "@/components/modals/verify-account";
import SessionProvider from "@/components/session-provider";
import { getServerSession } from "next-auth";
import { authOptions } from "@/components/utils/auth-options";
const inter = Inter({
subsets: ["latin"],
variable: "--font-inter",
display: "swap",
});
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const session = await getServerSession(authOptions);
return (
<html lang="en" className="scroll-smooth" suppressHydrationWarning>
<body
className={`${inter.variable} bg-slate-200 font-inter tracking-tight text-slate-800 antialiased dark:bg-slate-900 dark:text-slate-100`}
>
<SessionProvider refetchInterval={12 * 60 * 60} session={session}>
<Theme>
<LoginModal />
<RegisterModal />
<ForgotPasswordModal />
<ResetPasswordModal />
<VerifyAccount />
<Toaster richColors position="top-right" closeButton />
<div className="flex min-h-screen flex-col overflow-hidden supports-[overflow:clip]:overflow-clip">
{children}
</div>
</Theme>
</SessionProvider>
</body>
</html>
);
}3 Replies
AmericanOP
I included the next auth SessionProvider like so:
session-provider.tsx:
Root layout:
session-provider.tsx:
"use client";
import { SessionProvider } from "next-auth/react";
export default SessionProvider;Root layout:
import "./css/style.css";
import { Inter } from "next/font/google";
import Theme from "./theme-provider";
import LoginModal from "@/components/modals/login-modal";
import RegisterModal from "@/components/modals/register-modal";
import ForgotPasswordModal from "@/components/modals/forgot-password-modal";
import ResetPasswordModal from "@/components/modals/reset-password-modal";
import VerifyAccount from "@/components/modals/verify-account";
import { Toaster } from "sonner";
import SessionProvider from "@/components/session-provider";
import { getServerSession } from "next-auth";
const inter = Inter({
subsets: ["latin"],
variable: "--font-inter",
display: "swap",
});
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const session = await getServerSession();
return (
<html lang="en" className="scroll-smooth" suppressHydrationWarning>
<body
className={`${inter.variable} bg-slate-200 font-inter tracking-tight text-slate-800 antialiased dark:bg-slate-900 dark:text-slate-100`}
>
<SessionProvider refetchInterval={12 * 60 * 60} session={session}>
<Theme>
<LoginModal />
<RegisterModal />
<ForgotPasswordModal />
<ResetPasswordModal />
<VerifyAccount />
<Toaster richColors position="top-right" closeButton />
<div className="flex min-h-screen flex-col overflow-hidden supports-[overflow:clip]:overflow-clip">
{children}
</div>
</Theme>
</SessionProvider>
</body>
</html>
);
}Why is the extended session data only being populated when switching the tab and not when reloading or navigating on the website?
AmericanOP
Solved by moving and exporting
authOptions out of api/auth/[...nextauth]/route.ts to a seperate file in src/components/utils/auth-options and importing it in the root layout to pass it to getServerSession() like so:import "./css/style.css";
import { Inter } from "next/font/google";
import Theme from "./theme-provider";
import LoginModal from "@/components/modals/login-modal";
import RegisterModal from "@/components/modals/register-modal";
import ForgotPasswordModal from "@/components/modals/forgot-password-modal";
import ResetPasswordModal from "@/components/modals/reset-password-modal";
import VerifyAccount from "@/components/modals/verify-account";
import SessionProvider from "@/components/session-provider";
import { getServerSession } from "next-auth";
import { authOptions } from "@/components/utils/auth-options";
const inter = Inter({
subsets: ["latin"],
variable: "--font-inter",
display: "swap",
});
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const session = await getServerSession(authOptions);
return (
<html lang="en" className="scroll-smooth" suppressHydrationWarning>
<body
className={`${inter.variable} bg-slate-200 font-inter tracking-tight text-slate-800 antialiased dark:bg-slate-900 dark:text-slate-100`}
>
<SessionProvider refetchInterval={12 * 60 * 60} session={session}>
<Theme>
<LoginModal />
<RegisterModal />
<ForgotPasswordModal />
<ResetPasswordModal />
<VerifyAccount />
<Toaster richColors position="top-right" closeButton />
<div className="flex min-h-screen flex-col overflow-hidden supports-[overflow:clip]:overflow-clip">
{children}
</div>
</Theme>
</SessionProvider>
</body>
</html>
);
}Answer