ZevAuth Docs
Sign up

Building with the SDK

Components

The drop-in UI, and how it picks up your brand.

Every component renders what your environment has enabled. Turn magic links on in the console and they appear; turn passkeys off and they stop being offered. You do not redeploy.

SignIn

<SignIn afterSignInUrl="/dashboard" />
Live preview
Northwind

Sign in

Secured by ZevAuth

Renders whichever of password, magic link, email code and ZevID your environment accepts. Enable more in the console and they appear here, with no change to your code:

Live preview
Northwind

Sign in

or
or
Secured by ZevAuth

With several enabled that gets long. secondaryMethods="collapsed" folds the alternatives behind a toggle:

<SignIn secondaryMethods="collapsed" />
Live preview
Northwind

Sign in

Secured by ZevAuth

Which is right depends on the method you want people to reach for, so it is yours to choose rather than ours to decide.

If none are enabled it says so, rather than rendering an empty box.

PropTypeDefault
afterSignInUrlstringWhere to go once signed in. Omit it and the component simply stops rendering the form, leaving your router in charge.
secondaryMethods'inline' | 'collapsed''inline'Whether the passwordless alternatives are laid out or folded away.
childrenReactNodeRendered instead of the form once somebody is signed in.
classNamestringApplied to the outer wrapper.

SignInWithZevId

Just the SSO button, for a sign-in page you built yourself.

<SignInWithZevId />
Live preview

No card, no identity block, no attribution: it is a control inside your layout rather than a screen of ours. You do not have to adopt <SignIn> to offer ZevID.

PropTypeDefault
redirectUrlstringcurrent pageWhere to return after signing in.
labelstring'Continue with ZevID'
variant'primary' | 'secondary''secondary'secondary suits a row of provider buttons.
classNamestring

Leave afterSignInUrl off and the component simply stops rendering the form once somebody signs in, so your own router decides what happens next.

SignUp

<SignUp afterSignUpUrl="/welcome" />
Live preview
Northwind

Create your account

or
Optional.
8 characters or more.
Secured by ZevAuth

If your environment requires email confirmation, this shows the “check your email” state instead of signing the person in.

PropTypeDefault
afterSignUpUrlstringWhere to go once the account exists and a session started.
childrenReactNodeRendered instead of the form once signed in.
classNamestring

UserButton

<UserButton afterSignOutUrl="/" />
Live preview

An avatar and a menu. Renders nothing when nobody is signed in, so it can sit beside a sign-in button in your header without the two fighting.

PropTypeDefault
afterSignOutUrlstringWhere to go after signing out.
classNamestring

UserProfile

<UserProfile />
Live preview

Your profile

Contact support to change the address on your account.

8 characters or more. Your other devices will be signed out.

Picture, name and password, for a settings page. The email is shown but not editable: changing an address has to be proved before it takes effect, so it is a flow of its own rather than a text input.

The picture saves on its own rather than waiting for the form’s button. By the time it appears on screen it has already been uploaded, and a Save that seemed to be needed afterwards would ask for a second commitment to something already done.

The password fields start closed. Most visits to a profile page are to change a name, and two empty password boxes on arrival invite a password manager to fill them and a person to wonder what is wrong.

Render one half at a time if your settings area has its own navigation:

<UserProfile section="security" />
Live preview
8 characters or more. Your other devices will be signed out.
PropTypeDefault
section'all' | 'profile' | 'security''all'Render both, or one, so they can live on separate pages.
defaultPasswordOpenbooleanfalseWhether the password fields start open.
classNamestring

OrganizationSwitcher

<OrganizationSwitcher />
Live preview

Hides itself for somebody who belongs to no organizations, because a switcher with one option cannot do anything.

PropTypeDefault
allowPersonalbooleantrueOffer a way back to personal scope.
classNamestring

OrganizationProfile

<OrganizationProfile />
Live preview

Northwind

They need an account here already.
MembersLoading…

Lists members and, for anybody with org:members:manage, offers the controls to change them. The organization’s picture appears above them for anybody with org:manage, which is a separate permission on purpose: inviting a colleague and renaming the company are not the same authority.

PropTypeDefault
classNamestring

ImageField

The picture control from <UserProfile> and <OrganizationProfile>, exported on its own so a custom settings screen gets the same behaviour rather than reimplementing the upload-then-save sequence around uploadAvatar.

<ImageField
  label="Photo"
  value={user.imageUrl}
  upload={(file, onProgress) => client.me.uploadAvatar({ file, onProgress })}
  onSave={(imageUrl) => client.me.update({ imageUrl })}
/>

upload and onSave are separate so you decide what the URL is saved to. That is what lets the same control serve a user’s avatar and an organization’s image without knowing which it is looking at.

PropTypeDefault
labelstring
valuestring | nullThe picture now, or null.
upload(file, onProgress) => Promise<string>Resolves to the URL to save.
onSave(url: string | null) => Promise<unknown>Called with null on removal.
shape'circle' | 'square''circle'Round for a person, square for an organization.
isDisabledbooleanfalse

Styling

The components bring their own CSS, injected once on first render. There is no stylesheet to import. That is one less line to remember, and one less thing to break in a bundler that does not handle CSS imports.

Everything is prefixed zv- and nothing styles bare elements, so the styles cannot reach your markup and yours cannot reach ours.

Your brand arrives from the API: the accent, logo, radius and font you set in the console are applied as CSS variables. Here is the same component with a developer’s own colour:

Live preview
Northwind

Sign in

Secured by ZevAuth

The accent is contrast-corrected server-side for light and dark surfaces, so a colour that is beautiful on white does not become invisible on near-black. The console preview, the hosted pages and these components all paint the same value.

The ZevAuth badge

“Secured by ZevAuth” appears under the card. Whether it can be removed is decided by your plan, on the server. A client cannot turn it off. Development always shows it, so you never design against a screen production will not give you.

Updated at, Friday, August 28, 2026