javascriptreactjsnext.jssession-storage

How can I conditionally render a React component if a sessionStorage variable does not exist in Next.js?


I have an <Authenticated> component that is used to render all of my authenticated routes. I want to prevent rendering the page until I have checked a token stored in sessionStorage.

'use client';

export const Authenticated = ({ children }) => {
  const token = typeof window !== 'undefined' ? sessionStorage.getItem('token') : null;

  if (!token) {
    return <></>;
  }

  return (
    <main>{children}</main>
  );
}

This works but I get this hydration error:

Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.

Is there a better way to do this?


Solution

  • According to the Next.js docs hydration errors can be caused by:

    Using checks like typeof window !== 'undefined' in your rendering logic

    That is what you are doing here:

    const token = typeof window !== 'undefined' ? sessionStorage.getItem('token') : null;
    

    Instead wrap your session handling logic into your useEffect hook. This will ensure that you only check for a token when the page has fully loaded and that window is available:

    'use client';
    
    import React, {useState, useEffect} from 'react';
    
    export const Authenticated = ({ children }) => {
      const [token, setToken] = useState('');
    
      useEffect(() => {
         setToken(window.sessionStorage.getItem('token'))
      }, [])
    
      return (
        {token ? <main>{children}</main> : null}
      );
    }
    

    A few things to note about this approach: