Authentication

  • Entering data
  • 3 min
  • components: 8
  • pairs: 3

Nothing here is a special component — it is an ordinary form. Everything that matters is in the decisions, and most of them are about what not to say.

Reviewed 2026-09-06

On this page

What it solves

The library has no sign-in component, and this page will not pretend otherwise: authentication is built from GrForm, two GrInputs and a button. Nothing on the screen is unusual.

Everything that makes it hard is invisible. An error message that is too helpful tells an attacker which addresses are registered. A field that fights the password manager makes people choose weaker passwords. A disabled button hides the reason it is disabled. None of that shows up in a mockup.

So this pattern is about decisions, and most of them are decisions about what not to say.

Anatomy

The parts are ordinary, and the conditions are the same as anywhere else:

  1. The form owns validation — GrForm. One place decides whether the attempt is allowed to leave the browser.
  2. Each field binds label, control and error — GrFormField. Same as any form: the error belongs to the field, not to the page.
  3. A string is entered — GrInput for the address and the password, with the autofill contract set correctly — see below, because that is the whole of the password-manager story.
  4. A flag in a form — GrCheckbox for «stay signed in», which is a choice about this device, and worth saying so.
  5. The action changes state — GrButton. It submits; it is not a link.
  6. The message belongs to the page — GrAlert for what went wrong with the attempt as a whole, distinct from a field-level error.
  7. A transition is needed — GrLink for «forgot», «create an account», «use another method»: these are places, and they get addresses.

Example

Do and don’t

Do — One message for a wrong address and a wrong password

«Wrong email or password» is deliberately vague, and the vagueness is the point: it does not tell a stranger which addresses have accounts. The person who owns the account is not confused by it — they know which of the two they got wrong.

Don’t — «No account with this email»

It is helpful to the person and equally helpful to whoever is checking a list of addresses. The same applies to sign-up: «this email is taken» answers the same question from the other side, and the honest fix is to say it by email instead.

Do — Tell the browser what the fields are

The autofill contract is what password managers read: username for the address, current password for signing in, new password for setting one. Get it right and a manager fills the form; get it wrong and people type from memory — and a password typed from memory is a short password.

Don’t — Block paste, or cap the length

Blocking paste in a password field is aimed at nobody: an attacker types, a person with a manager cannot. A low length cap is worse — it says the password is stored in a way that has a size limit, and that is not something to advertise.

Do — Say what happened after too many attempts

Locked for a few minutes is fine; silence is not. GrAlert carries the reason and, where it applies, when to try again. A person who does not know they are rate-limited will assume the password is wrong and start changing it.

Don’t — Disable the button until the fields look valid

On a sign-in form there is nothing to validate before submitting — the server decides. A disabled button cannot be focused and explains nothing, and the person is left checking a form that is already correct.

Accessibility

The error must reach a screen reader. A failed attempt puts the message in a live region, not only on the screen: the page did not change address, the form looks the same, and without an announcement nothing happened at all.

A show-password toggle is a button with a state. It reports whether the password is currently visible, so a screen-reader user knows what the field holds before they type into it in public.

Waiting must be visible. The moment between pressing the button and the answer belongs to GrLoading — otherwise people press again, and the second attempt is what triggers the rate limit.

This page describes the screen, not the security behind it. Password storage, session lifetime, second factor and lockout policy are decided outside the interface — and no component list makes those choices safer.

Components in this pattern

The list is built from frontmatter, not from links in the prose: renaming a slug does not lose it.

Keyboard

Contracts come from the library. The pattern does not restate them — it points at them.