Next.js Discord

Discord Forum

Is it normal that all components in Next.js are client components? (next auth )

Unanswered
Orinoco Crocodile posted this in #help-forum
Open in Discord
Orinoco CrocodileOP
I use app folder and Next Auth library. So that each page has access to the session, I wrapped the entire application in a SessionProvider. But since it's useContext under the hood, I had to add the 'use client' directive everywhere. This resulted in all pages being client-side since they use useSession. And all page components (buttons, inputs) also became client-side.

app/layout.tsx
const RootLayout = ({ session, children }: { session: Session; children: ReactNode }) => {
    return (
        <SessionProvider session={session}>
                <html lang={`eng`} 
                    <head>
                    </head>
                    <body>
                        {children}
                    </body>
                </html>
        </SessionProvider>
    )
}


some protected page


'use client';

import {useSession} from "next-auth/react";

export default function ProtectedPage() {
    const {data, status} = useSession()


    return (
                <div>
                    {status === "authenticated" ? <div>data.name</div> : null}
                </div>
    )
}


Is it normal that all pages and components are now rendered on the client? The Next Auth documentation recommends wrapping everything in a provider, but then the main feature of Next.js, namely SSR, no longer works

37 Replies

@aardani So think first whether you are authenticating user on server or client, then implement it with NextAuth, not the other way around
Orinoco CrocodileOP
Thank you for answer. But do you think it's bad practice to use 'use client' everywhere?
@Orinoco Crocodile Thank you for answer. But do you think it's bad practice to use 'use client' everywhere?
using use client everywhere is not as bad as you think.
using use client in everything is bad practice
as long as you know what needs to be rendered in the server, and what needs interactivity
furthermore, this table provide greater details as to what should 'use client' and what should not
https://nextjs.org/docs/getting-started/react-essentials#when-to-use-server-and-client-components
@joulev > The Next Auth documentation recommends wrapping everything in a provider, but then the main feature of Next.js, namely SSR, no longer works no, it still works; all pages are still server components unless you explicitly opt out. components are only client components if 1. they are marked as such with `use client` 2. or they are imported into a client component
Orinoco CrocodileOP
but if my application root has a provider and a 'use client' directive, and all pages have 'use client' to access the session, then all components automatically become client-side if they are imported into my pages?
@Orinoco Crocodile but if my application root has a provider and a 'use client' directive, and all pages have 'use client' to access the session, then all components automatically become client-side if they are imported into my pages?
if your pages requires the session at request time (i.e everytime page load) you might be able to just use getServerSession to authenticate the user in the server
that way you don't need to 'use client' at every page
@Orinoco Crocodile And if I leave the provider in the root, will all pages be server or client?
if you import a client component into a server component, and if you put {children} as the child of the client component, then it will be server rendered
using this pattern
thats why this pattern works
@aardani if you import a client component into a server component, and if you put {children} as the child of the client component, then it will be server rendered
Orinoco CrocodileOP
thank you. it turns out that I can leave the provider at the root, and depending on whether I have a server or client component (based on the table https://nextjs.org/docs/getting-started/react-essentials#when-to-use-server-and-client-components), I use either useSession or getServerSession, right?
Cape horse mackerel
yep, since everything under <Providers /> is passed as children, it allows for server components to be passed into client components. this is what prevents the entire tree from becoming client components
i usually use useSession() for things that requries auth after the page finished loading
thats like if the user wants to press a button to mutate stuff, i check if user is authenticated
or like if session suddenly expires, i can just useSession to redirect to auth
Orinoco CrocodileOP
thank you. and if I have an admin panel where all pages should be private, I have to check the session on each one, right?
Orinoco CrocodileOP
But then user can just redirect to 'http://localhost:3000/protected'  ?
I thought I need check in every page it
@Orinoco Crocodile But then user can just redirect to 'http://localhost:3000/protected'  ?
that is where the getServerSession() is done at root layout
forxample i have this at an app layout
that protects for example /protected
if I access /protected/test/aaaa/123, that code will still be run
Orinoco CrocodileOP
oh, thank you. and in the layout.tsx you just call getLoggedInSeddion_redirectIfNotAuth() ?
const RootLayout = ({ session, children }: { session: Session; children: ReactNode }) => {

getLoggedInSeddion_redirectIfNotAuth() 

    return (
        <SessionProvider session={session}>
            <SSRProvider>
                <html lang={`ru`} data-js-focus-visible="" className="js-focus-visible">
                    <head>
                        <title>My </title>
                    </head>
                    <body>
                        {children}

                    </body>
                </html>
            </SSRProvider>
        </SessionProvider>
    )
}
\
@aardani although you can do better with the function name haha
Orinoco CrocodileOP
ahaha, yes, thank you