Next.js Discord

Discord Forum

Issue with useSession in App Router

Answered
American posted this in #help-forum
Open in Discord
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
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>
  );
}
View full answer

3 Replies

AmericanOP
I included the next auth SessionProvider like so:
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