Build A Next.js App With Supabase: A Complete Tutorial
Build a Next.js App with Supabase: A Complete Tutorial
Hey everyone! 👋 Today, we’re diving into a super cool tutorial: building a full-stack application using Next.js and Supabase . If you’re looking to learn how to create modern web apps with a robust backend, you’re in the right place. We’ll cover everything from setting up your project to implementing user authentication, database interactions, and even real-time updates. By the end of this tutorial, you’ll have a solid understanding of how to use Supabase with Next.js and be able to build your own awesome projects. So, let’s get started!
Table of Contents
Setting Up Your Next.js and Supabase Project
First things first, we need to get our project set up. This involves installing Next.js and creating a Supabase project. Don’t worry, it’s pretty straightforward, even if you’re new to both technologies. First, let’s get Next.js up and running. Open your terminal and run the following command to create a new Next.js project. We’ll name our project
supabase-nextjs-tutorial
:
npx create-next-app supabase-nextjs-tutorial
This command will set up a basic Next.js application with all the necessary dependencies. Now, let’s navigate into the project directory:
cd supabase-nextjs-tutorial
Next up, let’s create our Supabase project. Head over to the Supabase website and sign up or log in. Once you’re logged in, create a new project. You’ll be prompted to choose a name, region, and database password. Choose a name that reflects your project (e.g., “nextjs-supabase-app”), select a region close to your users, and set a strong password. After your project is created, you’ll be taken to the Supabase dashboard. Here, you’ll find all the tools you need to manage your database, authentication, and more. Back in your Next.js project, you’ll need to install the Supabase client library. This library allows you to interact with your Supabase backend from your Next.js application. Run this command in your terminal:
npm install @supabase/supabase-js
With both Next.js and Supabase set up, your project is ready for the next steps! We’ve laid the groundwork; now it’s time to integrate Supabase into our Next.js application. We’ll start by initializing the Supabase client and setting up authentication.
Initializing Supabase and Setting Up Authentication
Now, let’s connect our Next.js app to Supabase. This involves initializing the Supabase client and configuring user authentication.
Authentication
is a crucial part of almost any modern web application, so we’ll make sure to get this right. First, we need to grab our project’s API keys from the Supabase dashboard. Go to your Supabase project’s settings (the gear icon) and then to “API keys.” You’ll see two important keys:
anon public
and
service_role
. The
anon public
key is used for client-side operations (like in your Next.js app), while the
service_role
key should be kept secret and is used for server-side operations.
Next, create a new file in your Next.js project to handle the Supabase client initialization. A common place for this is in a directory called
lib
, so create a file
lib/supabase.js
and add the following code:
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);
In this code, we’re importing
createClient
from the
@supabase/supabase-js
library. We’re also retrieving
supabaseUrl
and
supabaseAnonKey
from environment variables. These variables will hold your Supabase project’s URL and anonymous key, respectively. It’s important to keep sensitive information like API keys out of your codebase and into environment variables. To set these environment variables, create a
.env.local
file in the root of your Next.js project if you haven’t already. Add the following lines, replacing
YOUR_SUPABASE_URL
and
YOUR_SUPABASE_ANON_KEY
with your actual Supabase project URL and anonymous key (found in your Supabase dashboard):
NEXT_PUBLIC_SUPABASE_URL=YOUR_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY
Make sure to prefix your environment variables with
NEXT_PUBLIC_
if you want them to be accessible in the client-side code. This is a Next.js requirement. Next, we’ll move on to implementing user authentication. Let’s create a simple sign-up and sign-in form in a new component.
Implementing User Authentication with Supabase and Next.js
With the Supabase client initialized, let’s implement user authentication. We’ll create a simple form for signing up and signing in. Create a new component file, perhaps named
components/AuthForm.js
, and add the following code:
import { useState } from 'react';
import { supabase } from '../lib/supabase';
const AuthForm = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const handleSignup = async (e) => {
e.preventDefault();
setLoading(true);
setError(null);
try {
const { error } = await supabase.auth.signUp({ email, password });
if (error) throw error;
alert('Check your email for a verification link!');
} catch (error) {
setError(error.message);
} finally {
setLoading(false);
}
};
const handleSignin = async (e) => {
e.preventDefault();
setLoading(true);
setError(null);
try {
const { error } = await supabase.auth.signInWithPassword({ email, password });
if (error) throw error;
alert('Successfully logged in!');
} catch (error) {
setError(error.message);
} finally {
setLoading(false);
}
};
return (
<div>
{error && <p style={{ color: 'red' }}>{error}</p>}
{loading && <p>Loading...</p>}
<form onSubmit={handleSignup}>
<div>
<label htmlFor="email">Email</label>
<input
type="email"
id="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div>
<label htmlFor="password">Password</label>
<input
type="password"
id="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<button type="submit" disabled={loading}>Sign up</button>
</form>
<form onSubmit={handleSignin}>
<div>
<label htmlFor="email">Email</label>
<input
type="email"
id="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div>
<label htmlFor="password">Password</label>
<input
type="password"
id="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<button type="submit" disabled={loading}>Sign in</button>
</form>
</div>
);
};
export default AuthForm;
This component includes input fields for email and password, as well as functions to handle sign-up and sign-in using
supabase.auth.signUp
and
supabase.auth.signInWithPassword
. The component also displays loading indicators and error messages to provide feedback to the user. To use this component, import it into your
pages/index.js
file and render it. You can also add some basic styling to make it look nicer.
// pages/index.js
import AuthForm from '../components/AuthForm';
const Home = () => {
return (
<div>
<h1>Welcome to My App</h1>
<AuthForm />
</div>
);
};
export default Home;
After implementing these steps, you should be able to create an account and log in. Supabase will send a verification email, and upon verification, the user will be authenticated. Now, let’s explore how to integrate a database into your Next.js application.
Integrating a Database with Supabase and Next.js
Next, let’s explore database integration. Supabase provides a powerful and easy-to-use database built on PostgreSQL. We’ll create a simple table and learn how to perform CRUD (Create, Read, Update, Delete) operations. First, let’s create a table in your Supabase dashboard. Go to the