You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(*): optimize satellite handshakes and introduce satelliteAutoSync prop
Satellite domains previously always triggered a handshake redirect to the primary
domain on first visit, even when users weren't authenticated. This caused unnecessary
latency and poor UX for apps where most visitors are anonymous.
Changes:
- Add `satelliteAutoSync` option (defaults to false)
- When false, satellites skip handshake if no cookies exist and no sync trigger
- Use `__clerk_synced` query param: 'false' triggers sync, 'true' marks completion
- Server-side redirects include sync param for post-sign-in handshake trigger
- Client-side adds sync param to forceRedirectUrl and fallbackRedirectUrl
- TanStack Start middleware supports callback function for dynamic options
Packages affected:
- @clerk/backend: authenticateRequest logic and redirect handling
- @clerk/clerk-js: CSR support and redirect URL modification
- @clerk/shared: sync constants and option types
- @clerk/nextjs, @clerk/astro, @clerk/tanstack-react-start: option passthrough
Add `satelliteAutoSync` option to optimize satellite app handshake behavior
11
+
12
+
Satellite apps currently trigger a handshake redirect on every first page load, even when no cookies exist. This creates unnecessary redirects to the primary domain for apps where most users aren't authenticated.
- When `false` (default): Skip automatic handshake if no session cookies exist, only trigger after explicit sign-in action
16
+
- When `true`: Satellite apps automatically trigger handshake on first load (previous behavior)
17
+
18
+
**New query parameter: `__clerk_sync`**
19
+
-`__clerk_sync=1` (NeedsSync): Triggers handshake after returning from primary sign-in
20
+
-`__clerk_sync=2` (Completed): Prevents re-sync loop after handshake completes
21
+
22
+
Backwards compatible: Still reads legacy `__clerk_synced=true` parameter.
23
+
24
+
**SSR redirect fix**: Server-side redirects (e.g., `redirectToSignIn()` from middleware) now correctly add `__clerk_sync=1` to the return URL for satellite apps. This ensures the handshake is triggered when the user returns from sign-in on the primary domain.
25
+
26
+
**CSR redirect fix**: Client-side redirects now add `__clerk_sync=1` to all redirect URL variants (`forceRedirectUrl`, `fallbackRedirectUrl`) for satellite apps, not just the default `redirectUrl`.
### Behavior change: `satelliteAutoSync` defaults to `false`
86
+
87
+
Previously, satellite apps would automatically trigger a handshake redirect on every first page load to sync authentication state with the primary domain—even when no session cookies existed. This caused unnecessary redirects to the primary domain for users who weren't authenticated.
88
+
89
+
The new default (`satelliteAutoSync: false`) provides a better experience for end users. Performance-wise, the satellite app can be shown immediately without attempting to sync state first, which is the right behavior for most use cases.
90
+
91
+
**To preserve the previous behavior** where visiting a satellite while already signed in on the primary domain automatically syncs your session, set `satelliteAutoSync: true`:
92
+
93
+
```typescript
94
+
exportdefaultclerkMiddleware({
95
+
isSatellite: true,
96
+
domain: 'satellite.example.com',
97
+
signInUrl: 'https://primary.example.com/sign-in',
98
+
satelliteAutoSync: true, // Opt-in to automatic sync on first load
99
+
});
100
+
```
101
+
102
+
### TanStack Start: Function props to options callback
103
+
104
+
The `clerkMiddleware` function no longer accepts individual props as functions. If you were using the function form for props like `domain`, `proxyUrl`, or `isSatellite`, migrate to the options callback pattern.
105
+
106
+
**Before (prop function form - no longer supported):**
The callback receives a context object with the `url` property (a `URL` instance) and can return options synchronously or as a Promise for async configuration.
0 commit comments