Home > Enterprise >  NextJS Supabase - Blank Page Issue
NextJS Supabase - Blank Page Issue

Time:10-19

I am attempting to render either an Application or Login page depending on whether getUser() returns a user object.

However, in both development and production, a blank page is rendered.

This is the code

export default function index() {
  supabase.auth.getUser().then((response) => {
    const userData = response.data.user;
    console.log(userData);

    return userData != undefined || userData != null ? (
        <>
          <Shell />
          <AppView />
        </>
      ) : (
        <NoSessionWarn />
      );
  });
}

I use NextJS's router.push('/application') to route the user to this page, in case that might have something to do with it.

Any idea why this could be showing a blank page? I've tried taking the return block out of the .then() block and still nothing.

CodePudding user response:

Few things:

  1. In React functional components, side effects must be handled inside a useEffect hook
  2. React components names should be capitalized (Index instead of index in your case).
  3. Most of the time it's a better idea to use strict equality operator since it also checks for the type of the operands.
  4. As a suggestion, you could abstract the logic of the auth checking process into a custom hook. This not only increases the readability of the component, but also makes this logic reusable and you now would have separation of concerns. Your component doesn't know and doesn't care about how the user data is being retrieved, it just uses it.

Putting it all together:

useAuth custom hook:

export const useAuth = () => {
  const [user, setUser] = useState(null)
  const [isAuthorizing, setIsAuthorizing] = useState(true)

  useEffect(() => {
    supabase.auth
      .getUser()
      .then((response) => {
        setUser(response.data.user)
      })
      .catch((err) => {
        console.error(err)
      })
      .finally(() => {
        setIsAuthorizing(false)
      })
  }, [])

  return { user, isAuthorizing }
}

Component:

export default function Index() {
  const { user, isAuthorizing } = useAuth()

  if (isAuthorizing) return <p>Loading</p>

  // Being very explicit here about the possible falsy values.
  if (user === null || user === undefined) return <NoSessionWarn />

  return (
    <>
      <Shell />
      <AppView />
    </>
  )
}

CodePudding user response:

You need to use the useState hook to re-render when you receive the data.

You need to use the useEffect hook with an empty dependency array to execute getUser() once on mount.

You'll also probably want a loading mechanism while the request is made.

export default function index() {
  const [userData, setUserData] = useState(null);
  const [loading, setLoading] = useState(true); 

  useEffect(() => {
    supabase.auth.getUser().then((response) => {
      setUserData(response.data.user);
      setLoading(false);
    });
  }, []);

  if (loading) return <p>Loading...</p>
  if (!userData) return <NoSessionWarn />;

  return (
    <>
      <Shell />
      <AppView />
    </>
  );
}

Example: https://stackblitz.com/edit/react-ts-neq5rh?file=App.tsx

  • Related