Getting Started

Configuration

Edit page
Configure URLs, registration, authentication providers, email delivery, and administrator access.

Customer Portal reads its deployment configuration from environment variables. Start from .env.example and keep secrets out of version control. This page explains the main choices; use the configuration reference for every variable, default, precedence rule, and production check.

Required settings

VariablePurpose
DATABASE_URLPostgreSQL connection string used by Drizzle
PUBLIC_URLPublic application URL used in links and redirects
BETTER_AUTH_URLBase URL used by Better Auth on the server and client
BETTER_AUTH_SECRETHigh-entropy secret used to protect Better Auth state

Use HTTPS URLs for PUBLIC_URL and BETTER_AUTH_URL in production.

Generate BETTER_AUTH_SECRET independently for each environment with openssl rand -base64 32. Do not put it in client runtime configuration, reuse a documentation value, or rotate it without a tested session-migration plan.

Registration policy

Set PORTAL_REGISTRATION_MODE to one of:

  • open — visitors may create accounts.
  • invitation-only — registration requires an organization invitation.
  • disabled — public registration is unavailable.

PORTAL_TERMS_URL controls the Terms of Service link shown by the authentication forms.

System administrators

ADMIN_EMAILS is a comma-separated list of accounts that receive the system administrator role. Organization roles are separate: an organization can have owners, administrators, and members without granting system-wide access.

.env
ADMIN_EMAILS=owner@example.com,maintainer@example.com

Social authentication

GitHub and Google sign-in are optional. Enable only providers for which credentials are configured:

.env
PORTAL_GITHUB_ENABLED=true
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=

PORTAL_GOOGLE_ENABLED=true
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=

Register the production and local callback URLs in the provider dashboard. If a provider is not needed, set its PORTAL_*_ENABLED flag to false.

Email delivery

Platform authentication messages use the platform Resend credentials:

.env
RESEND_API_KEY=
RESEND_FROM_EMAIL=

Feature-specific transactional email can have different ownership. For example, invoice delivery credentials are configured per organization by the timesheets feature.

Feature configuration

Official and local layers are declared explicitly in portal.config.ts. definePortalConfig() converts them into the ordered nuxtLayers consumed by Nuxt extends; localPortalLayer() also records database-provider metadata.

Disabling a layer removes its routes and registrations, but it does not delete its database schema or stored data. See Nuxt layers.