Step 5
Create your Supabase project & fill in .env.local
What you're about to do
Create a free Supabase project — your app's database and login system — and connect it to your app by filling in four values in .env.local, the file that holds your app's secret keys.
Why it matters
Your app can't even start without this. Supabase is what stores your data and signs users in. If these four values are missing, every page crashes with a “supabaseUrl is required” error — so we do this before the first run, not after.
What you'll need
Your project open in your code editor. A free Supabase account — use “Continue with GitHub” with the account you made in Step 1 so it's linked to your other tools. 10–15 minutes.
Create your Supabase project
- Go to supabase.com/dashboard (it's free — no credit card). Click “Continue with GitHub” and authorize with the account from Step 1. There is no “Sign up” button — signing in with GitHub creates your account.
- First time here? Supabase asks you to create an Organization first — that's just the container your projects live in. Give it any name (your own name is fine), choose the Free plan, and continue. You'll land on a Projects page.
- Click New project (top right).
- Fill in the form. It asks for more than you might expect — here's what matters:
- Organization — the one you just made.
- GitHub (optional) — skip this. You don't need it.
- Project name — anything; your app's name is fine.
- Database password — save it somewhere safe. You'll need it in a few minutes, and Supabase won't show it again. (“Generate a password” is fine — just copy it somewhere first.)
- Region — pick the one closest to you.
- Security — leave these at their defaults. The boilerplate expects them as-is.
- Click Create new project. Supabase takes a minute or two to set everything up — wait for it to finish before moving on.
Create your .env.local file
Your project already includes a file called .env.example that lists every value your app can use. You'll make a copy of it called .env.local — that copy is where your real secrets live, and it's automatically kept out of GitHub so they stay private.
In the terminal (inside your project folder), run:
Mac:
cp .env.example .env.localWindows (PowerShell):
copy .env.example .env.localNow open .env.local in your code editor. You'll fill in these four values next:
NEXT_PUBLIC_SUPABASE_URL=https://YOUR-PROJECT-REF.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=sb_publishable_...your-publishable-key...
SUPABASE_SERVICE_ROLE_KEY=sb_secret_...your-secret-key...
DATABASE_URL=postgresql://postgres.YOUR-PROJECT-REF:[YOUR-PASSWORD]@...pooler.supabase.com:6543/postgresThe placeholders above just show you the shape of each value. The next sections tell you exactly where to find the real ones in your Supabase dashboard.
1. Get your project URL
This is NEXT_PUBLIC_SUPABASE_URL.
- In your Supabase project, click the Connect button at the top of the page (it's also shown on your project home header).
- Copy the project URL — it looks like
https://abcdefgh.supabase.co. - Paste it as the value of
NEXT_PUBLIC_SUPABASE_URLin.env.local.
2. Get your API keys
These are NEXT_PUBLIC_SUPABASE_ANON_KEY and SUPABASE_SERVICE_ROLE_KEY — two keys, straight from the page Supabase opens by default.
- Click the gear icon at the bottom of the left sidebar (Project Settings), then choose API Keys.
- Stay on the tab that's already open — “Publishable and secret API keys.” Everything you need is here.
- Copy the Publishable key (the public one, starting with
sb_publishable_). Paste it asNEXT_PUBLIC_SUPABASE_ANON_KEY. - Copy the Secret key (the admin-level one, starting with
sb_secret_). Paste it asSUPABASE_SERVICE_ROLE_KEY.
Yes, the names look mismatched. That's expected.
Supabase renamed these keys — what it now calls the Publishable key and the Secret key used to be called anon and service_role. The variable names in your .env.local still use the old words. Nothing is wrong: same two values, same two slots. Your app accepts either the new keys or the old ones, so don't let the wording throw you.
The Secret key is a master key.
It can bypass all security rules. Keep it only in .env.local. Never paste it into a web form, share it, or commit it to GitHub. (Your .env.local is already ignored by git, so this is handled as long as the secret stays in that file.)
One button to avoid. You'll see a second tab called “Legacy anon, service_role API keys”. You don't need it — the keys you just copied are the current ones, and Supabase is retiring the legacy set. But if you do wander over there, don't click “Disable legacy API keys.” It's a one-way door that can break a working setup.
3. Get your database connection string
This is DATABASE_URL. Your app connects through the transaction pooler (port 6543), which is the right choice for an app like this.
Copy this string — don't type it out. The hostname is different for every Supabase project, so the only reliable version is the one Supabase shows you.
- Click the Connect button at the top of your project again.
- Choose the ORM tab, then select Drizzle (that's the database library this app uses).
- Under Configure ORM, make sure you're on the
.envtab. Supabase shows a ready-madeDATABASE_URL=line already pointing at the transaction pooler. Copy it. - Paste it into
.env.local, replacing theDATABASE_URLplaceholder line that's already there. - In the string you just pasted, replace
[YOUR-PASSWORD](including the square brackets) with the database password you saved when you created the project.
If your database password has symbols in it, read this.
Characters like @, #, ?, /, % and : have special meaning inside a connection string, so pasting them raw will break it — often with a confusing error that looks nothing like “bad password.” The easy fix: use a password with only letters and numbers. You can reset it under Project Settings → Database → Reset database password.
Save .env.local. That's all four values — next you'll set up your database.
How to verify it worked
- ✓You have a
.env.localfile in your project folder (not just.env.example) - ✓All four values are filled in:
NEXT_PUBLIC_SUPABASE_URL,NEXT_PUBLIC_SUPABASE_ANON_KEY,SUPABASE_SERVICE_ROLE_KEY, andDATABASE_URL - ✓Your two keys start with
sb_publishable_andsb_secret_(from the default API Keys tab) - ✓
DATABASE_URLis the string you copied from Supabase (it containspooler.supabase.comand port6543), and you replaced[YOUR-PASSWORD]with your real password — no square brackets left anywhere
If all four are true, you're ready for Step 6.
What to do if something went wrong▾
Problem: the dashboard says “Publishable” and “Secret,” but my .env.local says ANON_KEY and SERVICE_ROLE_KEY.
Nothing's wrong — those are the same two values under older names. Publishable goes in the ANON_KEY line, Secret goes in the SERVICE_ROLE_KEY line. Supabase changed what it calls them; the variable names haven't caught up.
Problem: I followed an older guide and my keys start with eyJ.
Those are Supabase's legacy keys, and they still work — your app accepts either format, so you don't have to change anything today. But Supabase is retiring them, so next time you're in the dashboard, grab the sb_publishable_ and sb_secret_ keys from the default API Keys tab and swap them in.
Problem: I can't find .env.example in my editor.
Files starting with a dot are hidden by default in some places, but your code editor's file explorer shows them. Make sure you've opened your project folder in the editor (the one with package.json in it). If the copy command in the terminal succeeded, .env.local is there even if it looks hidden.
Problem: I forgot my database password.
You can reset it in Supabase under Project Settings → Database → Reset database password. Then use the new password in DATABASE_URL. (Stick to letters and numbers — see the warning above.)
If you're stuck, click Support at the top of this page.