.env.local file is included in the repository and pre-configured for local development.
The
.env.local file is already set up for local development. You typically don’t need to modify these values unless you’re setting up integrations or testing specific features.Core Configuration
Database
| Variable | Value | Description |
|---|---|---|
DATABASE_URL | PostgreSQL connection string | Connection to Neon database (DEV branch for local) |
- Uses the DEV branch of the Neon database
- Safe to experiment without affecting production data
- Automatically configured in
.env.local
Authentication
| Variable | Value | Description |
|---|---|---|
BETTER_AUTH_SECRET | Random 32+ char string | Secret for encrypting sessions |
BETTER_AUTH_URL | http://localhost:3000 | Base URL for auth server |
NEXT_PUBLIC_BETTER_AUTH_URL | http://localhost:3000 | Public-facing auth URL (client-side) |
NEXT_PUBLIC_APP_URL | http://localhost:3000 | Main app URL |
NEXT_PUBLIC_CLIENT_PORTAL_URL | http://clients.localhost:3000 | Client portal URL |
Google OAuth
| Variable | Description |
|---|---|
GOOGLE_CLIENT_ID | OAuth client ID from Google Cloud Console |
GOOGLE_CLIENT_SECRET | OAuth client secret |
- Go to Google Cloud Console
- Select the CharleOS project
- Find the OAuth 2.0 Client ID credentials
Only @charle.co.uk email addresses are allowed to sign in.
Integrations
Cloudflare R2 (File Storage)
| Variable | Description |
|---|---|
CLOUDFLARE_WORKER_URL | URL of the R2 API worker (https://r2-api.charle.agency) |
R2_UPLOAD_SECRET | Shared secret for worker authentication |
CLOUDFLARE_R2_PUBLIC_URL | Public URL for accessing uploaded files (https://files.charle.agency) |
- Stores file attachments (task attachments, ticket files, etc.)
- Accessed via a Cloudflare Worker for security
- Files are served from
files.charle.agency
Pusher (Real-time & Notifications)
CharleOS uses Pusher for two purposes:Pusher Channels (Real-time updates)
| Variable | Description |
|---|---|
NEXT_PUBLIC_PUSHER_KEY | Public API key (client-side) |
NEXT_PUBLIC_PUSHER_CLUSTER | Server cluster (eu) |
PUSHER_APP_ID | Application ID (server-side) |
PUSHER_SECRET | Secret key (server-side) |
- Real-time updates to task status
- Live notifications in the UI
- Multi-user collaboration features
Pusher Beams (Push notifications)
| Variable | Description |
|---|---|
NEXT_PUBLIC_PUSHER_BEAMS_INSTANCE_ID | Beams instance identifier |
PUSHER_BEAMS_SECRET_KEY | Secret for sending push notifications |
- Browser push notifications
- Desktop notifications for tasks and mentions
Resend (Email)
| Variable | Description |
|---|---|
RESEND_API_KEY | API key for sending emails |
- Sending email notifications
- Quote approval emails to clients
- Task assignment notifications
- System alerts
- Go to Resend Dashboard
- Create an API key for the CharleOS project
Algolia (Search)
| Variable | Description |
|---|---|
ALGOLIA_APP_ID | Algolia application ID |
ALGOLIA_ADMIN_API_KEY | Admin API key (for indexing) |
ALGOLIA_SEARCH_API_KEY | Search-only API key (public, read-only) |
ALGOLIA_INDEX_NAME | Index name (search_entities_dev for local) |
- Global search across clients, tasks, quotes, projects
- Instant search results as you type
- Indexed data includes: clients, tasks, quotes, projects, tickets
- Local/Dev:
search_entities_dev - Production:
search_entities_prod
HubSpot (CRM Integration)
| Variable | Description |
|---|---|
HUBSPOT_ACCESS_TOKEN | Private app access token |
- Syncing client data with HubSpot CRM
- Creating deals and contacts
- Tracking client interactions
OpenAI (AI Features)
| Variable | Description |
|---|---|
OPENAI_API_KEY | OpenAI API key for AI features |
- Alan (AI assistant) for scheduling and task management
- Smart suggestions for task sizing
- Natural language processing for search
Slack (Notifications)
| Variable | Description |
|---|---|
SLACK_BOT_TOKEN | Bot user OAuth token (xoxb-...) |
SLACK_SIGNING_SECRET | Signing secret for verifying requests |
SLACK_APP_TOKEN | App-level token (xapp-...) |
SLACK_APP_ID | Slack app identifier |
- Sending notifications to Slack channels
- Task updates in Slack
- Quote approvals and mentions
- Integration with team communication
- Go to Slack API Dashboard
- Select the CharleOS app
- Find credentials in “OAuth & Permissions” and “Basic Information”
Sentry (Error Tracking)
| Variable | Description |
|---|---|
SENTRY_AUTH_TOKEN | Auth token for uploading source maps |
- Error tracking and monitoring
- Performance monitoring
- Release tracking with source maps
- Go to Sentry Settings
- Create a token with
project:releasesandorg:readscopes
Environment-Specific Values
Local Development (.env.local)
| Variable | Local Value |
|---|---|
DATABASE_URL | DEV database branch |
BETTER_AUTH_URL | http://localhost:3000 |
NEXT_PUBLIC_BETTER_AUTH_URL | http://localhost:3000 |
NEXT_PUBLIC_CLIENT_PORTAL_URL | http://clients.localhost:3000 |
ALGOLIA_INDEX_NAME | search_entities_dev |
Production (.env.production)
| Variable | Production Value |
|---|---|
DATABASE_URL | Production database (via Vercel) |
BETTER_AUTH_URL | https://charle.agency |
NEXT_PUBLIC_BETTER_AUTH_URL | https://charle.agency |
NEXT_PUBLIC_CLIENT_PORTAL_URL | https://clients.charle.agency |
ALGOLIA_INDEX_NAME | search_entities_prod |
Required vs Optional Variables
Required for Core Functionality
These are required for the app to run:DATABASE_URL- Database connectionBETTER_AUTH_SECRET- Auth encryptionBETTER_AUTH_URLand public variants - Auth configurationGOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRET- OAuth sign-in
Optional (Feature-Specific)
These are optional and only needed for specific features:- Pusher - Real-time updates (app works without, but no live updates)
- Resend - Email notifications (app works without, but no emails sent)
- Algolia - Search (app works without, but search will be slower/limited)
- HubSpot - CRM integration (purely optional)
- OpenAI - AI features (Alan won’t work without this)
- Slack - Slack notifications (purely optional)
- Sentry - Error tracking (purely optional, for monitoring)
- Cloudflare R2 - File uploads (attachments won’t work without this)
Managing Environment Variables
Local Development
The.env.local file is already configured and checked into the repository. You don’t need to create or modify it unless:
- You’re testing a specific integration
- You need to use a different database branch
- You’re debugging auth issues
Adding New Variables
If you add new environment variables to the codebase:- Add to
.env.localwith a dev/test value - Add to
.env.examplewith a placeholder - Document here in this page
- Add to Vercel for production (via Vercel Dashboard)
Security Best Practices
Never Commit Secrets
Never Commit Secrets
.env.localis in the repo but only has dev/test credentials- Never commit production API keys or secrets
- Production secrets are managed via Vercel environment variables
Use Environment-Specific Values
Use Environment-Specific Values
- Development values in
.env.local - Production values in Vercel Dashboard
- Never mix environments
Rotate Compromised Secrets
Rotate Compromised Secrets
If a secret is exposed:
- Immediately rotate it in the service (Google, Pusher, etc.)
- Update Vercel environment variables
- Update
.env.localif it’s a dev credential - Redeploy if necessary
Use Public Variables Correctly
Use Public Variables Correctly
Variables prefixed with
NEXT_PUBLIC_ are exposed to the client:- Only use for public, non-sensitive data
- Examples:
NEXT_PUBLIC_PUSHER_KEY(read-only),NEXT_PUBLIC_APP_URL - Never use for API secrets or tokens
Troubleshooting
Missing Variable Errors
Error: “Missing environment variable: X” Fix:- Check if the variable exists in
.env.local - If missing, add it (check
.env.examplefor reference) - Restart the dev server:
npm run dev
Wrong Environment
Error: Auth URLs point to production / CORS errors Fix:- Verify
.env.localhasBETTER_AUTH_URL=http://localhost:3000 - Check you haven’t accidentally modified
.env.localwith production values - Restore from git if needed:
git checkout .env.local
Integration Not Working
If an integration (Pusher, Algolia, etc.) isn’t working:- Check the variable is set in
.env.local - Verify the credential is valid in the service’s dashboard
- Restart the dev server - env vars are loaded on startup
- Check service status - the external service might be down
Related Documentation
Local Setup
Step-by-step guide to setting up your local environment
Authentication
How Better Auth uses these environment variables
Deployment
Managing environment variables in production