Protected routes keep parts of your website safe. Only logged-in users can see them.
Protected routes in frontend in Supabase
import { useEffect } from 'react'; import { useRouter } from 'next/router'; import { supabase } from './supabaseClient'; function ProtectedRoute({ children }) { const router = useRouter(); useEffect(() => { supabase.auth.getSession().then(({ data: { session } }) => { if (!session) { router.push('/login'); } }); }, [router]); return children; }
This example uses React with Next.js and Supabase for authentication.
It checks if a user session exists. If not, it redirects to the login page.
import { useEffect } from 'react'; import { useRouter } from 'next/router'; import { supabase } from './supabaseClient'; function ProtectedRoute({ children }) { const router = useRouter(); useEffect(() => { supabase.auth.getSession().then(({ data: { session } }) => { if (!session) { router.push('/login'); } }); }, [router]); return children; }
import { useEffect, useState } from 'react'; import { useRouter } from 'next/router'; import { supabase } from './supabaseClient'; function ProtectedRoute({ children }) { const router = useRouter(); const [loading, setLoading] = useState(true); const [session, setSession] = useState(null); useEffect(() => { supabase.auth.getSession().then(({ data: { session: currentSession } }) => { setSession(currentSession); setLoading(false); if (!currentSession) { router.push('/login'); } }); }, [router]); if (loading) return <p>Loading...</p>; return session ? children : null; }
This complete example shows a protected route component that checks if the user is logged in using Supabase. If not logged in, it redirects to the login page. While checking, it shows a loading message. You wrap your private page content inside this component.
import { useEffect, useState } from 'react'; import { useRouter } from 'next/router'; import { supabase } from './supabaseClient'; export default function ProtectedRoute({ children }) { const router = useRouter(); const [loading, setLoading] = useState(true); const [session, setSession] = useState(null); useEffect(() => { supabase.auth.getSession().then(({ data: { session: currentSession } }) => { setSession(currentSession); setLoading(false); if (!currentSession) { router.push('/login'); } }); }, [router]); if (loading) return <p>Loading...</p>; return session ? children : null; } // Usage example in a page component // import ProtectedRoute from './ProtectedRoute'; // // export default function Dashboard() { // return ( // <ProtectedRoute> // <h1>Welcome to your dashboard!</h1> // </ProtectedRoute> // ); // }
Always check user session on the client side to protect routes.
Redirecting unauthenticated users improves security and user experience.
Use loading states to avoid showing protected content before session check completes.
Protected routes keep parts of your app safe by allowing only logged-in users.
Use Supabase session to check if a user is logged in.
Redirect users to login if they try to access protected pages without permission.
Practice
Solution
Step 1: Understand what protected routes do
Protected routes restrict access to certain pages so only authorized users can see them.Step 2: Connect with Supabase session usage
Supabase sessions help check if a user is logged in, enabling route protection.Final Answer:
To allow only logged-in users to access certain pages -> Option AQuick Check:
Protected routes = restrict access to logged-in users [OK]
- Thinking protected routes speed up loading
- Confusing route protection with data storage
- Assuming protected routes change app appearance
Solution
Step 1: Identify Supabase method for session retrieval
Supabase's current method to get session info is auth.getSession(), which returns user session data.Step 2: Compare options with official API
Options A, B, and C are outdated or incorrect method names; only getSession() is valid.Final Answer:
const user = supabase.auth.getSession() -> Option DQuick Check:
Use auth.getSession() to check login [OK]
- Using deprecated methods like auth.session()
- Calling supabase.session() which does not exist
- Confusing getUser() with getSession()
const session = supabase.auth.getSession();
if (!session) {
navigate('/login');
} else {
showDashboard();
}Solution
Step 1: Understand getSession() behavior
supabase.auth.getSession() is an asynchronous function returning a Promise, so calling it without await assigns a Promise object to session, not session data.Step 2: Analyze the code flow
A Promise object is truthy, so if (!session) evaluates to false, and showDashboard() executes regardless of login status.Final Answer:
The dashboard is shown regardless -> Option AQuick Check:
Async getSession() without await returns truthy Promise [OK]
- Treating async getSession() as synchronous
- Assuming session is null if user not logged in
- Ignoring Promise returned by getSession()
const { data: session } = supabase.auth.getSession();
if (!session) {
window.location.href = '/login';
}What is the main issue?
Solution
Step 1: Check getSession() usage
supabase.auth.getSession() returns a Promise and must be awaited or handled asynchronously to get session data.Step 2: Understand destructuring without await
Destructuring data from a Promise without await results in undefined or incorrect values, so session is not properly checked.Final Answer:
getSession() is asynchronous and must be awaited -> Option CQuick Check:
Always await async getSession() calls [OK]
- Not awaiting async functions
- Thinking window.location.href can't redirect
- Using getUser() instead of getSession() incorrectly
function ProtectedPage() {
const [session, setSession] = React.useState(null);
React.useEffect(() => {
const getSession = async () => {
const { data } = await supabase.auth.getSession();
setSession(data.session);
if (!data.session) {
navigate('/login');
}
};
getSession();
}, []);
if (!session) return <p>Loading...</p>;
return <div>Welcome to protected content!</div>;
}Solution
Step 1: Analyze async session retrieval in useEffect
The code correctly uses an async function inside useEffect to get the session and update state.Step 2: Check redirect logic for unauthenticated users
If no session exists, the code calls navigate('/login') to redirect users, protecting the page.Step 3: Confirm loading state handling
While session is null, it shows a loading message, preventing content flash before redirect.Final Answer:
This code correctly protects the page by redirecting unauthenticated users -> Option BQuick Check:
Async session check + redirect = protected route [OK]
- Using getUser() instead of getSession() for session check
- Calling navigate outside async context incorrectly
- Initializing session state synchronously causing errors
Ready to prove it?
Pass the test and this pattern moves unknown
