Skip to content

Authentication

Authentication screens: sign in, sign up, password recovery, magic link, two-factor, device authorization and the whole flow, in a card or split shell.

Installation & usage

npx @youj/cli add auth-login

Also installs auth-shell.

The CLI copies the block to blocks/auth/login.tsx with every component it uses, so it’s yours to edit.

Every prop is optional and falls back to the demo, so it renders as you see it until you pass your own. Give it your data, rewrite or translate its strings through copy, and connect its actions:

login-view.tsx
'use client'

import Link from 'next/link'
import { Login, type LoginProps } from '@/blocks/auth/login'

export function LoginView({ providers, brand }: Pick<LoginProps, 'providers' | 'brand'>) {
  return (
    <Login
      providers={providers}
      brand={brand}
      copy={{ legalBefore: 'By continuing you agree to our' }}
      linkComponent={Link}
      onSignIn={async (values) => {
        // await your API here; the block shows progress until it settles
      }}
      onProvider={(provider) => {
        // your code
      }}
    />
  )
}

Reference

Props12 props, 2 types

Props

Login props
PropType
onSignIn(values: LoginValues) => Promise<unknown>

Resolve to sign in; reject with an Error whose message says why not.

default a short demo wait

a short demo wait
onProvider(provider: string) => unknown

Starts a provider's redirect with its id. Default: a short demo wait.

–
providersAuthProvider[]

The "Continue with…" buttons, in order; [] for the email form alone. Default: Google and GitHub.

–
defaultValuesPartial<LoginValues>

The fields' starting values (email, password, remember). Default: empty, with "Keep me signed in" on.

–
errorReactNode

A server error to show above the form (from a failed redirect, say) until the next attempt.

–
layoutAuthShellVariant
'card''split'

card: one centered card. split: the form beside an art panel from lg up.

default 'card'

'card'
illustrationIllustrationSlot

The split layout's art: a scene from the illustrations by id, your own node, or null for the plain band alone.

default 'deploy'

'deploy'
copyPartial<AuthCopy>

Any of the strings (headings, labels, errors, the quote, the legal line), to rewrite or translate. Default: the Northwind demo's.

–
brandAuthBrand

The product above the form: { name, logo?, href? }. Default: the Northwind demo.

–
linksPartial<AuthLinks>

Where the links go: signIn, signUp, forgot, terms, privacy, and the mail apps (gmail, outlook). Default: the demo's # anchors.

–
linkComponentElementType

Renders every internal link, e.g. Next.js Link.

default `'a'`

`'a'`
headingLevel1 | 2 | 3

The step heading's level.

default 1

1

AuthBrand

AuthBrand props
PropType
nameRequiredstring–
logoReactNode

Your mark before the name. Default: none (the demo brand has its own).

–
hrefstring

Where the brand links.

default '/'

'/'

AuthProvider

AuthProvider props
PropType
idRequiredstring

What onProvider receives, e.g. 'google'.

–
labelRequiredstring

The button's label, e.g. "Continue with Google".

–
iconReactNode

The provider's mark before the label.

–
variant'outline' | 'secondary'

default `secondary`

`secondary`
classNamestring–
Strings132 keys for copy

Strings

copy takes any of these keys; the rest keep their defaults. A key whose text holds a value (a count, a name) takes a function.

legalBeforelegalTermslegalAndlegalPrivacylegalAfterquotequoteNamequoteRoleproviderPendingproviderSuccessoremailemailPlaceholderemailRequiredemailInvalidgenericErrorsignInTitlesignInDescriptionsignInFormLabelsignInFailedpasswordpasswordRequiredforgotPasswordremembersignInsigningInsignedInsignInErrornewHerecreateAccountLinkmagicLinkmagicLinkSendingmagicLinkSentmagicLinkErrorsignUpTitlesignUpDescriptionsignUpFormLabelsignUpFailednamenamePlaceholdernameRequiredworkEmailpasswordRulestermstermsRequiredcreateAccountcreatingAccountaccountCreatedcreateErrorhaveAccountforgotTitleforgotDescriptionforgotEmailHintsendResetLinksendingsentsendErrorrememberedbackToSignIncheckEmailTitlecheckEmailBeforecheckEmailAfterresendLinkdifferentEmailresetTitleresetDescriptionresetFailednewPasswordconfirmPasswordconfirmRequiredmismatchupdatePasswordsavingsavedsaveErrorresetDoneTitleresetDoneDescriptioncontinueToSignIntwoFactorTitletwoFactorDescriptionrecoveryDescriptionverificationCoderecoveryCodecodeCheckingcodeVerifiedcodeFailedcodeFailedHintcodeVerifiedHintuseRecoveryuseAppsomeoneElsenoTextinboxTitleinboxBeforeinboxAfteropenGmailopenOutlooknothingYetsendAnotherdeviceTitledeviceDescriptiondeviceAppdeviceAccessdeviceAccountdeviceNotYoudeviceCodedeviceCodeMatchdeviceSafetydeviceAuthorizedeviceAuthorizingdeviceAuthorizeddeviceAuthorizeErrordeviceDenydeviceDenyingdeviceDenieddeviceDenyErrordeviceEnterInsteaddeviceEnterTitledeviceEnterDescriptiondeviceEnterLabeldeviceCheckingdeviceCodeFounddeviceCodeUnknowndeviceCodeUnknownHintdeviceApprovedTitledeviceApprovedDescriptiondeviceDeniedTitledeviceDeniedDescriptiondeviceExpiredTitledeviceExpiredDescriptiondeviceTryAnotherdeviceStartOver
Built from0 components, 1 blocks

Built from

Built on

Accessibilitylandmarks, forms, errors, focus

Accessibility

Every screen sits in a main; in the split layout the artwork is a separate aside, hidden below the lg breakpoint. Two-factor uses the kit’s one-time-code input and offers a resend. Device authorization shows its code as one image named letter by letter, or takes it in the same one-time-code input; Authorize and Deny are real buttons that report their progress, and the step you arrive on is announced. In the full flow the leaving step is inert and a status region announces the step you arrive on. Links and buttons are real a and button elements with the kit’s focus ring.

The Google logo is a trademark of Google, shown for illustration only.