Authentication
View as markdown.mdPassword reset
Build the reset page your app needs, then point Zeitlos at it.
Password reset is the one auth flow that needs a page from you. The email has to land somewhere that collects a new password, and only your app can provide that.
Because of that, reset is disabled until you configure the page. Until then,
forgetPassword throws RESET_PASSWORD_NOT_CONFIGURED.
How the flow works
- The user asks to reset their password in your app.
- You call
forgetPassword({ email }). - Zeitlos emails them a link to your reset page, with a token in the query string.
- Your page collects a new password and calls
resetPassword({ token, newPassword }). - You send them to sign in.
Setting it up
-
Build the reset page
Any route in your app —
/reset-passwordis a fine choice. It readstokenfrom the query string and collects a new password:app/reset-password/page.tsx 'use client'; import { useState } from 'react'; import { createClient, ZeitlosError } from '@zeitlosapp/sdk'; const client = createClient(); export default function ResetPassword() { const [error, setError] = useState<string | null>(null); async function submit(newPassword: string) { const token = new URLSearchParams(location.search).get('token'); if (!token) return setError('This link is malformed.'); try { await client.auth.resetPassword({ token, newPassword }); location.href = '/sign-in'; } catch (err) { if (err instanceof ZeitlosError && err.code === 'INVALID_TOKEN') { setError('This link has expired or was already used.'); } } } // …your form, calling submit(newPassword) } -
Tell Zeitlos where it is
Go to Authentication → Settings → Password reset and enter the page's full URL, e.g.
https://yourapp.com/reset-password. The card's badge flips from Disabled to Enabled once saved. -
Trigger a reset from your app
From your "Forgot password?" screen:
TypeScript await client.auth.forgetPassword({ email });This always resolves the same way whether or not the account exists — it does not reveal which emails are registered. Show a neutral "if that email exists, we've sent a link" message.
Tip
You can test the whole flow locally. See Local development for more details.
Handling an expired link
Reset tokens are single-use and time-limited. A link that has expired or already been used
throws INVALID_TOKEN on resetPassword. Catch it and offer to send a fresh link rather
than leaving the user on a dead page.
Where the email comes from
The sender name and reply-to address are under Authentication → Settings → Email, along with a preview of what the message looks like.