Nextbase Docs
Nextbase Docs
HomeBlogWelcome to Nextbase v5!Choose your starterGetting startedLocal Supabase per agent
Next.js + SupabaseInstallationEnvironment variablesAuthenticationAgent connectionsProject structureDeployment
AuthenticationWorkspaces and the admin area
Building with agentsEmails with Resend
TroubleshootingNextbase v5
The 8 starter kitsNext.js + Supabase

Environment variables

Every variable in the Next.js + Supabase starter's env files for the web and admin apps, what it does and where the value comes from.

The kit has one env file per Next.js app: apps/web/.env.local (from apps/web/.env.local.example) and apps/admin/.env.local (from apps/admin/.env.local.example). Each app also ships a .env.test with the same placeholders; the web one is the template the Playwright global setup turns into apps/web/.env.test.local. The database and email apps have no env files of their own.

pnpm supabase:sync-env writes the local Supabase URL and keys into both .env.local files. Variables prefixed NEXT_PUBLIC_ are bundled into the browser. Everything else is server-only. Never commit .env.local; it is in .gitignore.

Key names

This kit reads NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY and SUPABASE_SECRET_KEY. The older NEXT_PUBLIC_SUPABASE_ANON_KEY and SUPABASE_SERVICE_ROLE_KEY names are not read anywhere in either app.

apps/web/.env.local

Supabase

VariableRequiredExposurePurposeWhere to get it
NEXT_PUBLIC_SUPABASE_URLYesPublicSupabase API URL used by every client, middleware, the MCP adapter and the Supabase Storage remotePatterns entry in next.config.tspnpm supabase:sync-env, or env.API_URL from supabase status --output-format json. Production: project settings in the Supabase dashboard
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYYesPublicBrowser and user-session clientspnpm supabase:sync-env, or env.PUBLISHABLE_KEY. Production: API keys in the dashboard
SUPABASE_SECRET_KEYYesServerService-role client in src/supabase-clients/admin/ and src/mcp/pnpm supabase:sync-env, or env.SECRET_KEY. Production: API keys in the dashboard
SUPABASE_DATABASE_PASSWORDOptionalServerPresent in the example with the local default. Not read by the web app's sourceLocal default is postgres
SUPABASE_POSTGRES_DB_URLTestsServerDirect Postgres connection for the Playwright admin helpers. The global setup overwrites it in .env.test.local from env.DB_URLenv.DB_URL from supabase status
SUPABASE_JWT_SIGNING_KEYOptionalServerSigns tokens for the Unkey-backed Supabase client in src/supabase-clients/unkey/Only needed when you issue API keys through Unkey
SUPABASE_PROJECT_REFOptional, commented outServerReference for linking the CLI to a hosted project. Not read by the web app's sourceSupabase project settings

Stripe

VariableRequiredExposurePurposeWhere to get it
STRIPE_SECRET_KEYFor billingServerPayment gateway in src/payments/stripe-payment-gateway.tsStripe dashboard, API keys
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYFor billingPublicStripe.js in the browserStripe dashboard, API keys
STRIPE_WEBHOOK_SECRETFor billingServerVerifies /api/stripe/webhooks signaturesStripe webhook endpoint, or the secret printed by stripe listen --forward-to localhost:3000/api/stripe/webhooks

Host

VariableRequiredExposurePurposeWhere to get it
NEXT_PUBLIC_SITE_URLYesPublicCanonical web origin for redirects, auth callbacks and the User MCP issuer. Falls back to NEXT_PUBLIC_VERCEL_URL when unsethttp://localhost:3000 locally; your production domain in deployment

Email

VariableRequiredExposurePurposeWhere to get it
ADMIN_EMAILYesServerSender and admin notification address for app emailsYour own address; use a verified Resend sender in production
RESEND_API_KEYProductionServerResend client for app emails when USE_LOCAL_EMAIL is not trueResend dashboard
USE_LOCAL_EMAILLocalServerWhen true, app emails go to the Mailpit API instead of ResendSet true locally, remove or set false in production
MAILPIT_URLLocal, commented outServerMailpit base URL for src/utils/send-email-mailpit.ts and the Playwright mail helper. Defaults to http://localhost:54324 when unsetenv.MAILPIT_URL from supabase status --output-format json

Supabase Auth emails (verification, magic link, recovery) are not sent by the web app. Configure SMTP in the Supabase project; see emails.

Analytics, API keys, AI and error tracking (optional)

VariableRequiredExposurePurposeWhere to get it
NEXT_PUBLIC_POSTHOG_API_KEYOptionalPublicPostHog browser and server clientsPostHog project settings
NEXT_PUBLIC_POSTHOG_APP_IDOptionalPublicListed in the example and typed in environment.d.ts; not read by the app sourcePostHog
NEXT_PUBLIC_POSTHOG_HOSTOptionalPublicPostHog ingestion hostPostHog project settings
NEXT_PUBLIC_GA_IDOptionalPublicGoogle Analytics measurement IDGoogle Analytics
UNKEY_ROOT_KEYOptionalServerIssue and verify API keys from /user/settings/developerUnkey dashboard
UNKEY_API_IDOptionalServerThe Unkey API that keys belong toUnkey dashboard
OPENAI_API_KEYOptionalServerAI chat route (/api/chat) and DALL-E image generationOpenAI dashboard
NEXT_PUBLIC_SENTRY_DSNOptionalPublicRead by sentry.client.config.ts, sentry.server.config.ts and sentry.edge.config.ts. Sentry stays off until you uncomment withSentryConfig in next.config.tsSentry project settings

Supabase social providers (optional)

VariableRequiredExposurePurposeWhere to get it
TWITTER_API_KEY, TWITTER_API_SECRETOptionalServerRead by config.toml via env(...) for [auth.external.twitter]Twitter developer portal
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRETOptionalServer[auth.external.google] in config.tomlGoogle Cloud console
GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRETOptionalServer[auth.external.github] in config.tomlGitHub OAuth apps

These are consumed by the Supabase CLI when it starts the local project, not by Next.js. For a hosted project, enter them in the Supabase Auth providers settings instead. See authentication.

Observability and revalidation (optional)

VariableRequiredExposurePurposeWhere to get it
OTEL_ENABLEDOptionalServerTurns on @vercel/otel tracing in instrumentation.tstrue or unset
OTEL_SERVICE_NAMEOptionalServerService name reported in tracesAny name; example uses nextbase-ultimate-web
OTEL_EXPORTER_OTLP_ENDPOINTOptionalServerOTLP collector endpoint. Standard OpenTelemetry variable, not read directly by app codeYour collector
OTEL_EXPORTER_OTLP_HEADERSOptionalServerOTLP exporter headers. Standard OpenTelemetry variableYour collector
LOG_LEVELOptionalServerpino log level for src/utils/logger.ts and src/lib/logger.tsinfo, debug, and so on
REVALIDATE_SECRETWith the admin appServerExpected x-revalidate-secret header for POST /api/revalidate, and the Bearer token the admin app sends to POST /api/internal/admin-revalidate after publishing content. Must match the admin app's valueGenerate a random string and set it on both apps

apps/admin/.env.local

The admin example repeats the Supabase, Stripe, email, analytics, provider, OTEL, LOG_LEVEL and REVALIDATE_SECRET lines above (without SUPABASE_POSTGRES_DB_URL, SUPABASE_JWT_SIGNING_KEY, MAILPIT_URL, OPENAI_API_KEY and NEXT_PUBLIC_SENTRY_DSN). Supabase values must be the same project as the web app. The admin app's source reads these:

VariableRequiredExposurePurposeWhere to get it
NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY, SUPABASE_SECRET_KEYYesPublic, Public, ServerSame meaning as in the web app; the secret key powers the service-role queries in src/data/admin/ and the Admin MCPpnpm supabase:sync-env locally; the dashboard in production
NEXT_PUBLIC_SITE_URLYesPublicThe admin app's own origin: auth callbacks and the Admin MCP issuer. Falls back to NEXT_PUBLIC_VERCEL_URLhttp://localhost:3002 locally; the admin domain in production
NEXT_PUBLIC_WEB_APP_URLYesPublicThe web app's origin. Used for the "Open web app" link, support sign-in and impersonation links (which land on the web app's /auth/confirm) and the cache invalidation call. Must be a bare HTTP(S) originhttp://localhost:3000 locally; the product domain in production
REVALIDATE_SECRETYes for publishingServerSent as a Bearer token to the web app's /api/internal/admin-revalidate so published blog, changelog and feedback changes appear on the web appSame value as the web app
ADMIN_EMAIL, RESEND_API_KEY, USE_LOCAL_EMAILFor admin emailsServerEmails sent from admin actions through src/utils/api-routes/utils.ts. The admin copy of send-email-mailpit.ts posts to http://localhost:54324 and does not read MAILPIT_URLAs for the web app
STRIPE_SECRET_KEY, NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY, STRIPE_WEBHOOK_SECRETFor the payment gateway pagesServer, Public, ServerPayment gateway controls under /app-admin/payment-gatewayStripe dashboard

SUPABASE_DATABASE_PASSWORD, the PostHog, GA and Unkey variables, the social provider credentials, the OTEL variables and LOG_LEVEL are present in the admin example but not read by the admin app's source.

Referenced in code but not in the example files

VariableExposurePurposeNotes
NEXT_PUBLIC_APP_NAMEPublicFallback service name in apps/web/instrumentation.tsOptional
NEXT_PUBLIC_VERCEL_URLPublicFallback origin when NEXT_PUBLIC_SITE_URL is unset, in both appsSet by Vercel automatically
PORTServerPort for the web app's pnpm start and the Playwright baseURLDefaults to 3000
WEB_BASE_URL, ADMIN_BASE_URLTest onlyPoint Playwright at already running web and admin servers instead of starting themDefault to http://localhost:3000 and http://localhost:3002
MCP_TEST_SUPABASE_URL, MCP_TEST_SUPABASE_SERVICE_KEY, MCP_TEST_SUPABASE_ANON_KEYTest onlyEnable apps/web/src/mcp/supabase-store.integration.test.ts against a local databaseLoopback hosts only

Production checklist

Web app: NEXT_PUBLIC_SITE_URL, NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY, SUPABASE_SECRET_KEY, ADMIN_EMAIL, RESEND_API_KEY and REVALIDATE_SECRET. Add the three Stripe variables if you keep billing. Do not set USE_LOCAL_EMAIL=true in production.

Admin app: the three Supabase variables, NEXT_PUBLIC_SITE_URL (admin origin), NEXT_PUBLIC_WEB_APP_URL (web origin) and the same REVALIDATE_SECRET. Add Stripe and email variables if you use those controls. The deployment page has the full flow.

Installation

Clone the Next.js + Supabase starter, start a local Supabase project, run the web and admin apps and sign in for the first time.

Authentication

How Supabase Auth, email verification, social providers, the admin role, the separate admin app and RLS work in the Next.js + Supabase starter.

On this page

apps/web/.env.localSupabaseStripeHostEmailAnalytics, API keys, AI and error tracking (optional)Supabase social providers (optional)Observability and revalidation (optional)apps/admin/.env.localReferenced in code but not in the example filesProduction checklist