This guide will walk you through the steps to set up user registration, login, and session management, leveraging the power of Supabase as a backend service. By the end of this tutorial, you will have a fully functional authentication system that can be integrated into your Next.js applications.
Prerequisites
Before we begin, ensure you have the following:
- Node.js installed on your machine (preferably version 14 or higher).
- A Supabase account (you can sign up for free at [supabase.io](https://supabase.io)).
- Basic knowledge of JavaScript and React.
Setting Up Supabase
1. Create a New Project:
- Log in to your Supabase account and create a new project.
- Choose a name for your project and select a database password.
2. Configure Database:
- Once your project is created, navigate to the "SQL Editor" in the Supabase dashboard.
- Run the following SQL command to create a users table:
1 2 3 4 5 6
create table users ( id serial primary key, email text unique not null, password text not null, created_at timestamp with time zone default timezone('utc'::text, now()) );
3. Enable Authentication:
- Go to the "Authentication" section in the Supabase dashboard.
- Enable email authentication under the "Settings" tab.
4. Get API Keys:
Navigate to the "API" section to find your Supabase URL and anon/public API key. You will need these for your Next.js application.
Setting Up Next.js 15
1. Create a New Next.js Project:
1 2
npx create-next-app@latest my-auth-app cd my-auth-app
2. Install Supabase Client:
1
npm install @supabase/supabase-js
3. Create Supabase Client:
Create a new file called supabaseClient.js
in the root of your project:
1 2 3 4 5 6
import { createClient } from '@supabase/supabase-js'; const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; export const supabase = createClient(supabaseUrl, supabaseAnonKey);
4. Add Environment Variables:
Create a .env.local
file in the root of your project and add your Supabase URL and anon key:
1 2
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
Implementing Authentication
User Registration
Create a Registration Component:
Create a new file Register.js
in the components
directory:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
import { useState } from 'react'; import { supabase } from '../supabaseClient'; const Register = () => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const handleRegister = async (e) => { e.preventDefault(); const { user, error } = await supabase.auth.signUp({ email, password, }); if (error) console.error(error); else console.log('User registered:', user); }; return ( <form onSubmit={handleRegister}> <input type="email" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} required /> <input type="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)} required /> <button type="submit">Register</button> </form> ); }; export default Register;
User Login
Create a Login Component:
Create a new file Login.js
in the components
directory:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
import { useState } from 'react'; import { supabase } from '../supabaseClient'; const Login = () => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const handleLogin = async (e) => { e.preventDefault(); const { user, error } = await supabase.auth.signIn({ email, password, }); if (error) console.error(error); else console.log('User logged in:', user); }; return ( <form onSubmit={handleLogin}> <input type="email" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} required /> <input type="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)} required /> <button type="submit">Login</button> </form> ); }; export default Login;
Session Management
1. Manage User Sessions:
In your main application file (e.g., pages/index.js
), you can check the authentication state:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
import { useEffect, useState } from 'react'; import { supabase } from '../supabaseClient'; import Register from '../components/Register'; import Login from '../components/Login'; const Home = () => { const [user, setUser] = useState(null); useEffect(() => { const session = supabase.auth.session(); setUser(session?.user ?? null); const { data: authListener } = supabase.auth.onAuthStateChange((_, session) => { setUser(session?.user ?? null); }); return () => { authListener.unsubscribe(); }; }, []); return ( <div> {user ? ( <h1>Welcome, {user.email}</h1> ) : ( <> <Register /> <Login /> </> )} </div> ); }; export default Home;
Conclusion
You have now built a modern authentication system using Next.js 15 and Supabase. This setup allows users to register, log in, and manage their sessions seamlessly. You can further enhance this system by adding features like password recovery, email verification, and user profile management. Happy coding!