SignupForm
A ready-made account-creation form — name/email/password/confirm fields, a live password-strength checklist, and a required terms checkbox — emits `submit` with the collected values instead of calling an API itself.
<UiSignupForm />Options
One block per prop — what it does, and what it looks like set.
Loading
loading disables every field and swaps the submit button's label and icon for a spinner, for while the request is in flight.
Error
error is shown above the fields — where a failed signup belongs, since it's about the attempt rather than about any one input.
Purely presentational — it validates the fields client-side and emits submit with the raw values, but never calls an API itself. Wire @submit to your own registration request, and set loading/error from its result.
Color
color applies to the submit button and the links, so the whole form picks up one accent.
Title
title is the heading. An empty string drops it, for a form inside a page or modal that already has one.
Description
description is the line under the heading — the one place to make the promise specific to your product. An empty string drops it.
Login to
loginTo is where 'Sign in' points, /login by default. An empty string drops the line.
Terms to
termsTo is the Terms of Service link. Set it to an empty string and the words stay in the sentence but stop being a link — which is what you want before the page exists, rather than shipping a 404 into your consent copy.
Privacy to
privacyTo is the same for the Privacy Policy link.
Providers
providers adds social sign-up under the submit button — a labelled rule, then one button per provider, rendered by SocialLogin with a 'Sign up with …' label. Clicking one emits provider with its id and nothing else happens: the OAuth flow is yours to start. Note that a provider account skips the terms checkbox entirely, so record that consent in your own callback if you need it.
A provider button bypasses the whole form, terms checkbox included — nothing here records that consent. If you need it, gate the OAuth flow behind your own check in the provider handler, or capture it on the callback route.
The buttons read 'Sign up with …' rather than SocialLogin's neutral 'Continue with …'. The flow itself is identical either way — OAuth signs in an existing account and creates a missing one with the same redirect — so the wording is a promise about the screen, not about what happens.
Provider layout
providerLayout picks between the full-width labelled buttons above (stacked) and one icon-only button per provider on a single row (inline) — worth the switch once you're offering four or more.
Examples
The component in real use: compositions that answer "how do I build X with this", rather than one prop at a time.
Translating the rest — a locale, not thirty props
Every other string comes from the locale handed to App. The consent sentence is five separate keys so it can be reordered per language — German closes the clause after the links with termsSuffix, where English leaves it empty. See [Internationalization](/i18n).
`terms` slot — when the sentence won't come apart
Where five fragments still aren't enough — a language that reorders the clause around the links, or copy that needs a third link — the slot replaces the whole sentence and the fragments stop being consulted.
Basic — live password requirements, confirm-password match check, required terms checkbox
The password field sets PasswordInput's min-length/require-uppercase/require-lowercase/require-number — its live checklist is what drives this form's own password validity, tracked via v-model:valid rather than re-implemented here. require-special-char is deliberately left off; add it yourself (and update the submit-time check) if your backend requires it.
'Confirm password' is a plain Input, not another PasswordInput — it doesn't get its own reveal toggle or requirements checklist, it's just checked against password on submit.
The 'Sign in' and terms/privacy links point to /login, /terms, and /privacy — plain hardcoded routes, not props. Add matching pages in your app, or copy the component and change the links if yours differ.
API Reference
Generated from the component's source — props, slots and emits as the component actually declares them.
Props
booleanfalse"neutral" | "primary" | "secondary" | "success" | "error" | "warning" | "info" | "pending"'primary'stringstring'/terms'string'/privacy'(SocialProviderId | SocialProvider)[][]"stacked" | "inline"'stacked'Slots
termsEmits
submit[payload: { name: string; email: string; password: string }]provider[id: string]Types
type Color = "neutral" | "primary" | "secondary" | "success" | "error" | "warning" | "info" | "pending";interface SocialProvider {
/**
* Identifier emitted by `select` — use it in your handler to pick which OAuth flow to start.
* Matching a `SocialProviderId` also supplies the brand name and logo for free.
*/
id: string;
/**
* The provider's brand name, rendered after the `label` verb ('Continue with **Google**').
* Defaults to the brand name for a built-in id, or the id itself, title-cased.
*/
name?: string;
/**
* URL of the provider's logo, rendered as an `<img>`. Defaults to the bundled brand mark for a
* built-in id.
*/
logo?: string;
/**
* A bundled icon name to render instead of a logo image — for a provider with no brand mark of
* its own (SAML, a magic link, your own SSO).
*/
icon?: string;
}type SocialProviderId = "google" | "apple" | "microsoft" | "github" | "gitlab" | "facebook" | "discord" | "x" | "twitter" | "instagram";