Documentation Index
Fetch the complete documentation index at: https://usegately.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
Magic links provide passwordless authentication by sending a secure login link to the user’s email.
Send Magic Link
await gately.sendMagicLink(email, options)
Parameters
| Parameter | Type | Required | Description |
|---|
email | string | Yes | User’s email address |
options.redirectTo | string | No | URL to redirect after login |
Example
import { GatelyClient } from '@gately/sdk'
const gately = new GatelyClient('YOUR_PROJECT_ID')
async function handleMagicLink(email) {
try {
await gately.sendMagicLink(email, {
redirectTo: '/dashboard'
})
// Show success message
showMessage('Check your email for a login link!')
} catch (error) {
console.error('Failed to send magic link:', error.message)
}
}
React Component
import { useState } from 'react'
import { useGately } from '@gately/sdk'
function MagicLinkForm() {
const { sendMagicLink } = useGately()
const [email, setEmail] = useState('')
const [sent, setSent] = useState(false)
const [error, setError] = useState('')
const handleSubmit = async (e) => {
e.preventDefault()
setError('')
try {
await sendMagicLink(email, { redirectTo: '/dashboard' })
setSent(true)
} catch (err) {
setError(err.message)
}
}
if (sent) {
return (
<div className="success">
<h2>Check your email</h2>
<p>We sent a login link to {email}</p>
<button onClick={() => setSent(false)}>
Use a different email
</button>
</div>
)
}
return (
<form onSubmit={handleSubmit}>
{error && <p className="error">{error}</p>}
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Enter your email"
required
/>
<button type="submit">
Send Magic Link
</button>
</form>
)
}
How It Works
- User enters their email
- SDK sends request to Gately API
- Gately sends email with secure link
- User clicks link in email
- Link redirects to your app with auth token
- SDK automatically logs user in
Email Template
The magic link email includes:
- Your project name/branding
- Login button with secure link
- Link expiry notice (default: 1 hour)
- Security notice
Customize the email template in Settings > Email > Templates.
Link Expiry
Magic links expire after 1 hour by default. If a user clicks an expired link:
- They see an error message
- They’re prompted to request a new link
Security
Magic links are:
- Single-use (invalidated after first use)
- Time-limited (expire after 1 hour)
- Cryptographically signed
- Tied to specific email address
New vs Existing Users
| Scenario | Behavior |
|---|
| Existing user | Logs in to existing account |
| New user | Creates account and logs in |
// Works for both new and existing users
await gately.sendMagicLink('user@example.com')
Error Handling
try {
await gately.sendMagicLink(email)
} catch (error) {
switch (error.code) {
case 'INVALID_EMAIL':
showError('Please enter a valid email address')
break
case 'RATE_LIMITED':
showError('Too many requests. Please wait a moment.')
break
default:
showError('Failed to send login link. Please try again.')
}
}
Rate Limiting
Magic link requests are rate limited to prevent abuse:
- 3 requests per email per 10 minutes
- 10 requests per IP per 10 minutes
Combining with Password Login
Offer both options for flexibility:
function LoginOptions() {
const [mode, setMode] = useState('password') // or 'magic'
return (
<div>
<div className="tabs">
<button
className={mode === 'password' ? 'active' : ''}
onClick={() => setMode('password')}
>
Password
</button>
<button
className={mode === 'magic' ? 'active' : ''}
onClick={() => setMode('magic')}
>
Magic Link
</button>
</div>
{mode === 'password' ? (
<PasswordLoginForm />
) : (
<MagicLinkForm />
)}
</div>
)
}