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
Option 1: Standalone Authentication (Recommended for Production)
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-upOption 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:
- User clicks login on do.dev
- Redirect to auth.do.dev with a callback URL
- After auth, redirect back with a one-time token
- Exchange token for session server-side
- Set session cookies without URL parameters
Production Recommendations
For production deployment on do.dev:
- Use Custom Domain: Configure Clerk with your actual domain (do.dev) instead of localhost
- Consider Standalone Auth: Each subdomain handles its own auth to avoid sync parameters
- Use Secure Cookies: Ensure all auth cookies are httpOnly, secure, and use proper sameSite settings
- 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-upConclusion
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.