#How do I get NextAuth session outside of components?

83 messages · Page 1 of 1 (latest)

spark tide
#

I can't seem to find a documented way to do it, and whenever I try it, I need to use a SessionProvider, which isn't possible for how I have my site built.

nova fogBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize

✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)

spark tide
#

Also, I'm using App Router

maiden dawn
#

What version of next-auth are you using? Also, why isn't using a SessionProvider an option? Are you getting the session data inside a client component or a server component?

autumn hinge
spark tide
#
 ⨯ Error: [next-auth]: `useSession` must be wrapped in a <SessionProvider />
    at useSession (/home/nova/Desktop/dev.electric.carbon/.next/server/chunks/ssr/node_modules_ea690b._.js:14204:15)
    at Page (/home/nova/Desktop/dev.electric.carbon/.next/server/chunks/ssr/[root of the server]__1f8803._.js:87:182)
digest: "516915812"
 GET / 500 in 3682ms
maiden dawn
autumn hinge
spark tide
#

because my layout is built by functions with basically no actual base page

#

what page returns:

return (
    <>
        <div style={{ display: 'flex', margin: '0px' }}>
            <div style={{ width: '200px', backgroundColor: '#111111', margin: '0px', height: '100vh', marginRight: '10px' }} id='sidebar'>
                {}
            </div>
            <div style={{ flex: 1 }} id='page'>
                {}
            </div>
        </div>
    </>
);
maiden dawn
#

Can you give me your layout.jsx?

spark tide
#

layout or page?

maiden dawn
spark tide
#

oh wait

#
import type { Metadata } from "next";
import localFont from "next/font/local";
import "./globals.css";

const jbm = localFont({
    variable: "--jbm",
    weight: "100 900",
    src: "./fonts/JetBrainsMonoNerdFont-Regular.ttf",
});

export const metadata: Metadata = {
    title: "Carbon",
    description: "Making in-game items truly yours.",
};

export default function RootLayout({
    children,
}: Readonly<{
    children: React.ReactNode;
}>) {
    return (
        <html lang="en">
            <body
                className={`${jbm.variable} antialiased`}
            >
                {children}
            </body>
        </html>
    );
}
#

i completely forgot that layout.tsx even exists 😭

maiden dawn
#

You can follow this too.

  1. Create a session-provider.jsx then paste this code:
"use client";

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

export default function SessionProvider({ children }) {
  return <Provider>{children}</Provider>;
}
  1. Go to your layout.jsx and integrate your SessionProvider.
<SessionProvider>
       <html lang="en">
            <body
                className={`${jbm.variable} antialiased`}
            >
                {children}
            </body>
        </html>
</SessionProvider>
#

You won't be able to use SessionProvider directly from next-auth because that would need to be in a client component. You can use it if you want your layout.tsx to be a client component but that's not recommended.

maiden dawn
spark tide
maiden dawn
#

Yeah you need to import it.

#

I usually create that session-provider.jsx under a components folder.

If that's the case then do this:

import SessionProvider from "@/components/session-provider";

spark tide
#

page is router spamming

#
[next-auth][error][CLIENT_FETCH_ERROR] "\nhttps://next-auth.js.org/errors#client_fetch_error" "JSON.parse: unexpected character at line 1 column 1 of the JSON data" {}
maiden dawn
#

Can I see your full layout and page?

spark tide
# maiden dawn Can I see your full layout and page?

layout.tsx:

import type { Metadata } from "next";
import localFont from "next/font/local";
import "./globals.css";
import SessionProvider from "./session-provider";

const jbm = localFont({
    variable: "--jbm",
    weight: "100 900",
    src: "./fonts/JetBrainsMonoNerdFont-Regular.ttf",
});

export const metadata: Metadata = {
    title: "Carbon",
    description: "Making in-game items truly yours.",
};

export default function RootLayout({
    children,
}: Readonly<{
    children: React.ReactNode;
}>) {
    return (
        <SessionProvider>
            <html lang="en">
                <body
                    className={`${jbm.variable} antialiased`}
                >
                    {children}
                </body>
            </html>
        </SessionProvider>
    );
}
maiden dawn
#

The issue is in your page.tsx.

useEffect(() => {
        loadPage();
    });

This is a bad use of useEffect

spark tide
# spark tide page.tsx:

sorry that its really long, im trying to shorten it by using next-auth and stuff like that

maiden dawn
#

Yeah. Your page.tsx is bloated. At least separate the components entirely.

autumn hinge
spark tide
autumn hinge
spark tide
#

oh wait

spark tide
#
import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials"
import { initialisemongoose } from "../[route]/route"
import { UserModel } from "../../mongoosemodels"
import { sha512 } from "js-sha512"

export const authOptions = {
    providers : [
        CredentialsProvider({
            name: 'Credentials',
            credentials: {
                username: { label: "Username", type: "text", placeholder: "johndoe" },
                password: {  label: "Password", type: "password" }
            },
            async authorize(credentials) {
                if (!credentials) {
                    throw new Error('Credentials are required');
                }
                const { username, password } = credentials;
                initialisemongoose();
                try {
                    const userDoc = await UserModel.findOne({ username });
                    if (userDoc) {
                        if (userDoc?.pwdhash && userDoc?.salt) {
                            const pwdhash = sha512(password + userDoc.salt);
                            if (pwdhash === userDoc.pwdhash) {
                                return {
                                    id: userDoc._id ? userDoc._id.toString() : '',
                                    name: userDoc.username ? userDoc.username : '',
                                }
                            } else {
                                return null;
                            }
                        } else {
                            return null;
                        }
                    }
                } catch (err) {
                    console.error(err);
                    return null;
                }
                return null;
            }
        })
    ],
}

export default NextAuth(authOptions);
autumn hinge
spark tide
autumn hinge
spark tide
#

im leaving it as a point of reference

spark tide
#

line 173

#

in page.tsx

autumn hinge
spark tide
autumn hinge
spark tide
#

with next router?

autumn hinge
maiden dawn
#

Yeah, it's also painful to see document.getElementById, it feels like vanilla JS

spark tide
autumn hinge
autumn hinge
autumn hinge
spark tide
#

are you referring to why im not using both app and pages?

maiden dawn
#

It's because you created some components and tried to render them in loadPage()

#

It's not ideal in next JS

spark tide
maiden dawn
#

You can create separate components then load them to your page.tsx rather than having them inside the Page()

spark tide
maiden dawn
#

This is also an antipattern of React itself. Don't create components within components, just create a separate on entirely

autumn hinge
# spark tide i tried that with the sidebar in my app and got really confused really quickly

It seems like you are new in nextjs. In developement you can't just start by watching a youtube video or ask other people and follow every step the guy in the video does or someone said to you. That works, until you get an error. So start by learning the basics and then one after another. Right now it seems like you are learning React, Nextjs and JSX.

That's way to much to start. So, start with the basics: Javascript, CSS, HTML. Then go in the advanced direction: JSX, React, important Libraries. And then go in the OP stuff like: NextJs and Typescript.
It looks like you already know the basics like Javascript, CSS and HTML, so go now to JSX and React

I learned all these stuff from this guy: Codevolution
Very much recommended.

For the beginning I recommend you, you using his crash course, for the topics I wrote down: https://www.youtube.com/watch?v=jLS0TkAHvRg&list=PLC3y8-rFHvwhuX4qGvFx-wPy_MEi6Jdp7&index=8

If you just want to learn nextjs, you might want to start their learning couse: https://nextjs.org/learn

Please do it, else you won't make it that long in programming
After this playlist you know the basics of webdevelopement and can start big projects like a ecommerce store.

Enjoy the developement journey and best of luck ^^

maiden dawn
#

This is what you should've done.

Create the sidebar in another file.

export function Sidebar(){
...
}

import the sidebar in page.tsx and just call it.

return(
<>
  <Sidebar/>
</>)
spark tide
#

im really lost :p

maiden dawn
#

You can leave me a dm if it's just the basics or if you were having issues implementing standard React patterns.

spark tide
#

i think i figured out why i was having issues, i just undid to when i made it

#

found this error

#
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.
 ⨯ TypeError: Cannot read properties of null (reading 'useContext')
    at useRouter (/home/nova/Desktop/dev.electric.carbon/.next/server/chunks/ssr/node_modules_next_3478ec._.js:1285:42)
    at [project]/app/components/sidebar.tsx [app-ssr] (ecmascript) (/home/nova/Desktop/dev.electric.carbon/.next/server/chunks/ssr/[root of the server]__dac2ff._.js:73:164)
    at instantiateModule (/home/nova/Desktop/dev.electric.carbon/.next/server/chunks/ssr/[turbopack]_runtime.js:589:23)
    at getOrInstantiateModuleFromParent (/home/nova/Desktop/dev.electric.carbon/.next/server/chunks/ssr/[turbopack]_runtime.js:644:12)
    at esmImport (/home/nova/Desktop/dev.electric.carbon/.next/server/chunks/ssr/[turbopack]_runtime.js:132:20)
    at [project]/app/page.tsx [app-ssr] (ecmascript) (/home/nova/Desktop/dev.electric.carbon/.next/server/chunks/ssr/[root of the server]__dac2ff._.js:239:133)
    at instantiateModule (/home/nova/Desktop/dev.electric.carbon/.next/server/chunks/ssr/[turbopack]_runtime.js:589:23)
    at getOrInstantiateModuleFromParent (/home/nova/Desktop/dev.electric.carbon/.next/server/chunks/ssr/[turbopack]_runtime.js:644:12)
    at commonJsRequire (/home/nova/Desktop/dev.electric.carbon/.next/server/chunks/ssr/[turbopack]_runtime.js:147:20)
digest: "193160438"
 GET / 500 in 2952ms
#

this is when using my sidebar as a component