This is the operational guide for running Peels with the Supabase CLI, preview branches, and local mock data.
- Git repo: schema migrations, local bucket config, local seed data, and app code
- Supabase dashboard: GitHub integration, preview branches, and hosted project settings
- GitHub settings: required PR checks on
main - Vercel settings: preview environment variables
If you remember one thing, make it this: we now treat supabase/ in Git as the source of truth for schema work, but a few platform toggles still have to be enabled once in Supabase, GitHub, and Vercel.
Official reference: Supabase GitHub integration docs
- Open the Peels project in the Supabase dashboard.
- Go to
Project Settings->Integrations. - Under
GitHub Integration, clickAuthorize GitHub. - Complete the GitHub authorisation flow and return to Supabase.
- Choose the Peels GitHub repository.
- Set the Supabase directory path to
supabase. - Turn on
Automatic branching. - Turn on
Supabase changes only. - Leave
mainas the production branch. - Do not turn on
Deploy to productionuntil you are happy with preview-branch behaviour. - Save or enable the integration.
What this does:
- A PR branch that changes
supabase/**gets its own Supabase preview branch. - That preview branch runs migrations and bucket config from Git.
- Seed data comes from
supabase/seed.sql, not from production data. - Demo media is tracked under
supabase/storage/, but is uploaded only into local Supabase withnpm run seed:local-media.
Official reference: GitHub branch protection docs
- Open the Peels GitHub repository.
- Go to
Settings->Branches. - Edit the existing rule for
main, or create one if there is not already a rule. - Turn on
Require status checks to pass before merging. - In the check list, select
Supabase Previewonce it has appeared at least once on a PR. - Keep
Require branches to be up to date before mergingon if you want stricter protection. - Save the branch rule.
What this does:
- GitHub will block merging a PR into
mainif Supabase could not build the preview branch cleanly.
Official reference: Vercel environment variable docs
- Open the Peels project in Vercel.
- Go to
Settings->Environment Variables. - Check what is currently set for:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEY
- Keep the production values for the
Productionenvironment. - Set
Previewvalues so preview deployments use the Supabase branch credentials instead of production credentials. - If you want branch-specific overrides, add them for the matching Git branch in Vercel.
- Redeploy a preview deployment after changing the variables.
What this does:
- Your preview frontend talks to the preview Supabase branch instead of the live Peels database.
npm install
cp .env.example .env.local
npm run supabase:start
npm run supabase:reset
npm run seed:local-media
npm run supabase:envThen make sure .env.local has:
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54331
NEXT_PUBLIC_SUPABASE_ANON_KEY=<paste the ANON_KEY value here>Do not mix the hosted project URL with the local anon key. That combination fails with Invalid API key.
Finally:
npm run devBoth Playwright suites expect the local seeded Supabase stack, not the hosted Peels project.
Use this shape in .env.local before npm run test:e2e:prod:
NEXT_PUBLIC_SITE_URL=http://127.0.0.1:3000
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54331
NEXT_PUBLIC_SUPABASE_ANON_KEY=<paste the ANON_KEY value from npm run supabase:env>Recommended sequence:
- Run
npm run supabase:start - Run
npm run supabase:reset - Run
npm run seed:local-media - Run
npm run supabase:env - Paste the printed
ANON_KEYinto.env.local - Run
npm run test:e2eornpm run test:e2e:prod
If .env.local still points at https://mfnaqdyunuafbwukbbyr.supabase.co, the smoke suite will not see the seeded local listings, demo accounts, or demo chat thread.
- App:
http://127.0.0.1:3000 - Supabase API:
http://127.0.0.1:54331 - Supabase Studio:
http://127.0.0.1:54333 - Mailpit:
http://127.0.0.1:54334
Peels intentionally uses the 54331-54334 range so you can run it alongside other Supabase projects that still use the default local ports.
Supabase captures local auth emails in Mailpit instead of sending them to a real inbox. After npm run supabase:start, open http://127.0.0.1:54334 to inspect password reset, magic-link, invite, and email-change messages generated by the local stack.
The local stack uses Supabase's built-in auth email templates unless the Send Email Auth Hook is configured locally. The Peels custom auth email implementation lives in supabase/functions/send-email-for-auth-action, but that function is only used when Supabase Auth is configured to call it as the send_email hook. Hosted environments configure that in Supabase Auth Hooks; the default local config.toml path keeps Mailpit simple and uses the built-in templates.
For reset-password testing, use the reset link from Mailpit and keep the app running at http://127.0.0.1:3000. supabase/config.toml allow-lists http://127.0.0.1:3000/** and http://localhost:3000/** so Supabase can redirect through /auth/complete before landing on /profile/reset-password.
Both local demo accounts use the password peels-demo-password.
- Host account:
demo-host@peels.local - Donor account:
demo-donor@peels.local
The seed also creates:
- 3 public listings
- 1 chat thread
- 2 chat messages
- seeded profile avatars and listing photos in local Supabase Storage
The demo data is synthetic and safe to keep in Git.
When NEXT_PUBLIC_SUPABASE_URL points at http://127.0.0.1:54331, avatar and listing-photo uploads also go to the local Supabase buckets rather than production. Repo-tracked bucket media is uploaded only by npm run seed:local-media, not by hosted Supabase deploys.
Use this when setting up Peels on a new machine.
- Node.js
- npm
- Docker Desktop
- Supabase CLI
- Clone the repo.
- Run
npm install. - Copy
.env.exampleto.env.local. - Run
npm run supabase:start. - Run
npm run supabase:reset. - Run
npm run seed:local-media. - Run
npm run supabase:env. - Set
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54331in.env.local. - Copy the printed
ANON_KEYintoNEXT_PUBLIC_SUPABASE_ANON_KEYin.env.local. - Run
npm run dev. - Sign in with one of the demo accounts above.
If the app still shows old environment values, clear the build cache and restart:
rm -rf .next
npm run dev- Start local Supabase with
npm run supabase:start. - Make schema changes locally.
- Add or edit SQL migrations under
supabase/migrations/. - Rebuild from scratch with
npm run supabase:reset. - Upload local demo media with
npm run seed:local-mediaafter any reset that needs repo-tracked avatars or listing photos. - Run
npm run dev. - Test the flow locally.
- Commit app and migration changes together.
Use local Studio, psql, or the hosted dashboard for browsing rows. Use the CLI for schema lifecycle.
Right now the changes are only in your working tree on main. The safe path is:
- Create a feature branch from the current state.
- Stage only the Supabase local-first rollout files.
- Commit them together.
- Push the feature branch.
- Open a PR into
main. - Enable the required
Supabase Previewcheck once it appears on the PR.
Suggested branch name:
git switch -c dnywh/supabase-local-firstThen review what is staged before committing:
git status
git diff --cachedThis keeps main clean and makes the rollout easy to review.