Monday, May 19, 2025 – Last week’s issue was related to authentication. Previously, I had already implemented an authentication layout to prevent outsiders or logged-out users from accessing UI pages. Although the backend was already secure, blocking unauthorized data access, we still didn’t want unauthenticated users to even see the UI. That’s why the layout-based authentication was put in place.
However, I noticed a new problem: when a user’s token expired, they could still access the
UI pages. The backend continued to block the data, but the frontend still rendered the components, which wasn’t ideal. So, I decided to add another layer of protection by checking whether the token had expired and redirecting the user to the login page if it had.
On my first attempt, I tried adding the logic directly in the layout file, but I immediately ran into an error “window or localStorage is not defined”. This happens because Next.js layout files run on the server by default, and these browser-specific objects don’t exist in that context.
After looking into it further, I created a custom hook to handle the token expiration logic and tried calling it from the layout. That also didn’t work, since React hooks can only be used inside client components, and layouts are server components by default.
To get around this, I created a new client-only component specifically for token validation. I then placed this component inside the layout, which made the logic work correctly. Thanks to Mr. Peter’s tip on how to simulate an expired token, I was able to test the flow and confirm it behaved as expected.
This also required me to store another value in localStorage, “sessionExpiry” in addition to the existing “isLoggingOut”. With both of these in place, I could now reliably determine whether a user should still have access. The session is considered expired if either there’s no token or if the current time has passed the session expiry timestamp. Now, the UI is finally in sync with the authentication state, users are redirected when they’re no longer supposed to be there.
