React SDK
@keenauth/react gives you embeddable sign-in, sign-up and account components and the hooks under them. It runs on the browser core @keenauth/js, which does every network call, PKCE, DPoP and WebAuthn ceremony; the components never call fetch or WebCrypto themselves. The package is not published to npm yet.
For a redirect sign-in to the hosted login page, you do not need this package: see the React quickstart, which uses @keenauth/js directly.
Set up the provider
Create the core once and pass it to KeenAuthProvider. Pass the React package's error class to the core, so that the components recognise server problems:
import { KeenAuth } from "@keenauth/js";
import { KeenAuthProblemError, KeenAuthProvider, SignIn } from "@keenauth/react";
const core = new KeenAuth({
issuer: "https://acme.eu.keenauth.app",
clientId: "app_01j9zzzzzzzzzzzzzzzzzzzz",
redirectUri: "https://login.acme.example/callback",
createProblemError: (problem) => new KeenAuthProblemError(problem),
});
export function App() {
return (
<KeenAuthProvider core={core} locale="en">
<SignIn transaction={{ client_id: "app_01j9zzzzzzzzzzzzzzzzzzzz", redirect_uri: "https://login.acme.example/callback" }} />
</KeenAuthProvider>
);
}
KeenAuthProvider takes:
| Prop | Meaning |
|---|---|
core |
The @keenauth/js client (any object that implements the KeenAuthCore contract) |
locale |
UI language (BCP 47); default en |
appearance |
Optional theme overrides, see Appearance |
The components call the front API (/fapi/v1) with your environment's cookies and a CSRF header. The server accepts these calls only from the environment's own login origin, and only for first-party applications.
Components
| Component | What it does |
|---|---|
SignIn |
Identifier-first sign-in: password, passkey, email code or magic link, and second factors |
SignUp |
Sign-up with the environment's registration settings |
UserProfile |
The signed-in user's profile, emails (with code verification), passkeys and sessions |
SignIn and SignUp take transaction, the body that starts a sign-in transaction:
- in the redirect flow,
{ authorization_request: "azr_…" }from the authorization request; - without a redirect,
{ client_id, redirect_uri }with a registered redirect URI.
onComplete is called when the core has finished the transaction in the page; in the redirect flow the page navigates away instead. A step that the components do not draw (for example a challenge or an organization choice) becomes a link to continue on the hosted login page.
UserProfile takes sections, a subset of profile, emails, passkeys and sessions (all four by default). A profile write that conflicts with a change made elsewhere shows an error and reloads the current values.
Hooks
| Hook | Returns |
|---|---|
useKeenAuth() |
The provider value: core, locale, appearance |
useEnvironment() |
The environment's sign-in settings and a text lookup t for the active locale |
useTransaction() |
A transaction state machine over the core's transactions API |
useMe() |
The signed-in user's profile and the account API |
Appearance
appearance.variables overrides theme tokens (for example color.primary); they are written as --idp-* custom properties on the component root through the CSSOM, so a strict Content Security Policy without 'unsafe-inline' styles works. appearance.elements adds your class names to the components' elements. The package ships no stylesheet: style the idp-* classes in your own CSS.
<KeenAuthProvider core={core} appearance={{ variables: { "color.primary": "#1f6feb" }, elements: { buttonPrimary: "acme-button" } }}>
Languages and accessibility
- The components include texts in English, Turkish, French, German, Korean, Japanese, Italian and Spanish. Your environment's text overrides come first; another locale falls back to English, with the text direction of that locale.
- Every input has a label, the error summary takes focus,
autocompletevalues are set and paste is never blocked.
Passkeys
The passkey button appears when the passkey's relying party ID covers the page's host (or the page's origin is a related origin of the environment); otherwise the component links to the hosted login page. Passkeys need a secure context (https or localhost).
Current limits
- Social sign-in buttons are not drawn yet; an environment that offers social sign-in gets a link to the hosted login page.
- Phone numbers are not available yet:
UserProfilehas no phone section. - Organization components (an organization switcher and profile) are not available yet.