Clerk Satellite Domain Setup & URL Parameter Management

Overview

The dodev app is configured as a Clerk satellite domain, which means it delegates authentication to a primary auth domain (currently localhost:3000 in development). This architecture requires synchronization between domains, which Clerk handles through URL parameters.

Why Satellite Domains?

Satellite domains are useful when you want:

  • Centralized authentication across multiple apps
  • Single sign-on (SSO) across subdomains
  • Consistent user sessions across different services

The URL Parameter Issue

When using satellite domains, Clerk adds synchronization parameters to URLs:

  • __clerk_synced - Indicates sync status
  • __clerk_db_jwt - Contains encrypted session data
  • __clerk_hs_reason - Sync reason (e.g., "primary-responds-to-syncing")

These parameters are necessary for the authentication handshake but can be visually unappealing.

Solutions Implemented

1. Client-Side URL Cleaning

We've added a ClerkUrlCleaner component that automatically removes these parameters from the browser's address bar after the sync is complete. This provides a cleaner user experience while maintaining functionality.

2. Middleware Handling

The middleware allows these parameters to pass through without interference, as they're required for proper authentication.

Alternative Approaches

Instead of using satellite domains, each app can handle its own authentication:

# Remove satellite configuration
# NEXT_PUBLIC_CLERK_IS_SATELLITE=true
# NEXT_PUBLIC_CLERK_DOMAIN=auth.do.dev

# Use local authentication
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up

Option 2: Server-Side Redirect

Implement a server-side redirect that processes the sync parameters and redirects to a clean URL:

// In middleware.ts
if (hasClerkParams) {
  // Process sync
  const response = NextResponse.next()
  
  // Set a cookie to indicate sync is complete
  response.cookies.set('clerk-synced', 'true', {
    httpOnly: true,
    secure: true,
    sameSite: 'lax'
  })
  
  // Redirect to clean URL after processing
  return NextResponse.redirect(cleanUrl)
}

Option 3: Custom Auth Flow

Implement a custom authentication flow that handles the sync server-side:

  1. User clicks login on do.dev
  2. Redirect to auth.do.dev with a callback URL
  3. After auth, redirect back with a one-time token
  4. Exchange token for session server-side
  5. Set session cookies without URL parameters

Production Recommendations

For production deployment on do.dev:

  1. Use Custom Domain: Configure Clerk with your actual domain (do.dev) instead of localhost
  2. Consider Standalone Auth: Each subdomain handles its own auth to avoid sync parameters
  3. Use Secure Cookies: Ensure all auth cookies are httpOnly, secure, and use proper sameSite settings
  4. Implement Token Exchange: Use server-side token exchange instead of client-side sync

Configuration for Production

# Production configuration for do.dev
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_your_key
CLERK_SECRET_KEY=sk_live_your_secret

# If using satellite mode
NEXT_PUBLIC_CLERK_DOMAIN=auth.do.dev
NEXT_PUBLIC_CLERK_IS_SATELLITE=true
NEXT_PUBLIC_CLERK_SIGN_IN_URL=https://auth.do.dev/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=https://auth.do.dev/sign-up

# If using standalone mode (recommended)
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up

Conclusion

While the URL parameters are a necessary part of Clerk's satellite domain functionality, we've implemented client-side cleaning to improve the user experience. For production, consider whether satellite domains are necessary for your use case, as standalone authentication can provide a cleaner implementation without sync parameters.

On this page