Clerk Satellite Domains & Redirect Origins Configuration
Overview
This document explains how to configure Clerk authentication to work across multiple domains and Vercel preview deployments by properly setting up allowedRedirectOrigins. This prevents the common error:
"redirect_url does not match one of the allowed values for parameter redirect_url"Problem
When deploying to Vercel, each preview deployment gets a unique URL (e.g., https://doc-cp8rl0prp-dodev.vercel.app/). Clerk's security model requires these URLs to be explicitly allowed in the allowedRedirectOrigins configuration. Without this, authentication flows fail with redirect URL errors.
Solution
Configure the ClerkProvider with a comprehensive list of allowed redirect origins that automatically includes:
- Development environments
- Production domains
- Vercel system URLs (preview and production)
- Custom satellite domains
Implementation
1. Update ClerkProvider Configuration
Add the following configuration to your root layout file (app/layout.tsx) with satellite domain support:
import { ClerkProvider } from "@clerk/nextjs"
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
// Build allowed redirect origins for satellite domains and Vercel previews
// Note: To access VERCEL_* environment variables, enable "Automatically expose System Environment Variables"
// in your Vercel project settings under Environment Variables
const allowedRedirectOrigins = [
// Development environments
'http://localhost:3000',
'http://localhost:3001',
'http://localhost:3002',
'http://localhost:3016',
'http://localhost:3026',
// Production domains
'https://doc.dev',
'https://www.doc.dev',
// Vercel system environment variables (available when "Automatically expose System Environment Variables" is enabled)
process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : null,
process.env.VERCEL_BRANCH_URL ? `https://${process.env.VERCEL_BRANCH_URL}` : null,
process.env.VERCEL_PROJECT_PRODUCTION_URL ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}` : null,
// Additional Vercel URLs for Next.js (these may also be available)
process.env.NEXT_PUBLIC_VERCEL_URL ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` : null,
process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL ? `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}` : null,
// Custom satellite domains from environment
process.env.NEXT_PUBLIC_CLERK_SATELLITE_DOMAIN_1,
process.env.NEXT_PUBLIC_CLERK_SATELLITE_DOMAIN_2,
process.env.NEXT_PUBLIC_CLERK_SATELLITE_DOMAIN_3,
].filter((url): url is string => Boolean(url))
// Debug output in development
if (process.env.NODE_ENV === 'development') {
console.log('Clerk allowedRedirectOrigins:', allowedRedirectOrigins)
}
return (
<ClerkProvider allowedRedirectOrigins={allowedRedirectOrigins}>
<html lang="en">
<body>
{children}
</body>
</html>
</ClerkProvider>
)
}2. Configure Environment Variables
For satellite domain configuration (when your app is a satellite of another domain):
# Satellite Domain Configuration (Production)
# Enable satellite mode - set to 'true' for satellites, omit for primary domains
NEXT_PUBLIC_CLERK_IS_SATELLITE=true
# The domain of this satellite (usually auto-detected in production)
NEXT_PUBLIC_CLERK_DOMAIN=doc.dev
# Primary domain sign-in/sign-up URLs (where authentication happens)
NEXT_PUBLIC_CLERK_SIGN_IN_URL=https://do.dev/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=https://do.dev/sign-up
# Optional: Custom satellite domains for allowedRedirectOrigins
NEXT_PUBLIC_CLERK_SATELLITE_DOMAIN_1=https://satellite1.example.com
NEXT_PUBLIC_CLERK_SATELLITE_DOMAIN_2=https://satellite2.example.com
NEXT_PUBLIC_CLERK_SATELLITE_DOMAIN_3=https://satellite3.example.com
# Note: Vercel environment variables (VERCEL_URL, VERCEL_BRANCH_URL, etc.)
# are automatically available in Vercel deployments when "Automatically expose
# System Environment Variables" is enabled in project settingsFor standalone configuration (when your app handles its own authentication):
# Standalone Configuration (Development or Independent Apps)
# Omit NEXT_PUBLIC_CLERK_IS_SATELLITE or set to 'false'
# Use local sign-in/sign-up pages
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up3. Enable Vercel System Environment Variables
Critical Step: To access Vercel's system environment variables (VERCEL_URL, VERCEL_BRANCH_URL, etc.):
- Go to your Vercel Project Dashboard
- Navigate to Settings → Environment Variables
- Check "Automatically expose System Environment Variables"
- Deploy your project to apply the changes
See Vercel Environment Variables Documentation for details.
Environment Variables Reference
Vercel System Variables (Auto-Available)
| Variable | Description | Example |
|---|---|---|
VERCEL_URL | Current deployment URL | my-site-abc123.vercel.app |
VERCEL_BRANCH_URL | Git branch-specific URL | my-site-git-feature.vercel.app |
VERCEL_PROJECT_PRODUCTION_URL | Production domain | my-site.com |
Custom Configuration Variables
| Variable | Description | Example |
|---|---|---|
NEXT_PUBLIC_CLERK_SATELLITE_DOMAIN_1 | First custom satellite domain | https://admin.example.com |
NEXT_PUBLIC_CLERK_SATELLITE_DOMAIN_2 | Second custom satellite domain | https://api.example.com |
NEXT_PUBLIC_CLERK_SATELLITE_DOMAIN_3 | Third custom satellite domain | https://docs.example.com |
How It Works
Automatic URL Detection
The configuration automatically detects and allows:
- Development URLs: All common localhost ports
- Vercel Deployments: Current deployment, branch-specific, and production URLs
- Production Domains: Your configured production domains
- Custom Satellites: Any additional domains you specify
URL Building Logic
// Each environment variable is checked and built into a full HTTPS URL
process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : null
// Invalid/empty values are filtered out
.filter((url): url is string => Boolean(url))Debug Information
In development mode, the configuration logs all allowed origins:
Clerk allowedRedirectOrigins: [
'http://localhost:3016',
'https://doc.dev',
'https://doc-cp8rl0prp-dodev.vercel.app',
// ... other URLs
]Satellite Domains (Multi-Domain Authentication)
When to Use Satellite Domains
Use satellite domains when you need:
- Shared authentication across different domains
- Multi-tenant applications with domain isolation
- Admin panels on separate domains
- API documentation sites with authentication
Configuration for Satellite Domains
For the satellite domain (not the primary), configure:
# Satellite domain configuration (.env.local)
NEXT_PUBLIC_CLERK_IS_SATELLITE=true
NEXT_PUBLIC_CLERK_DOMAIN=satellite.yourdomain.com
NEXT_PUBLIC_CLERK_SIGN_IN_URL=https://primary.yourdomain.com/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=https://primary.yourdomain.com/sign-upFor the primary domain, ensure it includes the satellite in allowedRedirectOrigins:
// In primary domain's layout.tsx
const allowedRedirectOrigins = [
// ... other origins
'https://satellite.yourdomain.com',
]Troubleshooting
Common Issues
1. Redirect URL Error in Production
Error: redirect_url does not match one of the allowed values
Solution:
- Ensure "Automatically expose System Environment Variables" is enabled in Vercel
- Check that
VERCEL_URLis being properly read - Add debug logging to verify URLs are being included
2. Environment Variables Not Available
Error: process.env.VERCEL_URL is undefined
Solution:
- Enable system environment variables in Vercel project settings
- Redeploy after enabling the setting
- Verify in deployment logs that variables are available
3. Localhost Development Issues
Error: Authentication fails in development
Solution:
- Ensure localhost URLs include the correct port
- Check console logs for debug information
- Verify Clerk keys are correctly configured
Debug Steps
-
Check Environment Variables:
console.log('VERCEL_URL:', process.env.VERCEL_URL) console.log('VERCEL_BRANCH_URL:', process.env.VERCEL_BRANCH_URL) console.log('NEXT_PUBLIC_VERCEL_URL:', process.env.NEXT_PUBLIC_VERCEL_URL) -
Verify Allowed Origins:
console.log('Clerk allowedRedirectOrigins:', allowedRedirectOrigins) -
Test Authentication Flow:
- Try signing in from different domains
- Check browser network tab for redirect URLs
- Verify error messages in Clerk dashboard
- Check Vercel deployment logs for debug output
-
Emergency Fix for Specific Deployments: If you get a specific failing URL like
https://doc-g23uichgg-dodev.vercel.app/, you can:a) Add it manually to the array (temporary fix):
const allowedRedirectOrigins = [ // ... other origins 'https://doc-g23uichgg-dodev.vercel.app', // Emergency fix ]b) Set it as an environment variable:
# In Vercel dashboard, add this environment variable: NEXT_PUBLIC_VERCEL_DEPLOYMENT_URL=https://doc-g23uichgg-dodev.vercel.app
Best Practices
Security Considerations
- Principle of Least Privilege: Only include necessary domains
- Environment Separation: Use different configurations for dev/staging/prod
- Regular Audits: Review and update allowed origins periodically
Configuration Management
- Use Environment Variables: Avoid hardcoding domains
- Document Dependencies: Note when Vercel system variables are required
- Version Control: Include environment variable documentation
Performance
- Filter Efficiently: Remove null/undefined values early
- Cache Results: Consider memoizing the origins array if needed
- Monitor Logs: Watch for unnecessary debug output in production
Implementation Checklist
- Add
allowedRedirectOriginsto ClerkProvider - Include all development localhost ports
- Add production domains
- Configure Vercel system environment variables
- Enable "Automatically expose System Environment Variables" in Vercel
- Add custom satellite domains if needed
- Test authentication flow in development
- Deploy and test in preview environment
- Verify production deployment works
- Monitor for redirect URL errors
Related Documentation
Template for New Projects
For quick implementation in new projects, copy this template:
// app/layout.tsx
const allowedRedirectOrigins = [
// Development
'http://localhost:3000',
'http://localhost:3001',
// Production (update with your domains)
'https://yourdomain.com',
'https://www.yourdomain.com',
// Vercel (auto-configured)
process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : null,
process.env.VERCEL_BRANCH_URL ? `https://${process.env.VERCEL_BRANCH_URL}` : null,
process.env.VERCEL_PROJECT_PRODUCTION_URL ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}` : null,
].filter(Boolean)
return (
<ClerkProvider allowedRedirectOrigins={allowedRedirectOrigins}>
{/* Your app */}
</ClerkProvider>
)Remember to enable "Automatically expose System Environment Variables" in your Vercel project settings!