Magic Link Auth
Switch your site's login flow to passwordless magic links. Users enter their email, receive a one-time link, and click it to log in — no password required.
Configure login mode
Set loginMode in settings/auth.md:
---
provider: custom
# Login mode: password, magic-link
loginMode: magic-link
loginPage: /login
afterLogin: /account
afterLogout: /
---
| Value | Behavior |
|---|---|
password |
Email + password form (default) |
magic-link |
Email-only form, one-time login link sent by email |
How it works
In magic-link mode, the built-in auth pages call window.__sitemdAuth.requestMagicLink(email). Each provider handles the flow differently using its native passwordless API — no custom backend required for third-party providers.
The user experience is the same across all providers: enter email, receive a link, click to log in.
What changes in your pages
When loginMode: magic-link is set, the built-in auth pages adapt automatically at runtime:
/login — shows an email field and "Send Login Link" button instead of the email+password form. After submission, replaces the form with a "check your email" confirmation.
/upgrade (purchase page) — shows email only, opens Stripe checkout in a new tab. After payment, the Stripe webhook creates the user account and sends a welcome email containing the magic link.
/forgot-password — not linked from the login page in magic link mode (there is no password to reset).
/account/settings — the change password section is not shown.
Email template
Magic link emails use the magic-link template from emails/auth/magic-link.md. Customize it like any other email template:
---
id: magic-link
subject: Your login link
# Variables available: {{loginUrl}}
---
Click to log in — this link expires in 30 minutes:
[Log in]({{loginUrl}})
See Email Templates for full template format and provider setup.
JavaScript API
The auth runtime exposes requestMagicLink on window.__sitemdAuth:
window.__sitemdAuth.requestMagicLink(email)
.then(() => { /* show "check your email" */ })
.catch(err => { /* show error */ })
The current loginMode value is available at runtime via window.__sitemdAuthCfg.loginMode. Use it in your own page scripts to conditionally show or hide password-related UI:
var cfg = window.__sitemdAuthCfg || {};
if (cfg.loginMode === 'magic-link') {
// hide password fields
}
Provider support
Magic link mode works with all auth providers. Each uses its native passwordless API:
| Provider | How it works | Dashboard setup |
|---|---|---|
custom |
Your API implements /auth/magic-link/request and /auth/magic-link/verify endpoints (see below) |
— |
supabase |
Calls signInWithOtp — Supabase sends the magic link email |
Enable "Email OTP" in Authentication → Providers → Email |
firebase |
Calls sendSignInLinkToEmail — Firebase sends the email link |
Enable "Email/Password" → toggle on "Email link (passwordless sign-in)" in Authentication → Sign-in method |
clerk |
Creates a sign-in with email_link strategy — Clerk sends the link |
Enabled by default |
auth0 |
Redirects to Auth0 Universal Login with passwordless email | Enable the "Email" passwordless connection in Authentication → Passwordless |
For third-party providers, the redirect URL / callback URL for your site must be allowed in the provider's dashboard settings.
Custom provider API endpoints
When using provider: custom, your API must implement two endpoints:
POST /auth/magic-link/request
Body: { email: string }
Generates a one-time token, stores it, and sends the email. Always returns { ok: true } regardless of whether the email exists (prevents enumeration).
GET /auth/magic-link/verify?token=<tokenId>
Validates the token, creates a session, deletes the token, and redirects to:
{SITE_URL}/account#magic=<sessionToken>
The auth runtime handles the rest client-side.
Testing magic links locally
The dev server includes a built-in auth stub for the custom provider. Navigate to your login redirect URL with any magic code to log in instantly:
http://localhost:4747/account#magic=anytoken
The stub accepts any exchange code — no real API or email required. See Local Auth Testing for details.
Related
- User Auth & Gating — full auth setup, gating pages, user types
- Dev Server — Local Auth Testing — test auth flows without a backend
- Email Templates — customizing transactional email templates
- Purchase flow — how auth-pages integrate with checkout