Supabase Login With Next.js: A Quick Tutorial
Hey guys! In this guide, we're diving into how to set up a Supabase login page using Next.js. Supabase is an awesome open-source Firebase alternative that makes it super easy to handle authentication, databases, and more. Next.js, on the other hand, gives us a fantastic React framework for building fast, scalable web apps. Marrying these two technologies can save you a ton of time and effort, so let's jump right in!
Setting Up Your Next.js Project
First things first, let’s get a Next.js project up and running. If you already have one, feel free to skip this part. Open your terminal and run the following command:
npx create-next-app supabase-login-app
This command uses create-next-app, which is the official Next.js CLI tool, to scaffold a new project named supabase-login-app. Once the project is created, navigate into the project directory:
cd supabase-login-app
Now, let's install the Supabase client library. This library will allow us to interact with our Supabase project from our Next.js application. Run the following command:
npm install @supabase/supabase-js
With our Next.js project set up and the Supabase client installed, we’re ready to move on to setting up our Supabase project. Trust me, it's easier than it sounds!
Creating a Supabase Project
Next, you'll need a Supabase project. Head over to Supabase and sign up for an account if you haven't already. Once you're logged in, create a new project. You'll be prompted to choose a name, a database password, and a region. Choose a name that reflects your project (e.g., "Next.js Login App"), set a strong password, and pick a region that's geographically close to your users for the best performance. After filling out all the necessary info, create the project.
Once your project is created, navigate to the "Settings" tab in the left sidebar, then click on "API". Here, you'll find your Supabase URL and anon key. These are essential for connecting your Next.js app to your Supabase project. Make sure to keep these keys secure and never expose them in your client-side code. Instead, we'll use environment variables to store them.
Back in your Next.js project, create a .env.local file in the root directory. Add the following lines to the file, replacing the placeholders with your actual Supabase URL and anon key:
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
Important: The NEXT_PUBLIC_ prefix is crucial. It tells Next.js to expose these environment variables to the client-side code. Without this prefix, the variables will only be available on the server-side.
Now that we have our Supabase project set up and our Next.js app configured with the necessary credentials, we can start building the login page.
Building the Login Page
Let's create a simple login page using Next.js components. Create a new file named login.js inside the pages directory. This file will contain the code for our login page. Here’s a basic implementation:
// pages/login.js
import { useState } from 'react';
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
const supabase = createClient(supabaseUrl, supabaseAnonKey);
export default function Login() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const handleLogin = async (e) => {
e.preventDefault();
setLoading(true);
setError(null);
try {
const { user, error } = await supabase.auth.signIn({
email: email,
password: password,
});
if (error) {
setError(error.message);
} else {
// Redirect to the home page or dashboard
window.location.href = '/';
}
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
return (
<h1>Login</h1>
{error &&
{error}
}
Email:
Password:
Login
);
}
In this code:
- We import
useStatefrom React to manage the form inputs and loading state. - We initialize the Supabase client using the URL and anon key from our environment variables.
- We define a
Logincomponent that renders a simple form with email and password inputs. - The
handleLoginfunction is called when the form is submitted. It callssupabase.auth.signInto authenticate the user with Supabase. - If the login is successful, we redirect the user to the home page. If there's an error, we display an error message.
Don't forget to create an index page or dashboard so that the redirect in the handleLogin function works correctly. For example, create pages/index.js:
// pages/index.js
export default function Home() {
return (
<h1>Welcome to the Home Page!</h1>
);
}
Now, run your Next.js development server:
npm run dev
Navigate to http://localhost:3000/login in your browser, and you should see the login form. Try logging in with valid credentials. If everything is set up correctly, you'll be redirected to the home page.
Enhancing the Login Page
Okay, so we have a basic login page working. But, it's a bit bare-bones, isn't it? Let's look at some ways to enhance it.
Adding Sign-Up Functionality
Right now, users can only log in if they already have an account. Let's add a sign-up form to allow new users to create accounts. Add the following code to your login.js file:
// pages/login.js
// Add this state variable
const [isSignUp, setIsSignUp] = useState(false);
// Add this function to handle sign-up
const handleSignUp = async (e) => {
e.preventDefault();
setLoading(true);
setError(null);
try {
const { user, error } = await supabase.auth.signUp({
email: email,
password: password,
});
if (error) {
setError(error.message);
} else {
// Optionally, redirect to a verification page or the home page
window.location.href = '/';
}
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
// Modify the return statement to include the sign-up form
return (
<h1>{isSignUp ? 'Sign Up' : 'Login'}</h1>
{error &&
{error}
}
Email:
Password:
{isSignUp ? 'Sign Up' : 'Login'}
{isSignUp ? 'Already have an account? Login' : 'Need an account? Sign Up'}
);
In this code:
- We add a
isSignUpstate variable to toggle between the login and sign-up forms. - We add a
handleSignUpfunction that callssupabase.auth.signUpto create a new user account. - We modify the return statement to include both the login and sign-up forms, and a button to switch between them.
Implementing Social Login
Social login allows users to sign in with their existing accounts from providers like Google, Facebook, or GitHub. Supabase makes it incredibly easy to implement social login. Here’s how:
First, you need to enable the desired providers in your Supabase project settings. Go to the "Authentication" tab in your Supabase dashboard, then click on "Providers". Enable the providers you want to support and follow the instructions to configure them. You'll typically need to create an app in the provider's developer console and provide the app ID and secret to Supabase.
Once you've enabled the providers, you can add the following code to your login.js file:
// pages/login.js
// Add this function to handle social login
const handleSocialLogin = async (provider) => {
setLoading(true);
setError(null);
try {
const { user, session, error } = await supabase.auth.signIn({
provider: provider,
});
if (error) {
setError(error.message);
} else {
// Redirect to the home page or dashboard
window.location.href = '/';
}
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
// Modify the return statement to include the social login buttons
return (
<h1>{isSignUp ? 'Sign Up' : 'Login'}</h1>
{error &&
{error}
}
Email:
Password:
{isSignUp ? 'Sign Up' : 'Login'}
{isSignUp ? 'Already have an account? Login' : 'Need an account? Sign Up'}
Sign in with Google
);
In this code:
- We add a
handleSocialLoginfunction that callssupabase.auth.signInwith theprovideroption to initiate the social login flow. - We add buttons for each social provider that call the
handleSocialLoginfunction when clicked.
Adding Real-time Updates
To enhance the user experience, you can add real-time updates to your login page using Supabase's real-time capabilities. For example, you can display a list of online users or show a notification when a new user signs up.
First, you need to enable real-time updates in your Supabase project settings. Go to the "Database" tab in your Supabase dashboard, then click on "Realtime". Enable real-time updates for the tables you want to subscribe to.
Once you've enabled real-time updates, you can add the following code to your login.js file:
// pages/login.js
import { useEffect, useState } from 'react';
// Add this state variable
const [onlineUsers, setOnlineUsers] = useState([]);
// Add this useEffect hook to subscribe to real-time updates
useEffect(() => {
const subscription = supabase
.from('users')
.on('*', (payload) => {
// Update the list of online users
setOnlineUsers((prevUsers) => {
if (payload.new.online) {
return [...prevUsers, payload.new];
} else {
return prevUsers.filter((user) => user.id !== payload.new.id);
}
});
})
.subscribe();
// Clean up the subscription when the component unmounts
return () => {
supabase.removeSubscription(subscription);
};
}, []);
// Modify the return statement to display the list of online users
return (
<h1>{isSignUp ? 'Sign Up' : 'Login'}</h1>
{error &&
{error}
}
Email:
Password:
{isSignUp ? 'Sign Up' : 'Login'}
{isSignUp ? 'Already have an account? Login' : 'Need an account? Sign Up'}
Sign in with Google
<h2>Online Users</h2>
{onlineUsers.map((user) => (
{user.email}
))}
);
In this code:
- We add a
onlineUsersstate variable to store the list of online users. - We add a
useEffecthook to subscribe to real-time updates from theuserstable. - The
useEffecthook updates theonlineUsersstate variable whenever a user comes online or goes offline. - We modify the return statement to display the list of online users.
Conclusion
Alright, awesome work, guys! You've successfully built a Supabase login page with Next.js. We covered everything from setting up your Next.js project and Supabase, to implementing the login form, social login, and real-time updates. Now you have a solid foundation for building more complex authentication flows and user experiences. Keep experimenting, and don't be afraid to dive deeper into the Supabase and Next.js documentation. You're on your way to creating some truly amazing web apps!