Build Log
·How to connect your Supabase project through the terminal
The first time someone tells you to just run supabase link it sounds simple. Then you open the terminal. This is the step-by-step guide I wish I'd had — what to type, what it means, and what to do when something doesn't work.
By The Non-Developer Developer
# How to connect your Supabase project through the terminal
**Slug:** connect-supabase-terminal
**Category:** Build Log
---
The first time someone tells you to "just run supabase link in your terminal," it sounds simple. Then you open the terminal and realise you don't know where to start.
This is the guide I wish I'd had. Step by step, exactly what to type, what each thing means, and what to do when something doesn't work.
By the end you'll have your local project connected to your live Supabase database — and you'll understand why each step matters, not just that it worked.
---
## Before you start
You need three things:
**The Supabase CLI installed.** If you haven't done this yet:
Mac:
```bash
brew install supabase/tap/supabase
```
Windows:
```bash
scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
scoop install supabase
```
Verify it worked:
```bash
supabase --version
```
You should see a version number. If you get "command not found," the install didn't complete — try again.
**Your terminal open at your project root.** This means the folder that contains your `package.json` file. If you're not sure, run `ls` and check you can see `package.json` in the output.
**Your Supabase project ref.** This is the short ID in your Supabase dashboard URL. When you're in the Supabase dashboard, look at the URL — it'll look something like `supabase.com/dashboard/project/abcdefghijklm`. That `abcdefghijklm` part is your project ref. Copy it somewhere handy.
---
## Step 1 — Log in to Supabase
```bash
supabase login
```
This opens a browser window asking you to authenticate. Log in with the same account you use for the Supabase dashboard. Once you've done that, come back to the terminal — it should confirm you're logged in.
You only need to do this once per machine. After that, the CLI remembers you.
---
## Step 2 — Link your repo to your Supabase project
```bash
supabase link --project-ref YOUR_PROJECT_REF
```
Replace `YOUR_PROJECT_REF` with the ID you copied from your dashboard URL.
This creates a connection between your local repo and your live Supabase project. When you run Supabase CLI commands after this, they'll know which project to talk to.
It'll ask for your database password. This is in Supabase → Project Settings → Database → Database password. If you've never set one, you can reset it from there.
**What this does in plain English:** it tells your local machine "when I say Supabase, I mean this specific project."
---
## Step 3 — Pull your current schema (important if you've been using Lovable)
If you've been building in Lovable or making changes directly in the Supabase dashboard, your database schema exists in Supabase but not in your local repo as migration files. Fix this now before anything else.
```bash
supabase db pull
```
This generates a migration file in `supabase/migrations/` that represents your current database state. From this point forward, every schema change goes through migration files — never through the dashboard directly.
**Why this matters:** once you start using Claude Code or Codex to build features, they'll create migration files based on what they can see in your repo. If your schema isn't captured there, the agent and your live database will drift out of sync. This one command prevents weeks of debugging.
---
## Step 4 — Verify the connection works
Run this to check your migration status:
```bash
supabase db status
```
You should see your migrations listed and their status. If you see errors here, your project ref or database password is wrong — go back and check both.
You can also connect directly to your database to confirm everything is working:
```bash
psql "postgresql://postgres:YOUR_DB_PASSWORD@db.YOUR_PROJECT_REF.supabase.co:5432/postgres"
```
Once you're in, run:
```sql
\dt
```
You should see a list of your tables. If you see them, you're connected. Type `\q` to exit.
---
## Step 5 — Set function secrets (if you're using Edge Functions)
If your project uses Supabase Edge Functions — for things like sending emails when someone submits a form — those functions need access to credentials they can't store in your repo for security reasons.
You set these as secrets:
```bash
supabase secrets set \
SUPABASE_URL=https://YOUR_PROJECT_REF.supabase.co \
SUPABASE_SERVICE_ROLE_KEY=YOUR_SERVICE_ROLE_KEY \
PUBLIC_SITE_URL=https://your-live-site.com \
RESEND_API_KEY=re_xxxxx \
TOOLKIT_FROM_EMAIL="Your Name "
```
What each one is:
| Secret | Where to find it |
|---|---|
| `SUPABASE_URL` | Your project URL — Supabase dashboard → Settings → API |
| `SUPABASE_SERVICE_ROLE_KEY` | Supabase dashboard → Settings → API → service_role key |
| `PUBLIC_SITE_URL` | The URL of your live website |
| `RESEND_API_KEY` | Your Resend account → API Keys |
| `TOOLKIT_FROM_EMAIL` | A sender address on your verified Resend domain |
**Important:** the service role key has full access to your database bypassing RLS. Never put it in your frontend code or commit it to git. Secrets are the right place for it.
---
## Step 6 — Deploy an Edge Function
If you have an Edge Function to deploy (for example, one that sends a confirmation email when someone submits a form):
```bash
supabase functions deploy your-function-name --no-verify-jwt
```
The `--no-verify-jwt` flag is needed for functions called from public forms — it allows unauthenticated requests. Don't use it for functions that should be protected.
---
## Step 7 — Test end to end
Once deployed, test the actual flow:
1. Trigger the function from your live site (submit the form, click the button — whatever calls it)
2. Check your inbox or wherever the output should appear
3. Confirm the result looks right
If something doesn't work, check the function logs in Supabase dashboard → Edge Functions → your function → Logs. The error will be there in plain text.
---
## Quick troubleshooting
**"Function not found"** — redeploy: `supabase functions deploy your-function-name --no-verify-jwt`
**500 error when form is submitted** — one of the secrets is missing or has the wrong value. Check them in Supabase dashboard → Settings → Secrets.
**Email not arriving** — check your email provider's logs first (Resend has a Logs tab). If the function ran successfully but no email arrived, the issue is on the email provider side, not in Supabase.
**Link in email goes to wrong URL** — fix `PUBLIC_SITE_URL` in your secrets.
**Sender address rejected** — make sure `TOOLKIT_FROM_EMAIL` uses a domain you've verified with your email provider.
**Database password wrong** — reset it in Supabase → Project Settings → Database → Reset database password. Then update it in your local `.env` file and anywhere else you've used it.
---
## The smoke test
Once everything is set up, run through this before considering it done:
1. Submit the form with your own email
2. Verify you receive the expected response in your inbox
3. Click every link in the email — confirm they go to the right places
4. Reply to the email — confirm reply-to behaviour works as expected
5. Submit the same email again — confirm it handles duplicate submissions gracefully without breaking
If all five pass, you're connected and working correctly.
---
## What you've actually done
If you've followed all of this, you've:
- Connected your local machine to your live Supabase project
- Captured your database schema in version-controlled migration files
- Set credentials securely as secrets rather than in code
- Deployed and tested a live backend function
These four things together are what "having a proper development setup" actually means. It's not glamorous but it's the foundation that makes everything else reliable.
The terminal felt intimidating at the start. By the time you've run these commands a few times, you'll be doing it without thinking.
---
*The SQL Starter Queries cheat sheet — including the commands to check your database connection and verify your RLS policies — is in the TNDD toolkit.*
*[Download the Toolkit]*