Setting up your project
For the Business website template on Next.js 16 with Supabase. Only what your project uses, in the order to do it.
Build this guide for your project
1. Run the project
- 1Unzip the download and open a terminal in the folder. Run
npm install. - 2Copy
.env.exampleto.env.localand fill in the 3 required values:NEXT_PUBLIC_SUPABASE_URL,NEXT_PUBLIC_SUPABASE_ANON_KEY,NEXT_PUBLIC_SITE_URL. Each provider section below says where to get them. - 3Run
npm run devand openhttp://localhost:3000. This is a Next.js 16 project (Turbopack by default); it needs Node 20 or newer. - 4The
README.mdinside the project repeats this guide under Go live, so you can hand the folder to someone else.
Pages in the Business website template, plus the sign-in pages Supabase adds
//products/pricing/about/support/contact/terms/privacy/login/signup/forgot-password/account
2. Supabase (auth and database)
Your project ships with sign in, sign up, a protected account page and a Postgres profiles table. It needs two values from your Supabase project. Nothing else changes.
Values you will paste into .env.local
NEXT_PUBLIC_SUPABASE_URLProject URL from Project settings → API.NEXT_PUBLIC_SUPABASE_ANON_KEYThe anon public key (newer projects call it the publishable key, sb_publishable_…). Never the service role or secret key: this key is the only Supabase credential the site holds.NEXT_PUBLIC_AUTH_GOOGLESet to 1 to show a “Continue with Google” button on the sign-in and sign-up pages, after enabling the Google provider in Supabase (see the guide).NEXT_PUBLIC_SITE_URLThe public URL of your site, without a trailing slash. Links in emails (sign-up confirmation, password reset, newsletter confirmation) are built from it, never from the incoming request. http://localhost:3000 while developing; your real domain, e.g. https://www.yourdomain.com, when you deploy.
Get your keys
- 1Go to supabase.com/dashboard and create a project. The free tier is enough. Pick a region close to your users and save the database password somewhere safe (you won't need it for this guide).
- 2In the left sidebar open Project settings (the gear icon), then API.
- 3Copy the Project URL. It looks like
https://abcdefghijkl.supabase.co. - 4Copy the anon public key. Newer projects call this the publishable key and it starts with
sb_publishable_; either works. Do not copy the service role or secret key, it must never be in a browser app.
Paste them into the env file
- 1In the project folder, copy
.env.exampleto.env.local. On macOS or Linux:cp .env.example .env.local. On Windows:copy .env.example .env.local. - 2Open
.env.localand fill in both values:
NEXT_PUBLIC_SUPABASE_URL=https://abcdefghijkl.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=sb_publishable_xxxxxxxxxxxxxxxxxxxx NEXT_PUBLIC_SITE_URL=http://localhost:3000
.env.local is ignored by git, so your keys stay out of version control. When you deploy, set the same variables in the host's environment settings, with NEXT_PUBLIC_SITE_URL changed to your real domain: the confirmation and reset emails link back to it.
Create the database table
- 1In the Supabase dashboard open SQL editor and click New query.
- 2Paste the contents of
supabase/migrations/0001_profiles.sqlfrom your project and click Run. This creates aprofilestable with row-level security and a trigger that fills it in when someone signs up.
Allow sign-in redirects
- 1Open Authentication → URL configuration.
- 2Set Site URL to
http://localhost:3000. When you deploy, change it to your domain, the same value asNEXT_PUBLIC_SITE_URL. - 3Under Redirect URLs add
http://localhost:3000/auth/callback**. Add your production domain the same way later, for examplehttps://example.com/auth/callback**. The two stars let the link carry anext=parameter, which the password reset uses. - 4The site asks Supabase to send people to
NEXT_PUBLIC_SITE_URL+/auth/callback; a destination that is not on the Site URL's domain or in the Redirect URLs is ignored and the email links to the Site URL instead. - 5Optional: under Authentication → Providers → Email, turn off Confirm email while developing so you can sign in immediately after signing up.
Try it
- 1Restart
npm run devso the new env file is read. - 2Open
http://localhost:3000/signup, create an account, confirm the email if required, and sign in. You land on/account, where you can edit your name; it reads and writes your row in theprofilestable. - 3Try Forgot password? on the sign-in page: the email link opens
/reset-passwordwith a recovery session so you can choose a new password.
Production email (recommended before launch)
- 1Supabase's built-in mailer sends only a few emails per hour and is meant for testing. Before real users sign up, switch to your own SMTP.
- 2If you enabled Resend: open Authentication → SMTP Settings, turn on Custom SMTP, and enter host
smtp.resend.com, port465, usernameresend, password = your Resend API key, sender = yourEMAIL_FROM. Any other SMTP provider works the same way. - 3Under Authentication → Email Templates you can reword the confirmation and reset emails.
Google sign-in (optional)
- 1In Google Cloud Console create an OAuth client ID of type Web application. Add
https://YOUR-PROJECT-REF.supabase.co/auth/v1/callbackas an authorised redirect URI (the exact value is shown in Supabase under Authentication → Providers → Google). - 2In Supabase open Authentication → Providers → Google, enable it, and paste the client ID and secret.
- 3Set
NEXT_PUBLIC_AUTH_GOOGLE=1in.env.localand restart. A Continue with Google button appears on the sign-in and sign-up pages.
Prefer the CLI to the SQL editor?
- 1Run
npx supabase@latest login, thennpx supabase@latest link --project-ref YOUR-PROJECT-REF(the ref is the first part of your Project URL). - 2Run
npm run db:pushto apply every file insupabase/migrations/. Re-run it whenever you add a migration.
What was added to your project
lib/supabase/client.ts, server.ts, session.ts, env.tsproxy.ts (Next 16) or middleware.ts (Next 15)app/login, app/signup, app/forgot-password, app/reset-password, app/accountapp/auth/actions.ts (sign in/up/out, password reset, profile update, Google), app/auth/callbacklib/safe-next.ts (keeps post-sign-in redirects on this site)lib/site-url.ts (the origin for links in emails, from NEXT_PUBLIC_SITE_URL)components/auth/auth-card.tsxsupabase/migrations/0001_profiles.sql, supabase/config.toml, npm run db:push
If something goes wrong
- “Supabase is not configured yet”: The env file is missing or the dev server was started before you saved it. Check the file name is exactly
.env.localand restart. - Sign-up email never arrives: Check spam, or turn off Confirm email under Authentication → Providers → Email while developing. Supabase's built-in mailer is rate-limited; for production, configure SMTP under Authentication → SMTP settings.
- Redirected to an error after clicking the confirmation link: The callback URL is not in Redirect URLs. Add it exactly as shown.
- “The site's public URL is not set”: On a deployed site
NEXT_PUBLIC_SITE_URLis missing or stillhttp://localhost:3000. Set it to your domain in the host's environment (with Cloudflare: in.env.local, thennpm run cf:secrets). - Account page shows no name: The SQL migration has not been run, so there is no
profilesrow. Run it and sign up again. - Reset link opens /login instead of the password form: The link expired (they last one hour) or was opened in a different browser. Request a new one.
- Google button does nothing or errors: Check the redirect URI in Google Cloud matches the one Supabase shows exactly, and that the provider is enabled with the client secret saved.
Missing something? See the full reference. Back to the builder