I am using NextJS 14 to setup routing. I am using root layout in app/layout.js
to check for jwt tokens and conditionally allow page rendering or redirect to /auth/login.
However in doing so, I am getting 2 back-to-back errors.
- First the app is redirected to /auth/login as expected.
- Then due to some reason, the
/auth/login
keeps re-rendering multiple times but with the UI of AppLayout.js (tried putting dummy text in AppLayout and figured it out). - After a few re-renders, the app crashes, nothing is shown on browser and console gives this error:
⨯ app/(dashboard)/AppLayout.jsx (10:2) @ Layout
⨯ ReferenceError: localStorage is not defined
at Layout (/home/krush/agro/aggro/.next/server/chunks/_f13a71._.js:137:19)
8 | export default function Layout({ children }) {
9 | const token = localStorage.getItem('token');
> 10 |
| ^
11 | useEffect(() => {
12 | if (!token) redirect('/auth/login');
13 | }, [token]
// app/layout.js
import AppLayout from './(dashboard)/AppLayout'
import './globals.css'
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className + 'w-full'}>
<AppLayout>
{children}
</AppLayout>
</body>
</html>
)
}
This is the AppLayout where I am trying to conditionally authenticate using jwt tokens. The AppLayout is in a (dashboard)
group inside NextJS as I only want the layout for the dashboard and not for the auth pages
// app/(dashboard)/AppLayout.js
'use client';
import { redirect } from 'next/navigation';
import { useEffect } from 'react';
export default function Layout({ children }) {
const token = localStorage.getItem('token');
useEffect(() => {
if (!token) redirect('/auth/login');
}, [token])
return (
<div className='flex-1'>
{children}
</div>
)
}
I have no code written yet for auth pages.
// app/auth/login/page.js
export default function Page() {
return (
<>
</>
)
}
As mentioned above, I simply want to use a layout for the whole dashboard(AppLayout) and that layout should not be displayed in /auth/* so have added a group (dashboard)
. And AppLayout will be using many Client side React functions so I am taking it out of /app/layout.js
The error is definitely exists in the way I have written the token fetching and useeffect code, but I dont know what exactly the error is and how to resolve it.
2
Answers
the redirection shouldn’t be happening with given route, so that users can access
/auth/login
.also, don’t forget to add route guard for already logged-in users.
the app crashes because memory has just run out; I’d suggest checking redirection often if possible.
Although you use
use client
, your client component is first rendered on the server. you can test this by adding thisconsole.log("where am I ");
to your layout file. you will see "where am I " is logged both on the terminal and browser console.. that is why, if you are usingwindow.localStorage
, you need to make sure you are on the browser environment: