News & Updates

How to Seamlessly Combine Next.js with Supabase Auth

By Mitchell Cross 11 min read 2359 views

How to Seamlessly Combine Next.js with Supabase Auth

If you’ve built a React front‑end with Next.js and are looking for a hassle‑free way to add sign‑up, login, and password‑reset flows, Supabase Auth is a solid choice. The combination lets you keep most of the heavy lifting on the server while still enjoying the static‑site generation and API routes that make Next.js popular. Below is a step‑by‑step guide that walks you through the entire process, from project setup to protecting pages on both the client and the server.

Why Pair Next.js with Supabase Auth?

Next.js already provides a clean separation between server‑side code (via pages/api or the new app directory) and client‑side React components. Supabase, on the other hand, offers a PostgreSQL‑backed authentication layer that mirrors Firebase’s ease of use but with open‑source flexibility. When you bind the two together you get:

  • Instant email‑magic‑link or OAuth logins without writing custom back‑end logic.
  • Server‑side rendering (SSR) that can read the session before the page reaches the browser, improving SEO and perceived performance.
  • A single source of truth for user data, because Supabase stores the auth session in its own JWT‑based cookies.

All of this works out of the box once you configure a few environment variables.

Prerequisites

Before diving in, make sure you have the following:

  • Node.js ≥ 16 installed locally.
  • A fresh Next.js project (you can create one with npx create-next-app@latest).
  • A Supabase account; the free tier is more than enough for a prototype.
  • Basic familiarity with React hooks and async/await.

If any of these items are missing, pause the guide and get them sorted first—otherwise you’ll run into avoidable errors later.

Setting Up the Supabase Project

Log into the Supabase dashboard and hit “New Project.” After the database spins up, navigate to the “Authentication” tab and enable the providers you need (email, Google, GitHub, etc.). You’ll also want to copy the API URL and anon public key; they’ll become environment variables in your Next.js app.

Optionally, tweak the “Email templates” section if you prefer a custom look for magic‑link emails. Supabase lets you add your own logo, change the sender name, and even set a redirect URL after a successful login.

Installing Packages in Your Next.js App

From the root of your Next.js project run:

npm install @supabase/supabase-js @supabase/auth-helpers-nextjs

The first library is the core JavaScript client, while the second provides helpers for Next.js‑specific tasks like SSR session handling and route protection.

Configuring the Auth Provider

Create a file called lib/supabaseClient.js (or .ts if you use TypeScript) with the following content:

import { createClient } from '@supabase/supabase-js';

export const supabase = createClient(

process.env.NEXT_PUBLIC_SUPABASE_URL,

process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY

);

Next, add the environment variables to .env.local:

NEXT_PUBLIC_SUPABASE_URL=your-project-url.supabase.co

NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key

Because these variables are prefixed with NEXT_PUBLIC_, they’ll be exposed to the browser—exactly what the client‑side auth flow needs.

Protecting Routes and Server‑Side Rendering

One of the biggest advantages of the Supabase auth helpers is the ability to fetch the user session during SSR. In a page that should only be visible to logged‑in users, add a getServerSideProps function:

import { supabase } from '@/lib/supabaseClient';

import { createServerSupabaseClient } from '@supabase/auth-helpers-nextjs';

export const getServerSideProps = async (ctx) => {

const supabaseServerClient = createServerSupabaseClient(ctx);

const { data: { session } } = await supabaseServerClient.auth.getSession();

if (!session) {

return {

redirect: {

destination: '/login',

permanent: false,

},

};

}

return { props: { user: session.user } };

};

This snippet checks for a valid session; if none exists, the visitor is redirected to /login. Because the check runs on the server, the protected page never even renders for unauthenticated users, which is good for both security and SEO.

Handling Sessions on the Client

On the client side you’ll likely need to show the current user's name, log out, or trigger a sign‑in flow. The useUser hook from @supabase/auth-helpers-react makes this painless:

import { useUser, useSupabaseClient } from '@supabase/auth-helpers-react';

export default function Profile() {

const user = useUser();

const supabase = useSupabaseClient();

if (!user) return null; // or a loading spinner

const handleLogout = async () => {

await supabase.auth.signOut();

// Optionally redirect after logout

};

return (

<div>

<h2>Welcome, {user.email}</h2>

<button onClick={handleLogout}>Log out</button>

</div>

);

}

The hook automatically syncs with the server‑side session, so you won’t see flickering UI where the user appears logged out for a split second.

Creating a Simple Login Page

A minimal login component can rely on Supabase’s built‑in magic‑link flow:

import { useState } from 'react';

import { supabase } from '@/lib/supabaseClient';

export default function Login() {

const [email, setEmail] = useState('');

const [message, setMessage] = useState('');

const handleLogin = async (e) => {

e.preventDefault();

const { error } = await supabase.auth.signInWithOtp({ email });

if (error) setMessage(error.message);

else setMessage('Check your inbox for the login link.');

};

return (

<form onSubmit={handleLogin}>

<input

type="email"

placeholder="you@example.com"

value={email}

onChange={(e) => setEmail(e.target.value)}

required

/>

<button type="submit">Send Magic Link</button>

<p>{message}</p>

</form>

);

}

Because Supabase stores the JWT in an HttpOnly cookie, you don’t need to manage tokens in localStorage—a common source of XSS vulnerabilities.

Common Pitfalls and Tips

  • Cookie domain mismatches. If you’re developing locally with localhost and later deploy to a custom domain, remember to update the Auth > Settings > Site URL in the Supabase dashboard; otherwise redirects will fail.
  • SSR caching. When using next/cache or any CDN, ensure that pages with getServerSideProps are not cached for anonymous users, as this could serve a protected page to the wrong visitor.
  • Refresh token handling. Supabase automatically refreshes the JWT, but if you manually read session.access_token you should also listen for onAuthStateChange to keep the client state up to date.
  • Environment variable leakage. Only the NEXT_PUBLIC_ prefixed keys are exposed to the browser. Keep your service_role key in a separate .env.production file and never commit it.

FAQ

Can I use Supabase Auth with Next.js middleware?

Yes. The @supabase/auth-helpers-nextjs package includes a supabaseMiddleware you can add to middleware.ts. It checks the request’s cookie and redirects unauthenticated users before they reach the page.

Do I need a separate database for user profiles?

Supabase stores basic user metadata (email, provider, timestamps) automatically. For richer profiles—like avatars or preferences—you can create a profiles table and link it to the auth.users ID using a foreign key.

Is server‑side rendering compatible with static site generation (SSG)?

Pages that truly depend on a logged‑in user must use getServerSideProps or the new app directory’s fetch with cache: "no-store". Purely static pages can still be generated with getStaticProps, but they won’t have access to the session at build time.

How do I log out across multiple tabs?

Supabase writes the session cookie as HttpOnly; when you call signOut(), the cookie is cleared for the current tab. To sync the logout across tabs, listen for the storage event on window and trigger a client‑side redirect if the session disappears.

Complete UPDATED Guide - Next.js Auth With Supabase - YouTube
Supabase Authentication and Authorization in Next.js: Implementation Guide
Supabase Next.js 연동 완전 가이드—설치가 아니라 설계부터 시작하라 — MANI
Nextjs Supabase Auth | Tailwind Resources

Written by Mitchell Cross

Mitchell Cross is a Features Editor specializing in the people, ideas, and changes behind the headlines. Her reporting spans society, lifestyle, and current affairs, combining detailed research with engaging narratives that explore how major developments influence individuals and communities.


You Might Like