Skip to content

Magic link authentication

Implement passwordless authentication by sending secure, time-limited login links via email.

This example demonstrates how to send a magic link email for passwordless authentication using Cloudflare Email Service.

TypeScript
interface Env {
EMAIL: SendEmail;
DOMAIN: string;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === "/send-magic-link" && request.method === "POST") {
return handleSendMagicLink(request, env);
}
return new Response("Not Found", { status: 404 });
},
};
async function handleSendMagicLink(
request: Request,
env: Env,
): Promise<Response> {
const { email } = await request.json();
if (!email || !isValidEmail(email)) {
return new Response(JSON.stringify({ error: "Invalid email" }), {
status: 400,
});
}
// Generate a simple secure token (you would implement proper JWT/token handling)
const token = crypto.randomUUID();
const magicUrl = `https://${env.DOMAIN}/login?token=${token}`;
// Send magic link email
await env.EMAIL.send({
to: email,
from: `noreply@${env.DOMAIN}`,
subject: "Your login link",
html: `
<h1>Login to your account</h1>
<p>Click the link below to log in:</p>
<p><a href="${magicUrl}">Login Now</a></p>
<p>This link expires in 15 minutes.</p>
`,
text: `
Login to your account
Click this link to log in: ${magicUrl}
This link expires in 15 minutes.
`,
});
return new Response(
JSON.stringify({
success: true,
message: "Magic link sent to your email",
}),
);
}
function isValidEmail(email: string): boolean {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}