diff --git a/.changeset/wet-donuts-tap.md b/.changeset/wet-donuts-tap.md new file mode 100644 index 00000000000..db93e40aba7 --- /dev/null +++ b/.changeset/wet-donuts-tap.md @@ -0,0 +1,5 @@ +--- +'@clerk/nextjs': patch +--- + +Append `return_url` when logging the claimUrl for on Keyless. diff --git a/packages/nextjs/src/app-router/server/ClerkProvider.tsx b/packages/nextjs/src/app-router/server/ClerkProvider.tsx index ff59c754fea..7748f06fa6a 100644 --- a/packages/nextjs/src/app-router/server/ClerkProvider.tsx +++ b/packages/nextjs/src/app-router/server/ClerkProvider.tsx @@ -24,6 +24,15 @@ const getNonceFromCSPHeader = React.cache(async function getNonceFromCSPHeader() return getScriptNonceFromHeader((await headers()).get('Content-Security-Policy') || '') || ''; }); +/** Discards errors thrown by attempted code */ +const onlyTry = (cb: () => unknown) => { + try { + cb(); + } catch (e) { + // ignore + } +}; + export async function ClerkProvider( props: Without, ) { @@ -111,12 +120,24 @@ export async function ClerkProvider( } else { const KeylessCookieSync = await import('../client/keyless-cookie-sync.js').then(mod => mod.KeylessCookieSync); + const headerStore = await headers(); + /** + * Allow developer to return to local application after claiming + */ + const host = headerStore.get('x-forwarded-host'); + const proto = headerStore.get('x-forwarded-proto'); + + const claimUrl = new URL(newOrReadKeys.claimUrl); + if (host && proto) { + onlyTry(() => claimUrl.searchParams.set('return_url', new URL(`${proto}://${host}`).href)); + } + /** * Notify developers. */ keylessLogger?.log({ cacheKey: newOrReadKeys.publishableKey, - msg: createKeylessModeMessage(newOrReadKeys), + msg: createKeylessModeMessage({ ...newOrReadKeys, claimUrl: claimUrl.href }), }); output = {clientProvider};