Dynamic Site URL Configuration for Convex Auth
This guide explains how to configure dynamic site URLs for Convex Auth across different development and deployment environments.
Problem
When using different dev servers or deployment environments, the SITE_URL needs to change dynamically to match the current environment. This affects:
- OAuth redirect URLs
- Magic link destinations
- Email verification links
Solutions
1. Environment-Based Configuration (Recommended)
Set different SITE_URL values for each Convex deployment:
# Development
npx convex env set SITE_URL http://localhost:3000
# Preview/Staging (for branch deployments)
npx convex deploy --preview
npx convex env set SITE_URL https://preview-branch-name.yourdomain.com
# Production
npx convex env set SITE_URL https://yourdomain.com --prod2. Multiple Local Development Ports
If you need to support multiple local development ports:
// In convex/auth.ts
callbacks: {
async redirect({ redirectTo }) {
const localPorts = ['3000', '3001', '3002', '5173'];
const allowedOrigins = [
process.env.SITE_URL,
...localPorts.map(port => `http://localhost:${port}`),
].filter(Boolean);
// Handle relative redirects
if (redirectTo.startsWith('/')) {
return `${process.env.SITE_URL}${redirectTo}`;
}
// Validate absolute URLs
const isAllowed = allowedOrigins.some(origin =>
redirectTo.startsWith(origin)
);
if (!isAllowed) {
throw new Error(`Invalid redirectTo URL: ${redirectTo}`);
}
return redirectTo;
}
}3. Branch-Based Deployments
Use Convex preview deployments for each Git branch:
# Create a preview deployment for current branch
npx convex deploy --preview
# The deployment URL will be something like:
# https://careful-elephant-123.convex.cloud
# Set the SITE_URL for this preview
npx convex env set SITE_URL https://your-branch.preview.yourdomain.com4. OAuth Provider Configuration
When using OAuth providers, you'll need to update the redirect URLs in each provider's settings:
GitHub OAuth
Add these redirect URLs to your GitHub OAuth app:
http://localhost:3000/api/auth/callback/githubhttps://dev.yourdomain.com/api/auth/callback/githubhttps://staging.yourdomain.com/api/auth/callback/githubhttps://yourdomain.com/api/auth/callback/github
Google OAuth
Add authorized redirect URIs in Google Cloud Console:
http://localhost:3000/api/auth/callback/googlehttps://dev.yourdomain.com/api/auth/callback/google- etc.
5. Email Provider Configuration
For email providers like Resend, the SITE_URL is used to generate verification links. The ResendOTP provider will automatically use the configured SITE_URL.
6. Client-Side Configuration
Ensure your client-side code uses the correct Convex deployment URL:
// In your client provider
const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL);Set different values in your .env files:
# .env.development
NEXT_PUBLIC_CONVEX_URL=https://dev-deployment.convex.cloud
# .env.production
NEXT_PUBLIC_CONVEX_URL=https://prod-deployment.convex.cloudBest Practices
- Use separate Convex deployments for dev, staging, and production
- Document all environment variables required for each environment
- Automate deployment with CI/CD to ensure correct environment variables
- Test OAuth flows in each environment after configuration
- Use preview deployments for pull request testing
Example Deployment Workflow
# 1. Development
npm run dev
# Uses SITE_URL=http://localhost:3000
# 2. Preview (for PR)
git checkout -b feature/new-feature
npx convex deploy --preview
npx convex env set SITE_URL https://pr-123.preview.yourdomain.com
# 3. Staging
git checkout staging
npx convex deploy --deployment staging
npx convex env set SITE_URL https://staging.yourdomain.com --deployment staging
# 4. Production
git checkout main
npx convex deploy --prod
# SITE_URL already set to https://yourdomain.comTroubleshooting
- OAuth redirect mismatch: Ensure the OAuth provider has all possible redirect URLs configured
- Email links not working: Check that
SITE_URLis set correctly for the deployment - Wrong redirect after login: Verify the
redirectcallback is handling all your domains
Security Considerations
- Always validate redirect URLs in the
redirectcallback - Use HTTPS in production for all site URLs
- Limit allowed domains to only those you control
- Don't expose internal URLs in production builds