RegisterPage
Pre-built registration page with invitation-gated signup. Uses blocks primitives, fully localizable and customizable.
01 Usage
Basic
Create account
<script lang="ts">
import { RegisterPage } from '@urbicon-ui/auth';
import { goto } from '$app/navigation';
import { page } from '$app/state';
import { resolve } from '$app/paths';
</script>
<!-- The invitation link is /auth/register?token=<secret>&email=<invitee>; the
token is the proof of invitation, so read both off the URL. -->
<RegisterPage
token={page.url.searchParams.get('token') ?? ''}
defaultEmail={page.url.searchParams.get('email') ?? ''}
onSuccess={() => goto(resolve('/'))}
/>
02 Accessibility
The requirements list has a name
The password checklist is a real <ul> carrying aria-label, so a reader announces it as a named
list with a known item count instead of four orphaned lines under a text field. It is also
the only explanation for why the submit button is disabled — but it renders only once the
password field has content, and not at all when showRequirements is false. In both of those states the button is
disabled with no reachable reason at all, so supply your own explanation if you turn the
checklist off.
Pass/fail is text, not colour
Each requirement is prefixed with a literal ✓ or ✗ character, not an icon and not a colour swap
alone, so the state survives both a screen reader and a monochrome display. The data-met attribute mirrors it for CSS only. Note the
list is not itself a live region: it updates as you type but is not announced on every keystroke,
which would make the field unusable with speech output.
Mismatch is bound to the field
A confirm-password mismatch is passed to the field as the error prop, so Input sets aria-invalid and links the message through aria-describedby. The reader hears the problem
while focus is on the field that has it — server-side failures go to the page-level live
region instead.
Autofill hints
autoComplete is set on all four fields — name, email,
and new-password on both password fields, which is the signal
a password manager needs to offer a generated password rather than the saved one.
03 API Reference
Prop | Type | Default | Description | |
|---|---|---|---|---|
token required | string | — | The invitation token from the ?token= query param. **Required to
register**: possession of it is the entire proof of invitation (#149), so
without it the request is rejected before anything is looked up.
Read it in your route the same way as defaultEmail:
token={page.url.searchParams.get('token') ?? ''}.
It is a credential: keep it out of logs and analytics, and do not put it in
a page title or a shared screenshot.
Required rather than optional-with-a-default on purpose: a page rendered
without it can only ever produce a 400, and an optional prop makes that
mistake type-check. This way the compiler names every call site. | |
apiPath | string | '/api/auth/register' | ApiPath property for the RegisterPage component | |
class | string | — | Extra classes on the root element. | |
csrf | CsrfClientOptions | — | CSRF cookie/header names — only needed when the server overrides the defaults via config.csrf. Mutating requests echo the token automatically. | |
defaultEmail | string | '' | Pre-fills the email field. Pass the ?email= query param from the
invitation link (createInvitationHandlers builds
/auth/register?token=<secret>&email=<invitee>) so an invited user lands on
a ready-to-submit form instead of retyping. Following the same explicit-prop
pattern as ResetPasswordPage/VerifyEmailPage's token, read it from the
page in your route (SSR-safe), e.g.
defaultEmail={page.url.searchParams.get('email') ?? ''}.
Convenience only — the invitation names its own address, and registering
with a different one is refused. | |
fetcher | typeof globalThis.fetch | — | Custom fetch implementation for all API calls. Defaults to the global fetch. Useful for mock backends in demos/tests or custom retry/auth layers. | |
footer | Snippet | — | Content rendered below the form, above links (e.g. terms checkbox). | |
header | Snippet | — | Content rendered above the form (e.g. social login buttons). | |
links | Snippet | — | Replaces the link area. | |
loginUrl | string | '/auth/login' | URL for the login page link. | |
onSuccess | () => void | — | Called after successful registration. | |
passwordMinLength | number | 8 | Minimum password length. | |
requireDigit | boolean | true | RequireDigit property for the RegisterPage component | |
requireLowercase | boolean | true | Require lowercase letter. | |
requireSpecial | boolean | false | Require special character. | |
requireUppercase | boolean | true | Require uppercase letter. | |
showRequirements | boolean | true | Show real-time password requirements checklist. | |
slotClasses | AuthPageSlotClasses | — | Per-slot class overrides. Keys: root, card, title, form, field, submit, error, success, links. | |
t | PartialAuthLocale | — | Locale overrides, deep-merged over the active built-in bundle (resolved from the i18n context). Pass any subset — a single string or a whole tree. | |
unstyled | boolean | — | Strip all default styling. |
04 Types
Local type definitions used by this component.
Name | Kind | Category | Used by | Description | |
|---|---|---|---|---|---|
RegisterPageProps | interface | props | 0 | — | |
PartialAuthLocale | type | helper | 1 | Consumer-facing locale input: any subset of AuthLocale. Components
accept this as their t prop and deep-merge it over the active built-in
bundle, so overriding a single string never silently blanks the rest. | |
CsrfClientOptions | interface | helper | 1 | — | |
AuthPageSlotClasses | interface | helper | 1 | Per-slot CSS class overrides for auth page components (LoginPage, RegisterPage, etc.). Each key targets a specific visual area of the page. Only the slots you override are affected. | |
DeepPartial | type | helper | 0 | Recursive partial: every branch and leaf becomes optional. | |
AuthLocale | interface | helper | 0 | The complete auth locale bundle. Every key is required: the bundles this
package ships (en, de) satisfy the full shape, and consumer overrides
enter as PartialAuthLocale — deep-merged over the active built-in
bundle by mergeAuthLocale — so component markup reads keys directly,
without per-key ?? '…' fallback literals (review R19).
Placeholder convention: dynamic values use **single-brace** tokens
({n}, {name}, {email}) that the consuming component substitutes itself
via String.replace('{token}', value). There is deliberately **no**
{{…}} runtime interpolator in this package — the key-based translator twin
(authT/at) was removed in R21 — so {{…}} here would render verbatim. |
05 Installation
Import
import { RegisterPage } from '@urbicon-ui/auth';