Hi Netlify team! Rob from Clerk here. I’m just curious if there’s a recommended way of fixing our issue here.
Description
We’re encountering redirect loops with Clerk’s authentication handshake mechanism with Netlify’s caching, specifically in server-rendered applications. Here’s the sequence that causes the issue:
- User lands on the app (e.g., https://some-app.netlify.app/)
- Server immediately returns a 307 redirect to FAPI to start the handshake flow and determine auth state
- FAPI verifies auth state, issues new session token, and redirects back to original URL
- Instead of getting fresh auth check, Netlify serves the cached response from step 2
- This creates an infinite loop as the cached response contains the same handshake redirect logic
Current Workaround
We implemented a temporary solution in our Astro middleware that specifically targets Netlify environments:
function handleNetlifyCacheInDevInstance(locationHeader: string, requestState: RequestState) {
// Only run on Netlify environment and Clerk development instance
if (import.meta.env.NETLIFY && isDevelopmentFromPublishableKey(requestState.publishableKey)) {
const hasHandshakeQueryParam = locationHeader.includes('__clerk_handshake');
// If location header is the original URL before the handshake redirects, add cache bust param
if (!hasHandshakeQueryParam) {
const url = new URL(locationHeader);
url.searchParams.append(NETLIFY_CACHE_BUST_PARAM, Date.now().toString());
requestState.headers.set('Location', url.toString());
}
}
}
This solution:
- Adds a timestamp-based cache bust parameter to the initial redirect
- Only applies to Netlify environments
- Prevents the cache hit while maintaining Netlify’s caching benefits for other routes
We want to add this fix to more of our SDKs (tanstack-start, nuxt, etc.). For some reason, this issue doesn’t seem to appear in Next and OpenNext.
Questions/Recommendations:
- Is there a more standardized way to handle auth redirect flows with your caching system?
- Could there be a header or directive that marks certain responses as “auth-sensitive” to prevent caching?
Thank you very much for your time!