Skip to content

feat(clerk-js): Include current search params in handleRedirectCallback#7600

Open
jfoshee wants to merge 5 commits intorelease/core-2from
jfoshee/user-4308-oauth-redirect-fails-for-new-users-custom-sso
Open

feat(clerk-js): Include current search params in handleRedirectCallback#7600
jfoshee wants to merge 5 commits intorelease/core-2from
jfoshee/user-4308-oauth-redirect-fails-for-new-users-custom-sso

Conversation

@jfoshee
Copy link
Contributor

@jfoshee jfoshee commented Jan 14, 2026

so that component AuthenticateWithRedirectCallback automatically incorporates any redirects in the current query to match the documented usage

Part of USER-4308

Without a fix like this the developer must manually snag and specify all the possible redirects, which I think is not the intent of the component.

const redirectUrl = searchParams.get('redirect_url') ?? undefined
const signInFallbackRedirectUrl = searchParams.get('sign_in_fallback_redirect_url') ?? undefined
const signInForceRedirectUrl = searchParams.get('sign_in_force_redirect_url') ?? undefined
const signUpFallbackRedirectUrl = searchParams.get('sign_up_fallback_redirect_url') ?? undefined
const signUpForceRedirectUrl = searchParams.get('sign_up_force_redirect_url') ?? undefined
       <AuthenticateWithRedirectCallback
              continueSignUpUrl={buildContinueSignUpUrl()}
              redirectUrl={redirectUrl}
              signInFallbackRedirectUrl={signInFallbackRedirectUrl}
              signInForceRedirectUrl={signInForceRedirectUrl}
              signUpFallbackRedirectUrl={signUpFallbackRedirectUrl}
              signUpForceRedirectUrl={signUpForceRedirectUrl}
            />

Note to Reviewers

❓ Is this the best place to insert the URL's query params? It could be done at a higher level, e.g. adding an argument to handleRedirectCallback. Are there scenarios where it is undesirable to automatically use the window's current query?

❓ What are some scenarios I should manually test?

It would be helpful to consider this change in conjunction with this docs change. I acknowledge that the change to the docs is not ideal; it makes the code example much longer. But, my thinking is to first: make it correct, second: make SDK improvements that could reduce the burden on customers.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

…ack`

so that component `AuthenticateWithRedirectCallback` automatically incorporates any redirects in the current query
to match the documented usage
https://clerk.com/docs/guides/development/custom-flows/authentication/oauth-connections
@changeset-bot
Copy link

changeset-bot bot commented Jan 14, 2026

🦋 Changeset detected

Latest commit: 8e7497a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@clerk/clerk-js Patch
@clerk/chrome-extension Patch
@clerk/clerk-expo Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Jan 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Feb 18, 2026 6:23pm

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 14, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jfoshee/user-4308-oauth-redirect-fails-for-new-users-custom-sso

Comment @coderabbitai help to get the list of available commands and usage tips.

@jfoshee jfoshee changed the title feat(clerk-js): include current search params in handleRedirectCallback feat(clerk-js): Include current search params in handleRedirectCallback Jan 14, 2026
@jfoshee jfoshee requested review from brkalow and dstaley January 14, 2026 19:11
@jfoshee jfoshee marked this pull request as ready for review January 14, 2026 19:11
@jfoshee jfoshee requested review from a team, BrandonRomano and nikosdouvlis January 14, 2026 19:12
@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 26, 2026

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7600

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7600

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7600

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7600

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7600

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7600

@clerk/elements

npm i https://pkg.pr.new/@clerk/elements@7600

@clerk/clerk-expo

npm i https://pkg.pr.new/@clerk/clerk-expo@7600

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7600

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7600

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7600

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7600

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7600

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7600

@clerk/clerk-react

npm i https://pkg.pr.new/@clerk/clerk-react@7600

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7600

@clerk/remix

npm i https://pkg.pr.new/@clerk/remix@7600

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7600

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7600

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7600

@clerk/themes

npm i https://pkg.pr.new/@clerk/themes@7600

@clerk/types

npm i https://pkg.pr.new/@clerk/types@7600

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7600

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7600

commit: 8e7497a

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this fix introduce a breaking change? This change is in _handleRedirectCallback which is shared by both handleRedirectCallback and handleGoogleOneTapCallback. For the OAuth redirect callback this makes total sense, that's the whole point of the fix. But for Google One Tap, the dialog fires on whatever page the user is currently browsing, not on a dedicated callback URL. Since search params have highest priority in #getRedirectUrl (search params > props > options), any redirect_url that happens to be in the page's query string would silently override the redirect params passed via props.

Should we scope this to just the handleRedirectCallback path? Something like passing the search params from the caller:

// In handleRedirectCallback - pass search params
return this._handleRedirectCallback(params, { signUp, signIn, navigate }, new URLSearchParams(window.location.search));

// In handleGoogleOneTapCallback - don't pass search params (keeps current behavior)
return this._handleRedirectCallback(params, { signUp, signIn, navigate });

Then _handleRedirectCallback would forward whatever it receives to RedirectUrls instead of reading window.location.search directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. Thanks, Nikos. I've moved search params up a level and added an optional parameter to _handleRedirectCallback. I manually tested the OAuth app + sso sign-up flow (bug scenario) and it works fine with <AuthenticateWithRedirectCallback />. I tested basic sso sign-up w/ customized sign-in page as well. Are there any other scenarios I should test?

so that it can be passed from handleRedirectCallback for AuthenticateWithRedirectCallback, whereas the parameter is omitted for Google One Tap so we don't change the behavior there
await waitFor(() => {
expect(mockSetActive).toHaveBeenCalled();
// The redirect should include the custom redirect URL from URL search params
expect(mockNavigate.mock.calls[0][0]).toContain(customRedirectUrl);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth adding a test where both props and search params are present? Just to lock the precedence behavior (search params > props) and prevent future regressions

signUp: SignUpResource;
navigate: (to: string) => Promise<unknown>;
},
searchParams?: URLSearchParams,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a quick test verifying that handleGoogleOneTapCallback ignores redirect_url from the URL? Would help protect the intentional scoping here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments