Skip to content

Commit 7bac7f1

Browse files
committed
feat(webapp): improve the magic-link "sent" confirmation screen
Name the address the link was sent to (rendered bright) in the confirmation copy, carried through on the success redirect. Tighten the wording and balance the line wrapping so it doesn't orphan a word. "Re-enter email" now returns to /login (where the email form lives) instead of bouncing through this route's loader redirect.
1 parent 408ffbf commit 7bac7f1

2 files changed

Lines changed: 22 additions & 7 deletions

File tree

.server-changes/login-sso-ui.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ otherwise, so the inline form is the single source of truth and old links
1111
don't 404. `/login/sso` gets refreshed copy, an "Enterprise email address"
1212
placeholder, and an "Ask about SSO" link. The Documentation link is removed
1313
from the shared login layout. Both email fields validate inline with the
14-
standard styled form error instead of the browser's native tooltip.
14+
standard styled form error instead of the browser's native tooltip. The
15+
"magic link sent" confirmation names the address the link was sent to, and its
16+
"Re-enter email" action returns to `/login`.

apps/webapp/app/routes/login.magic/route.tsx

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ export async function loader({ request }: LoaderFunctionArgs) {
7575
// error isn't consumed here before /login can display it.
7676
const url = new URL(request.url);
7777
const sanitized = sanitizeRedirectPath(url.searchParams.get("redirectTo"));
78+
// The submitted address is carried on the success redirect so the
79+
// confirmation can name it. Validate before echoing it back.
80+
const emailParam = url.searchParams.get("email");
81+
const email = emailParam && z.string().email().safeParse(emailParam).success ? emailParam : null;
7882
if (!session.has("triggerdotdev:magiclink")) {
7983
// Throw (not return) so the redirect doesn't widen the loader's return
8084
// type — otherwise useTypedLoaderData sees TypedResponse<never> in the
@@ -109,6 +113,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
109113
{
110114
magicLinkSent: session.has("triggerdotdev:magiclink"),
111115
magicLinkError,
116+
email,
112117
},
113118
{
114119
headers,
@@ -210,7 +215,7 @@ export async function action({ request }: ActionFunctionArgs) {
210215
}
211216

212217
return authenticator.authenticate("email-link", request, {
213-
successRedirect: "/login/magic",
218+
successRedirect: `/login/magic?email=${encodeURIComponent(email)}`,
214219
failureRedirect: "/login/magic",
215220
});
216221
}
@@ -221,7 +226,9 @@ export async function action({ request }: ActionFunctionArgs) {
221226
const session = await getUserSession(request);
222227
session.unset("triggerdotdev:magiclink");
223228

224-
return redirect("/login/magic", {
229+
// The email form now lives on /login, so send "Re-enter email" straight
230+
// there rather than bouncing through this route's loader redirect.
231+
return redirect("/login", {
225232
headers: {
226233
"Set-Cookie": await commitSession(session),
227234
},
@@ -231,7 +238,7 @@ export async function action({ request }: ActionFunctionArgs) {
231238
}
232239

233240
export default function LoginMagicLinkPage() {
234-
const { magicLinkSent, magicLinkError } = useTypedLoaderData<typeof loader>();
241+
const { magicLinkSent, magicLinkError, email } = useTypedLoaderData<typeof loader>();
235242
const navigate = useNavigation();
236243

237244
const isLoading =
@@ -250,9 +257,15 @@ export default function LoginMagicLinkPage() {
250257
</Header1>
251258
<Fieldset className="flex w-full flex-col items-center gap-y-2">
252259
<InboxArrowDownIcon className="mb-4 h-12 w-12 text-indigo-500" />
253-
<Paragraph className="mb-6 text-center">
254-
We sent you an email which contains a magic link that will log you in to your
255-
account.
260+
<Paragraph className="mb-6 text-center [text-wrap:balance]">
261+
{email ? (
262+
<>
263+
We emailed a magic link to <span className="text-text-bright">{email}</span>{" "}
264+
to log you in to your account.
265+
</>
266+
) : (
267+
"We emailed you a magic link to log you in to your account."
268+
)}
256269
</Paragraph>
257270
<FormButtons
258271
cancelButton={

0 commit comments

Comments
 (0)