Overview
The useBioKey hook provides a complete React interface for biometric authentication. It manages the BioKeyClient instance, handles state management, and provides methods for enrollment, authentication, and identity management.
Import
import { useBioKey } from 'biokey-react'
Usage
import { useBioKey } from 'biokey-react'
function App () {
const {
identity ,
status ,
error ,
isEnrolled ,
isLoading ,
enroll ,
authenticate ,
reset
} = useBioKey ({
rpId: 'example.com' ,
rpName: 'My App' ,
serverUrl: 'https://api.example.com'
})
return (
< div >
{ isEnrolled ? (
< button onClick = { () => authenticate ( 'user-123' ) } disabled = { isLoading } >
{ isLoading ? 'Authenticating...' : 'Authenticate' }
</ button >
) : (
< button onClick = { () => enroll ( 'user-123' ) } disabled = { isLoading } >
{ isLoading ? 'Enrolling...' : 'Enroll Biometric' }
</ button >
) }
{ error && < p style = { { color: 'red' } } > { error } </ p > }
</ div >
)
}
Parameters
The hook accepts an optional options object that is passed directly to the BioKeyClient constructor.
Configuration options for the BioKeyClient instance Relying Party identifier. Defaults to location.hostname. This must match the domain where your app is hosted. useBioKey ({ rpId: 'example.com' })
Human-readable name for your application. Defaults to 'BioKey'. This name appears in the browser’s authentication prompt. useBioKey ({ rpName: 'My Application' })
Base URL for your BioKey server. If provided, the hook will sync enrollment and authentication with the server. Defaults to null (client-only mode). useBioKey ({ serverUrl: 'https://api.example.com' })
Return Value
The hook returns an object with state values and methods:
The current enrolled identity. Contains credential information if a user has enrolled, otherwise null. Hex-encoded derived public key from the biometric credential
Hex-encoded WebAuthn credential ID
Device fingerprint identifier
Timestamp when the credential was enrolled (milliseconds since epoch)
Key derivation method used ('prf' for PRF extension, 'rawid' for fallback HKDF)
Current operation status. One of:
'idle' - No operation in progress
'enrolling' - Enrollment in progress
'enrolled' - Enrollment completed successfully
'authenticating' - Authentication in progress
'authenticated' - Authentication completed successfully
'error' - An error occurred
Error message if an operation failed, otherwise null
Convenience boolean indicating if a credential is enrolled (!!identity)
Convenience boolean indicating if an operation is in progress (status === 'enrolling' || status === 'authenticating')
enroll
(userId?: string) => Promise<object>
Function to enroll a new biometric credential. See Hooks API for details.
authenticate
(userId?: string) => Promise<object>
Function to authenticate using the enrolled credential. See Hooks API for details.
Function to clear the stored identity and reset state. See Hooks API for details.
Complete Example
Here’s a complete authentication component with error handling and state management:
import { useBioKey } from 'biokey-react'
import { useEffect } from 'react'
function BiometricAuth ({ userId , onAuthenticated }) {
const {
identity ,
status ,
error ,
isEnrolled ,
isLoading ,
enroll ,
authenticate ,
reset
} = useBioKey ({
rpId: 'myapp.com' ,
rpName: 'My Secure App' ,
serverUrl: 'https://api.myapp.com'
})
const handleEnroll = async () => {
try {
const result = await enroll ( userId )
console . log ( 'Enrolled successfully:' , result )
} catch ( err ) {
console . error ( 'Enrollment failed:' , err )
}
}
const handleAuthenticate = async () => {
try {
const result = await authenticate ( userId )
console . log ( 'Authenticated:' , result )
onAuthenticated ( result )
} catch ( err ) {
console . error ( 'Authentication failed:' , err )
}
}
const handleReset = () => {
if ( confirm ( 'Remove your biometric credential?' )) {
reset ()
}
}
useEffect (() => {
if ( status === 'authenticated' ) {
console . log ( 'User authenticated with public key:' , identity . publicKey )
}
}, [ status , identity ])
return (
< div >
< h2 > Biometric Authentication </ h2 >
{ error && (
< div style = { { color: 'red' , padding: '10px' , marginBottom: '10px' } } >
Error: { error }
</ div >
) }
< div style = { { marginBottom: '10px' } } >
< strong > Status: </ strong > { status }
</ div >
{ identity && (
< div style = { { marginBottom: '10px' } } >
< strong > Enrolled: </ strong > {new Date ( identity . enrolledAt ). toLocaleString () } < br />
< strong > Method: </ strong > { identity . method } < br />
< strong > Device: </ strong > { identity . deviceId }
</ div >
) }
< div style = { { display: 'flex' , gap: '10px' } } >
{ ! isEnrolled ? (
< button
onClick = { handleEnroll }
disabled = { isLoading }
style = { { padding: '10px 20px' } }
>
{ isLoading ? 'Enrolling...' : 'Enroll Biometric' }
</ button >
) : (
<>
< button
onClick = { handleAuthenticate }
disabled = { isLoading }
style = { { padding: '10px 20px' } }
>
{ isLoading ? 'Authenticating...' : 'Authenticate' }
</ button >
< button
onClick = { handleReset }
disabled = { isLoading }
style = { { padding: '10px 20px' } }
>
Remove Credential
</ button >
</>
) }
</ div >
</ div >
)
}
export default BiometricAuth
State Management
The hook automatically manages state for you:
Initial Load : On mount, the hook reads any existing identity from localStorage and initializes the status to 'idle'
Enrollment : When enroll() is called, status changes to 'enrolling', then 'enrolled' on success or 'error' on failure
Authentication : When authenticate() is called, status changes to 'authenticating', then 'authenticated' on success or 'error' on failure
Reset : When reset() is called, identity is cleared and status returns to 'idle'
Errors : Any errors are caught and stored in the error state, and the status changes to 'error'
Error Handling
The hook provides multiple ways to handle errors:
Using the error state
const { error , status } = useBioKey ()
if ( status === 'error' && error ) {
return < div > Error: { error } </ div >
}
Using try-catch
const { enroll } = useBioKey ()
try {
await enroll ( 'user-123' )
} catch ( err ) {
// Handle error
console . error ( 'Enrollment failed:' , err . message )
}
Common errors
"No enrolled credential. Call enroll() first." - Attempted to authenticate without enrolling first
"PRF key mismatch — identity verification failed." - Biometric verification failed (wrong user)
"Server verification failed." - Server rejected the authentication
Browser errors - WebAuthn API errors (user cancelled, no biometrics available, etc.)
Client Instance Stability
The hook uses useRef to maintain a stable BioKeyClient instance across re-renders. The client is only created once when the component first mounts, ensuring that:
Configuration options are applied consistently
Local storage operations remain stable
Multiple hook calls in the same component tree share the same client instance
Best Practices
Pass options on first render : The options object is only used when creating the client instance. Changing options after mount will not affect the client.
Handle loading states : Always disable UI elements when isLoading is true to prevent duplicate operations.
Store userId separately : The hook does not store the userId - you must manage this in your application state and pass it to enroll() and authenticate().
Server URL is optional : If you omit serverUrl, the hook works in client-only mode with credentials stored in localStorage.
Next Steps
Hooks API Reference Detailed reference for all methods and state values
React Integration Guide Complete guide for integrating BioKey in React apps
BioKeyClient Learn about the underlying client class
Examples See full React application examples