Is it normal that all components in Next.js are client components? (next auth )
Unanswered
Orinoco Crocodile posted this in #help-forum
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
some protected page
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
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
the only times you need to use
useSession() is if you want to authentication in a client componentSo think first whether you are authenticating user on server or client, then implement it with NextAuth, not the other way around
@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 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
The Next Auth documentation recommends wrapping everything in a provider, but then the main feature of Next.js, namely SSR, no longer worksno, 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 client2. or they are imported into a client component
the documentation has some paragraph for you on using providers in layout: https://nextjs.org/docs/getting-started/react-essentials#rendering-third-party-context-providers-in-server-components
@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
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
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
that way you don't need to 'use client' at every page
getServerSession to authenticate the user in the serverthat way you don't need to 'use client' at every page
@aardani 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 CrocodileOP
And if I leave the provider in the root, will all pages be server or client?
@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 loadingthats 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 Crocodile 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?
you can just leave it at a common layout that is shared between admin pages
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 layoutforxample 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>
)
}\
although you can do better with the function name haha
@aardani although you can do better with the function name haha
Orinoco CrocodileOP
ahaha, yes, thank you