@@ -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
233240export 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