Sign-in & registration blocks
Screens for getting a user into your app: sign in with a password, a provider
or a magic link, create an account, prove it is them with a one-time code, and
reset a forgotten password. Each block is one .svelte file built from
SvTextInput, SvPasswordInput, SvOtpInput, SvButton and SvCard, themed
from the --sg-* tokens.
Installation
Add the whole group, or one block by its name (shown under each demo):
See them first with npx @svgrid/ui try blocks/auth. No project needed.
Login
A two-column page: a brand panel on the left, the sign-in card on the right with provider buttons, email and password (with reveal), remember-me and a forgot-password link. Below 720 px the brand panel is hidden and the card fills the screen.
Open the live example: Login block (Blocks)
npx @svgrid/ui add login
Sign-up
A centered account-creation card: first and last name side by side, work email, a password with the live strength meter, a plan switch and a terms checkbox.
Open the live example: Sign-up block (Blocks)
npx @svgrid/ui add signup
Two-factor code
The second step of a sign-in: a six-digit SvOtpInput that advances on each
digit and verifies on the last one, with a resend timer. Enter 000000 to see
the error state.
npx @svgrid/ui add otp
Sign-in with providers
SSO first: Google, GitHub and Microsoft buttons, and a Single sign-on (SAML) button that opens a company-domain field. Below the divider, a passwordless form emails a sign-in link and switches the card to a "Check your inbox" state with the address, a 30-second resend cooldown and a link to use a different email.
npx @svgrid/ui add auth-providers
Forgot password
Two states in one card. The request state takes an email, validates it and shows the button's loading state while it sends. The confirmation names the address, offers a resend after a 60-second cooldown and a link to try another email; "Back to sign-in" sits in the footer of both.
npx @svgrid/ui add auth-forgot-password
Connecting your auth
Each block's core takes its requests as options, so wiring a real backend
leaves the markup alone. Find the create...() call in the block's instance
script and replace the demo's timer. In the login block that is
createLogin({ onSubmit }). It gets { email, password, remember } once both
fields validate, the submit button shows its loading state until the promise
settles, and a throw keeps the form as it was and goes to onError:
const login = createLogin({
onSubmit: async (values) => {
const r = await fetch('/api/login', { method: 'POST', body: JSON.stringify(values) })
if (!r.ok) throw new Error('Wrong email or password')
location.assign('/app')
},
onError: (e) => toast.error(e instanceof Error ? e.message : 'Sign-in failed'),
})
In SvelteKit you can use a form action instead: give the <form> a
method="POST" and drop the {...login.formProps()} spread, which calls
preventDefault. The email and password fields already have a name; give any
other input one too. An input with a name submits its value through a hidden
field, so +page.server.ts reads it from request.formData() like a plain
input.
The other blocks work the same way:
- Sign-up:
createSignup({ onSubmit })gets{ first, last, email, password, plan, agree }. Until there is an email, a password of 8 or more characters and a ticked terms box, submit callsonIncompleteinstead. - Two-factor code:
createOtp({ onVerify })gets the code. Returnfalseor throw to reject it (onRejected); anything else moves the card to its verified state (onVerified).onResendsends a new code, and the core runs the 30-second cooldown. - Sign-in with providers:
createProviderSignIn({ onProvider, onSso, onSendLink }).onProvidergets{ id, name, mark }, so redirect to your OAuth start route foridthere.onSsogets the lowercased company domain.onSendLinkposts the magic-link email; when it resolves the card flips to "Check your inbox". - Forgot password:
createForgotPassword({ onRequest })handles the first send and, unless you passonResend, the resend button. A throw callsonError(error, 'request' | 'resend'). In the demo both go through therequestReset(addr)stand-in at the top of the script, so replacing that one function wires both:
const requestReset = async (addr: string) => {
const r = await fetch('/api/password-reset', { method: 'POST', body: JSON.stringify({ email: addr }) })
if (!r.ok) throw new Error('Reset failed')
}
Headless
Every block here is a styled render of the core in its <script module>. To
draw your own markup, take the core alone with npx @svgrid/ui add auth-forgot-password --headless (it writes auth-forgot-password.svelte.ts)
and spread its prop-getters on plain elements:
<script lang="ts">
import { createForgotPassword } from './auth-forgot-password.svelte.js'
const forgot = createForgotPassword({
onRequest: async (email) => {
const r = await fetch('/api/password-reset', { method: 'POST', body: JSON.stringify({ email }) })
if (!r.ok) throw new Error('Reset failed')
},
})
</script>
{#if forgot.sentTo}
<p>Check {forgot.sentTo} for a reset link.</p>
<button {...forgot.resendProps()}>{forgot.cooldown ? `Resend in ${forgot.cooldown}s` : 'Resend'}</button>
{:else}
<form {...forgot.formProps()}>
<label>Email <input {...forgot.fieldProps()} /></label>
{#if forgot.error}<p role="alert">{forgot.error}</p>{/if}
<button disabled={forgot.busy}>Send reset link</button>
</form>
{/if}
See also
Live examples
- Login block - A two-column authentication page: a branded gradient panel beside a sign-in SvCard with social SvButtons, SvTextInput + SvPasswordInput (reveal), remember-me SvCheckBox, an "or" SvDivider and forgot-password link. Drops into any route as-is.
- Sign-up block - A centered account-creation card: two-up name fields, work email, a password with the live strength meter, a plan SvSegmented switch, terms SvCheckBox and a benefits rail. Submit fires a promise toast. Pure UI-kit.
- Two-factor / OTP block - The verification step of a sign-in flow: SvOtpInput (6 digits, auto-advance + onComplete), a resend cooldown timer, and the waiting -> verifying -> verified states. Enter 000000 to see the error path.
- Sign-in with providers block - SSO-first SvCard with Google, GitHub and Microsoft SvButtons, plus a SAML option that reveals a company-domain SvTextInput. Below an SvDivider, a magic-link form switches to a Check your inbox state with a 30 s resend cooldown.
- Forgot password block - Password recovery in one SvCard. An email SvTextInput with validation and a loading SvButton leads to a check-your-email state that names the address, has a 60 s resend cooldown and a back-to-sign-in link.
Related articles
- The Headless UI Pattern - Separating Logic from Presentation - How SvGrid splits the row-model pipeline from rendering, and when you actually want to reach past the default table and drive the headless layer directly.
- Using SvGrid with shadcn-svelte - Wire SvGrid's --sg-* CSS tokens to shadcn-svelte's design variables so the grid inherits your app's palette and dark mode automatically - no JavaScript required.
- Using SvGrid with Flowbite Svelte - Wire SvGrid into a Flowbite Svelte app - map CSS tokens for dark mode, build toolbar controls from Flowbite components, and put Flowbite Buttons inside cell renderers.