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 settings

For 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-up

3. Enable Vercel System Environment Variables

Critical Step: To access Vercel's system environment variables (VERCEL_URL, VERCEL_BRANCH_URL, etc.):

  1. Go to your Vercel Project Dashboard
  2. Navigate to SettingsEnvironment Variables
  3. Check "Automatically expose System Environment Variables"
  4. Deploy your project to apply the changes

See Vercel Environment Variables Documentation for details.

Environment Variables Reference

Vercel System Variables (Auto-Available)

VariableDescriptionExample
VERCEL_URLCurrent deployment URLmy-site-abc123.vercel.app
VERCEL_BRANCH_URLGit branch-specific URLmy-site-git-feature.vercel.app
VERCEL_PROJECT_PRODUCTION_URLProduction domainmy-site.com

Custom Configuration Variables

VariableDescriptionExample
NEXT_PUBLIC_CLERK_SATELLITE_DOMAIN_1First custom satellite domainhttps://admin.example.com
NEXT_PUBLIC_CLERK_SATELLITE_DOMAIN_2Second custom satellite domainhttps://api.example.com
NEXT_PUBLIC_CLERK_SATELLITE_DOMAIN_3Third custom satellite domainhttps://docs.example.com

How It Works

Automatic URL Detection

The configuration automatically detects and allows:

  1. Development URLs: All common localhost ports
  2. Vercel Deployments: Current deployment, branch-specific, and production URLs
  3. Production Domains: Your configured production domains
  4. 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-up

For 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_URL is 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

  1. 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)
  2. Verify Allowed Origins:

    console.log('Clerk allowedRedirectOrigins:', allowedRedirectOrigins)
  3. 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
  4. 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

  1. Principle of Least Privilege: Only include necessary domains
  2. Environment Separation: Use different configurations for dev/staging/prod
  3. Regular Audits: Review and update allowed origins periodically

Configuration Management

  1. Use Environment Variables: Avoid hardcoding domains
  2. Document Dependencies: Note when Vercel system variables are required
  3. Version Control: Include environment variable documentation

Performance

  1. Filter Efficiently: Remove null/undefined values early
  2. Cache Results: Consider memoizing the origins array if needed
  3. Monitor Logs: Watch for unnecessary debug output in production

Implementation Checklist

  • Add allowedRedirectOrigins to 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

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!

On this page