Skip to content

feat(magic-link): let the bundled views choose where a link lands - #143

Merged
Bccorb merged 1 commit into
mainfrom
feat/magic-link-destination-for-bundled-views
Sep 4, 2026
Merged

feat(magic-link): let the bundled views choose where a link lands#143
Bccorb merged 1 commit into
mainfrom
feat/magic-link-destination-for-bundled-views

Conversation

@Bccorb

@Bccorb Bccorb commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Closes #139

Follow-up to #138, which added redirectUri to requestMagicLink. That was
reachable only from the headless client path, so an application using
AuthRoutes still had no way to set a destination, which left the
deployment-wide one as the only option for the audience least likely to be
wiring up its own client.

The change

AuthProvider takes magicLinkRedirectUri, and useAuthClient() hands it to
the client as the default for every send. SeamlessAuthClientOptions carries
the same field, so a directly constructed client can do this too.

<AuthProvider apiHost={apiHost} magicLinkRedirectUri="https://app.example.com/auth/magic">
  <AuthRoutes />
</AuthProvider>

Why the default lives on the client

The issue flags the resend as the part to get right: Login.sendMagicLink and
MagicLinkSent.resend both call requestMagicLink() with no argument, so they
agree today, and the moment one starts sending a destination and the other does
not, a resent link lands somewhere the first one did not.

Putting the destination on the client rather than at each call site means
neither view changes in this PR. Both still send with no argument, so they
cannot disagree. The alternative considered was threading it through the router
state the two views already share, but location.state does not survive a
reload, so a refresh followed by a resend would silently fall back to the
deployment default and recreate the exact mismatch.

An explicit requestMagicLink(uri) still wins over the configured default, so
headless callers keep per-call control.

Tests

tests/magicLinkDestination.test.tsx drives both views through a real client
with only fetch mocked, and asserts the resend body is byte-identical to the
first send. I verified it bites: pointing MagicLinkSent.resend at a different
destination fails it with the two bodies side by side, rather than passing
vacuously.

Also covered: the client honours its configured default, a call argument
overrides it, the hook passes the value through, and with nothing configured
both views still send {} and keep the deployment's destination.

Checks

npm run typecheck, npm run lint, npm run format:check, npm run build and
npm run check-npm-build all pass. 319 tests across 32 suites pass. The option
appears in the built AuthProvider.d.ts and createSeamlessAuthClient.d.ts.

requestMagicLink(redirectUri) shipped in 0.10.0, but only the headless client
path could reach it. An application using AuthRoutes had no way to set one, so
the deployment-wide destination was the only option for the audience least
likely to be wiring up its own client.

AuthProvider takes magicLinkRedirectUri and useAuthClient hands it to the
client as the default for every send. SeamlessAuthClientOptions carries the
same field for a directly constructed client.

The destination lives on the client rather than at each call site on purpose.
The sign-in screen and the resend both send with no argument, so neither view
changes here and the two cannot disagree about where the link goes. A resend
landing somewhere other than the link it repeats would be a confusing failure
and an easy one to miss in review.

Omit it and nothing changes: the same empty body is sent and the deployment's
destination still applies. An explicit argument still wins.

Closes #139
@Bccorb
Bccorb merged commit 74f17d2 into main Sep 4, 2026
2 of 3 checks passed
@Bccorb
Bccorb deleted the feat/magic-link-destination-for-bundled-views branch September 4, 2026 01:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The bundled auth views cannot set a magic link destination

1 participant