78  78. Step 5: Setup Supabase

As of Oct 22, 2026 · Official docs: Supabase · Supabase API keys

Supabase is an online service that gives you the tools you need to store and manage data for your app. It includes:

78.1 Remote vs. Local Supabase

Supabase can run remotely (hosted online by Supabase) and/or locally (running on your own computer). For beginners, remote Supabase is far easier. Everything happens in your browser, and nothing must be installed or configured. Local Supabase is mainly for advanced users and developers who want to test everything on their own computer before uploading to the Internet. Having a local copy of supabase also allows you to develop your app during times that you don’t have access to the Internet. Running Supabase locally needs a program named Docker (see “Deeper dive: Docker” in Step 5a: Supabase CLI command).

In this tutorial we will use remote Supabase only, so you do not need to install a local copy, or Docker, or manage anything technical on your machine.

78.2 Keep your setup worksheet open

From this step on, you collect IDs, web addresses and keys from several websites. Record them in the course’s setup worksheet (an Excel file):

Download the Task App Setup Worksheet (Excel)

  • Keep it in ~/projects/full-stack-demo-app, next to your task-app code folder and not inside it, so Git can never upload it to GitHub.
  • On its My Info sheet, fill in the yellow cells as you go. Gray cells fill themselves in: once you type your Supabase project ref, the worksheet builds your Supabase URL for you.
  • Its Commands sheet builds, from your values, the exact lines you copy, for example the two lines of your .env.local file.

Classes 10–12: Start here explains the worksheet in more detail.

The worksheet holds secret keys

Anyone with your secret keys or your database password can use your accounts. Don’t email the worksheet, post it, or show it while sharing your screen. Account passwords (for example your Supabase login) don’t go in it; keep those in your browser’s password manager.

78.3 Sign Up for Supabase

  1. Go to supabase.com and sign up. Continue with GitHub is easiest.
  2. Supabase first asks you to create an organization. Give it any name, choose the Free plan, and create it.
  3. Click New project.

A project is one complete back end for one app: its own database, its own users, its own keys and its own web address. An organization holds projects, like a company holds departments: it has the billing plan and the team members who may work on its projects.

The free plan allows only a few active projects, so if you used Supabase before, you may have to pause or delete an old project first.

78.4 Project Configuration

Fill in the “Create a new project” form:

  • GitHub (optional): skip it; don’t click Connect GitHub.
  • Project name: task-app.
  • Database password: click Generate a password and copy the password into the worksheet right away.
  • Region: the area closest to you and your users, for example Americas.
  • Security: leave Enable Data API and Automatically expose new tables on, and turn on Enable automatic RLS.

Click Create new project. It takes a couple of minutes.

Important: the app itself never uses the database password, but the Supabase CLI may ask for it when you link your folder to the project (Step 5a), and it needs it to create your tables later. Anyone who has it can read and change all of your data, so keep it only in the worksheet.

The “Create a new project” form

The “Create a new project” form

The region is where Supabase’s data center for your project is. Data takes time to travel, so a region close to your users makes the app faster. “Americas” lets Supabase pick a data center in the Americas.

  • The Data API is a web API that Supabase creates for your database automatically. The app’s code in the browser reads and changes tables by sending web requests to your project’s address. Without it, the app couldn’t reach its data.
  • Automatically expose new tables gives the Data API permission to use each new table. The app’s database setup (its migrations, see Step 9: Set Up Supabase Database) creates its tables but doesn’t grant those permissions itself; it relies on this setting. With it off, every request would fail with “permission denied”. (Supabase recommends turning it off and granting access to each table yourself; this older code wasn’t written that way.)
  • Row Level Security (RLS) is a set of rules, stored in the database, about which rows each user may see or change, for example “a user sees only their own tasks”. The Data API is open to anyone who has the publishable key, and that key is inside the app’s web pages, so RLS is what keeps one user out of another user’s data. Enable automatic RLS turns RLS on for every new table, so a table someone forgets to protect is locked (it looks empty) instead of open to everyone.

78.5 Get Your API Keys

Once your project is created:

  1. Record your project ref, URL and publishable key in the worksheet.

    • The URL. Your project’s home page in the Supabase dashboard shows the project URL under the project’s name, with a Copy button. It looks like https://qzvbnmtrewplkjhgfdsa.supabase.co.
    • The project ref is the part of the URL before .supabase.co, in this example qzvbnmtrewplkjhgfdsa. It is your project’s unique ID.
    • The publishable key. Click the API Keys card under Get connected on the home page, or go to Project Settings > API Keys. The publishable key starts with sb_publishable_. Click the copy icon next to it, because the page shows only the start of the key.

    If a Preview box appears at the bottom right of the dashboard, close it with its ×.

    The project’s home page: the URL under the name, and the API Keys card under Get connected

    The project’s home page: the URL under the name, and the API Keys card under Get connected

    The API Keys page (the keys are hidden in this picture)

    The API Keys page (the keys are hidden in this picture)
  2. Open the .env.local file in VS Code (in the task-app folder). You made it in Step 3: Storing your private info (env files, etc) by copying .env.example. It starts with notes (lines that begin with #) that explain the file, and ends with the two settings the app needs:

    NEXT_PUBLIC_SUPABASE_URL="https://XXXX.supabase.co"
    NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY="sb_publishable_XXXX"

    A value with XXXX in it is a placeholder: it only shows what your value looks like.

  3. Replace the two lines. The easiest way: copy the two .env.local lines from the worksheet’s Commands sheet and paste them over these two lines. To do it by hand instead, replace each whole value between the quotes with your own and keep the quotes: your URL in place of https://XXXX.supabase.co, and your publishable key in place of sb_publishable_XXXX. The key you copy already starts with sb_publishable_, so don’t type that part twice.

  4. Save the file. If the app is running (npm run dev), stop it with Ctrl+C and start it again: the app reads .env.local when it starts.

Publishable key and secret key

The API Keys page shows two kinds of keys:

  • The publishable key (sb_publishable_...) is safe to put in a web page: it only allows what your database’s security rules (RLS) allow. It goes in .env.local.
  • The secret key (sb_secret_...) skips all of those rules and can read and change everything, so it must never go into .env.local or into any variable whose name starts with NEXT_PUBLIC_. The app doesn’t need you to put it anywhere. (Only the optional automated tests use it, in Step 15.)

The tutorial video copies an older key, the “anon” key, from the Legacy tab. Ignore that tab and use the publishable key instead.

78.6 Two sign-in settings

Still in the Supabase dashboard, change two authentication settings (authentication, or “auth”, means checking who a user is). The dashboard has two menus on the left: a narrow column of icons (hold the mouse over it to see their names), and next to it a menu for the part you’re in. In the icon column, click Authentication, then move the mouse away from the icons: the second menu, titled Authentication, appears. Under CONFIGURATION:

  • Sign In / Providers, in the User Signups section: turn off Confirm email and click Save changes.
  • URL Configuration: check that Site URL is http://localhost:3000 (a new project already has it). Under Redirect URLs, click Add URL, type http://localhost:3000/**, and click Save URLs.

With Confirm email on, Supabase emails every new user a link, and the account works only after they click it. While you test with made-up accounts, those emails would never arrive, so you turn it off. A real app would turn it back on.

When someone signs in with Google (Step 6), their browser goes from your app to Google, from Google to Supabase, and then back to your app. The Site URL is the default address for that last trip. The redirect URLs are other addresses Supabase may send users back to. Only listed addresses are allowed, so that nobody can trick Supabase into sending a freshly signed-in user, with their login token, to a different website.

This app sends users back to http://localhost:3000/dashboard, which is not the Site URL, so it must be on the list. ** is a wildcard: it matches any characters, including /, so the one entry http://localhost:3000/** allows every page of the app on your computer. (A single * would stop at the next /.) When you put the app online (Step 13), you add its online address the same way.

The icon column, widened while the mouse is over it

The icon column, widened while the mouse is over it

Authentication > Sign In / Providers, with Confirm email still on

Authentication > Sign In / Providers, with Confirm email still on

Adding the redirect URL

Adding the redirect URL

URL Configuration after adding it

URL Configuration after adding it
Don’t sign in to the app yet

Every new user automatically gets a Stripe customer record, so signing up in the app fails until Stripe is set up (Step 8: Set Up Stripe).

Practice Questions

Easy

Question 1 · Multiple choice

Which of the following is not one of the Supabase features listed on this page?

  1. A database for storing structured data
  2. Authentication, so users can sign in to your app
  3. File storage in the cloud
  4. Processing credit card payments

d. Supabase gives you a database, authentication, file storage and edge functions. Payments are not a Supabase feature; in this project they are handled by a separate service, Stripe. Options a, b and c are all on the page’s list.

Question 2 · Short answer

What are Supabase edge functions?

Small pieces of code that run on servers close to your users (on Supabase’s servers, not in the user’s browser). In task-app, edge functions do jobs such as asking the OpenAI API to pick a tag for a task and talking to Stripe.

Question 3 · True or false

In this tutorial, you install and run your own copy of the Supabase server on your computer.

False. The tutorial uses remote Supabase only: Supabase runs the server online, and you set it up through your browser. Running Supabase locally is mainly for advanced developers, and it needs Docker, which this tutorial doesn’t use.

Question 4 · Short answer

On the “Create a new project” form, what do you enter or choose for the project name, the database password and the region?

  1. Project name: task-app.
  2. Database password: click Generate a password, and copy the password into the worksheet right away.
  3. Region: the area closest to you and your users, for example Americas.

(You also skip the optional GitHub connection and set the three Security settings.)

Question 5 · Short answer

What is the difference between a Supabase organization and a Supabase project?

A project is one complete back end for one app: its own database, users, keys and web address. An organization holds projects, like a company holds departments; it has the billing plan (here the Free plan) and the team members who may work on its projects.

Medium

Question 6 · Multiple choice

Most of your app’s users will be in New York. Which region should you pick for your Supabase project?

  1. A region on another continent, where data centers may be cheaper
  2. The region closest to your users, such as Americas
  3. Any region; the choice makes no difference
  4. Whichever region is listed first in the menu

b. Choose the region closest to your users. Data that travels a shorter distance arrives faster, so the app responds more quickly. A far-away region (a) makes every request slower, and the region does make a difference (c). The order of the menu (d) means nothing.

Question 7 · Short answer

Give two reasons why a developer might run Supabase locally (on their own computer) instead of using only the remote version.

  1. To test everything on their own computer before uploading it to the Internet.
  2. To keep working on the app when they don’t have Internet access.

The price is that local Supabase must be installed and configured (it needs Docker), which is why this tutorial uses remote Supabase.

Question 8 · Fill in the blank

Your project URL is https://qzvbnmtrewplkjhgfdsa.supabase.co. What is your project ref? Then write the complete line in .env.local that stores the URL.

The project ref is the part before .supabase.co: qzvbnmtrewplkjhgfdsa. The line is:

NEXT_PUBLIC_SUPABASE_URL="https://qzvbnmtrewplkjhgfdsa.supabase.co"

Keep the variable name and the quotes exactly as they are, and replace the whole placeholder https://XXXX.supabase.co with your real URL. (The worksheet’s Commands sheet builds this line for you once you have typed in your ref.)

Question 9 · Short answer

The API Keys page shows a publishable key and a secret key. Which one goes into .env.local, and why must the other one never go there?

The publishable key (sb_publishable_...) goes into .env.local. Settings whose names start with NEXT_PUBLIC_ are built into the web pages that every visitor’s browser downloads, so anyone could read them. That’s fine for the publishable key, which only allows what the database’s security rules (RLS) allow. The secret key (sb_secret_...) skips those rules and can read and change everything in the database, so it must never end up where visitors can read it.

Question 10 · True or false

Even though your project is a Git repository, it is OK to type your real Supabase values into .env.local.

True. As the notes at the top of the file say, .env.local is never uploaded to GitHub: the project’s .gitignore file tells Git to skip it. That is exactly why real values go into .env.local and not into .env.example, which is committed. Still, treat the file as private.

Question 11 · Multiple choice

Where should you keep the setup worksheet?

  1. Inside the task-app folder, so it is next to the code
  2. In ~/projects/full-stack-demo-app, next to the task-app folder
  3. In your fork on GitHub, so you can’t lose it
  4. In the README of your project

b. Git tracks only the files inside task-app, so a worksheet next to that folder can never be uploaded to GitHub by accident. Inside task-app (a), a careless commit could upload your keys. GitHub (c) and the README (d) would publish the keys.

Question 12 · Short answer

Why do you turn off Confirm email in Supabase’s authentication settings, and should a real app keep it off?

With Confirm email on, every new account works only after the user clicks a link that Supabase emails them. You test with made-up accounts whose emails would never arrive, so you turn it off. A real app would turn it back on, because the email proves that the address belongs to the user.

Hard

Question 13 · Scenario

Sam starts the app, but nothing that needs Supabase works. His .env.local contains:

NEXT_PUBLIC_SUPABASE_URL="https://XXXX.supabase.co"
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY="sb_publishable_XXXX"

What went wrong, and how does he fix it?

He never replaced the placeholders that came from the example file, so the app is trying to reach a Supabase project that doesn’t exist. He needs to put his own project’s URL and publishable key into these two lines (for example by pasting the two .env.local lines from his worksheet’s Commands sheet), and save the file. Restarting the development server (npm run dev) makes sure the app picks up the new values.

Question 14 · Short answer

The app never uses your database password. Why must you still save it in the worksheet, and why must you keep it secret?

  1. Tools that connect to the database directly need it. The Supabase CLI may ask for it when you link your folder to the project, and it uses it when it creates your tables.
  2. It is the password to your project’s database. Anyone who has it could connect to the database and read or change all of your app’s data, so it goes only in the worksheet: never in Git, never shared.

Question 15 · Scenario

Maria created her project with Automatically expose new tables turned off. Later, after the app’s tables are created, every request from the app fails with “permission denied”. Explain why.

The app’s code reaches its tables through Supabase’s Data API. The setting gives the Data API permission to use each new table. This app’s database setup creates the tables but doesn’t grant those permissions itself; it relies on the setting. With the setting off, the Data API may not use the tables, so every request fails with “permission denied”.

Question 16 · Long answer

The publishable key is inside the app’s web pages, where anyone can read it. Explain why Row Level Security (RLS) matters because of this, and what Enable automatic RLS adds.

Anyone who has the publishable key can send requests to the Data API, and anyone can read the key in the web pages. So the key alone can’t protect the data. RLS rules, stored in the database, decide which rows each user may see or change (for example, only their own tasks); they are what keeps one user out of another user’s data.

Enable automatic RLS turns RLS on for every new table. A table someone forgets to write rules for is then locked (it looks empty) instead of open to everyone. A good answer mentions both points: the key is public, and RLS is the real protection.

Question 17 · Scenario

After signing in with Google, Supabase should send users back to http://localhost:3000/dashboard, but they never get there. Under Redirect URLs, Sam had typed only http://localhost:3000. What is wrong, and what should the entry be?

Supabase only sends users back to addresses on its list, and http://localhost:3000/dashboard isn’t on it: the entry http://localhost:3000 matches only that one address. The entry should be http://localhost:3000/**. ** is a wildcard that matches any characters, including /, so the one entry allows every page of the app on your computer. (A single * would stop at the next /.)

Question 18 · True or false

Two classmates clone the same task-app repository from GitHub. Because the Supabase project URL is stored in the repository, both copies of the app automatically use the same Supabase project.

False. The repository only contains .env.example, with placeholders such as https://XXXX.supabase.co. Each student creates their own Supabase project and puts its URL in their own .env.local. That file is ignored by Git, so it never goes into the repository, and each copy of the app talks to its own project.

© 2025-2026 Y. Rosenthal. All rights reserved.