Skip to main content

Face Camera

The Face Camera component provides a live face capture experience with real-time feedback and automatic capture.

Properties​

Core Properties​

  • isOpen: Boolean
    Starts or stops the camera. Automatically set to false after capture or error — except when the preview screen (showPreviewScreen, opt-in) is enabled and the user chooses "Take another photo", in which case the camera restarts internally and isOpen stays true.

  • deviceId: String
    Specifies the ID of the camera device to use. The component validates that the provided value matches an available video input. If invalid or omitted, the default/front-facing camera is selected.

  • initializationTimeoutDuration: Number (milliseconds)
    How long the component waits for initialization to finish before timing out. Default: 30000 (30s). If initialization is not completed within this period, a timeout error is raised and the camera fails to start.

  • autoCaptureTimeoutDuration: Number (milliseconds)
    How long the component waits after initialization for an automatic face capture before timing out. Default: 60000 (60s). When the timeout expires, an auto-capture error (code 4) is dispatched and the camera closes automatically. Set to 0 to disable.

  • showBackButton: Boolean
    Controls the visibility of the back button used to exit the camera. Default: true.

  • enableOrientationLock: Boolean
    If true, the component attempts to lock the screen orientation to portrait on supported devices/browsers. Default: false.

  • showPreviewScreen: Boolean
    Controls whether the post-capture preview screen (review/retake) is shown before dispatching capture. When false (the default), capture dispatches immediately after a photo is taken, matching this component's behavior prior to ZIM-971. Opt in per integration — coordinate with your team before enabling, since it changes when capture/close fire. Default: false.

Detection Feedback​

  • hints: FaceDetectionHint
    Customizes user guidance messages used by detection feedback. Any fields you omit fall back to sensible defaults.

  • detectionState: FaceDetectionState (read-only)
    Indicates the current detection state. Useful for custom UI logic.

  • detectionText(faceState): Function
    Returns the human-readable guidance message for the provided FaceDetectionState, applying your hints and defaults.

  • isInPreview: Boolean (read-only)
    Indicates whether the component is currently showing a captured image preview.

Text Customization​

The Face Camera component supports text customization for internationalization, branding, and accessibility. Customer feedback during the v11 → v2.0.x migration showed that listing keys without describing how each one is applied at runtime is not enough. The reference below categorizes every supported key by runtime behavior, so you can map UI copy, ARIA labels, and screen-reader-only announcements without inspecting the SDK source.

Customization Objects​

The component exposes four objects, each with its own purpose:

ObjectPurposeStatus
uiTextsUser-facing copy and orientation-related text keys (recommended).Current
textsAlternative way to supply user-facing copy. Covers the same subset as the FaceTexts type — note this subset does not include landscapeButtonAriaLabel.Current (alternative)
ariaLabelsARIA labels for interactive controls (backButton, forcePortraitMode). Recommended for accessibility overrides.Current
accessibilityTextsLegacy accessibility strings, kept for backward compatibility.Legacy

Precedence for visible/user-facing copy:

uiTexts  →  texts  →  accessibilityTexts (legacy)  →  Component defaults

Precedence for the back button ARIA label (.backButton):

ariaLabels.backButton  →  accessibilityTexts.backButtonAriaLabel  →  Default

Precedence for the force-portrait button ARIA label:

ariaLabels.forcePortraitMode  →  uiTexts.landscapeButtonAriaLabel  →  Default

uiTexts.landscapeButtonAriaLabel applies only to the force-portrait button. It does not affect the back button.

Key Reference — Categorized by Runtime Behavior​

Each customization key falls into exactly one category below:

CategoryWhat it means at runtime
Visible UI copyRendered as visible text in the active flow.
ARIA labelRendered as an aria-label on an interactive control. Not visible.
Screen-reader-only textRendered inside an aria-live / .sr-only region. Not visible.
Error event textUsed as the message field of a FailureEvent. Not rendered in the UI.
Unreachable / backward-compatibleExists in the API for backward compatibility but is bound only inside a DOM region that the supported customer flow never reaches.
uiTexts keys​
KeyCategoryWhere it renders / when it applies
faceInstructionVisible UI copyPrimary "place your face" guidance in the portrait flow. Recommended for that text.
landscapeTitleVisible UI copyTitle of the landscape orientation overlay (mobile landscape).
landscapeSubtitleVisible UI copySubtitle of the landscape orientation overlay.
landscapeButtonLabelVisible UI copyVisible label of the "force portrait" button. Renders only when enableOrientationLock is true and the browser/device supports screen.orientation.lock().
landscapeButtonAriaLabelARIA labelaria-label of the "force portrait" button. Does not affect the back button. Note: this key exists only on uiTexts, not on texts (it is not part of the FaceTexts type).
orientationErrorMessageError event textUsed as the message of the FailureEvent dispatched when a capture attempt is blocked because the device is mobile + landscape (shouldBlockCapture: isMobile && isLandscape). Not rendered as overlay copy.
deviceOrientationTextScreen-reader-onlyInside <div aria-live="polite" class="sr-only">. Announced by screen readers (e.g. heard in TalkBack when rotating).
landscapeOrientationTextScreen-reader-onlySame SR-only region as above, when device is in landscape.
portraitOrientationTextScreen-reader-onlySame SR-only region as above, when device is in portrait.
step1Title, step1DescriptionUnreachable / backward-compatibleBound in a sidepanel element that only becomes visible under @media (orientation: landscape) for .sidepanel.mobile. Mobile landscape capture is blocked by design (biometric quality), and the landscape orientation overlay renders above the sidepanel. The text is in the DOM but never visible in any supported customer flow. Use uiTexts.faceInstruction for the visible "place your face" guidance.
step2Title, step2DescriptionUnreachable / backward-compatibleSame as above.
step3Title, step3DescriptionUnreachable / backward-compatibleSame as above.
ariaLabels keys​
KeyCategoryWhere it applies
backButtonARIA labelaria-label of the back button. Recommended way to override it.
forcePortraitModeARIA labelaria-label of the force-portrait button. Takes precedence over uiTexts.landscapeButtonAriaLabel.
accessibilityTexts keys (legacy)​
KeyCategoryNotes
backButtonAriaLabelARIA label (legacy)Legacy fallback for the back button. Use ariaLabels.backButton instead in new integrations.
placeYourFaceTextVisible UI copy (legacy)Legacy fallback for the "place your face" guidance. Use uiTexts.faceInstruction instead.
capturedPhotoTextVisible UI copy (supported)Visible confirmation text shown on successful capture. There is no uiTexts equivalent, so accessibilityTexts.capturedPhotoText is the current supported customization path for this string. This key lives on accessibilityTexts for historical reasons; despite the object being marked "legacy", this specific key is the supported way to override the captured-photo confirmation.

Orientation Keys — Quick Visibility Reference​

The orientation-related keys span four categories. This is the single most common source of confusion during migration:

KeyVisible?Notes
landscapeTitle, landscapeSubtitleVisible in the landscape overlayMobile landscape only.
landscapeButtonLabelVisible only if enableOrientationLock + lock supportedOtherwise the button is not rendered.
landscapeButtonAriaLabelNot visiblearia-label of the force-portrait button (not the back button).
deviceOrientationText, landscapeOrientationText, portraitOrientationTextNot visible — screen-reader announcement onlyHeard in TalkBack/VoiceOver when the device rotates.
orientationErrorMessageNot visible — error event messageSurfaces in the FailureEvent.detail.error.message when capture is blocked on mobile-landscape.

v11 → v2.0.x Migration Mapping​

If you are migrating from WebSDK v11, use this mapping to move existing customizations to the v2.0.x API:

v11 / pre-migration keyv2.0.x recommendedNotes
Visible "place your face" guidanceuiTexts.faceInstructionPrimary visible instruction in the portrait flow.
Back-button screen-reader labelariaLabels.backButtonaccessibilityTexts.backButtonAriaLabel is still supported as legacy fallback.
Force-portrait button visible labeluiTexts.landscapeButtonLabelRenders only when enableOrientationLock is true and lock is supported.
Force-portrait button ARIAariaLabels.forcePortraitModeuiTexts.landscapeButtonAriaLabel is consulted next for this button.
Orientation overlay title/subtitleuiTexts.landscapeTitle, uiTexts.landscapeSubtitleVisible in landscape overlay.
Orientation screen-reader announcementsuiTexts.deviceOrientationText, landscapeOrientationText, portraitOrientationTextSR-only.
Mobile-landscape capture-blocked messageuiTexts.orientationErrorMessageUsed as the FailureEvent message.
Captured-photo confirmation textaccessibilityTexts.capturedPhotoTextNo uiTexts equivalent. Supported via accessibilityTexts.
step1Title–step3DescriptionNot needed in the supported flowThese keys remain in the API for backward compatibility but are unreachable. Use uiTexts.faceInstruction for the visible guidance.

Example — Full Customization​

const liveFaceCamera = document.getElementById('live-face-camera');

// Visible UI copy and orientation-related text.
liveFaceCamera.uiTexts = {
faceInstruction: 'Place your face within the oval',
landscapeTitle: 'Turn your phone upright',
landscapeSubtitle: 'Please rotate your device to portrait to take a selfie',
landscapeButtonLabel: 'Force Portrait Mode',
landscapeButtonAriaLabel: 'Force portrait mode',
orientationErrorMessage:
'Face authentication requires portrait mode. Please rotate your device and try again.',
deviceOrientationText: 'Device orientation:',
landscapeOrientationText: 'landscape',
portraitOrientationText: 'portrait'
};

// ARIA labels for interactive controls.
liveFaceCamera.ariaLabels = {
backButton: 'Go back',
forcePortraitMode: 'Force portrait mode'
};

// Captured-photo confirmation — no uiTexts equivalent exists.
liveFaceCamera.accessibilityTexts = {
capturedPhotoText: 'Photo captured successfully'
};

Text Precedence Example​

liveFaceCamera.uiTexts = { faceInstruction: 'Center your face' };
liveFaceCamera.texts = { faceInstruction: 'Look straight ahead' };

// Rendered: "Center your face" — uiTexts wins over texts.

Preview Screen Customization​

previewScreenTexts and previewScreenAriaLabels are independent of the objects above — they only customize the post-capture preview screen controlled by showPreviewScreen, not the live-capture flow.

  • previewScreenTexts: Object
    Overrides the post-capture preview screen (shown after a selfie is taken, before the result is returned). Recognized keys:

    • title
    • body
    • photoAltText
    • continueButtonText
    • retakeButtonText
  • previewScreenAriaLabels: Object
    Supplies ARIA labels for the preview screen's buttons, independent of previewScreenTexts. Recognized keys:

    • continueButton
    • retakeButton
liveFaceCamera.previewScreenTexts = {
title: 'Check the preview of your selfie',
body: 'Check the photo of your selfie is clear, in focus and directly face on.',
photoAltText: 'Preview of your captured selfie',
continueButtonText: 'Continue',
retakeButtonText: 'Take another photo'
};

liveFaceCamera.previewScreenAriaLabels = {
continueButton: 'Continue',
retakeButton: 'Take another photo'
};

Lifecycle Overview​

The Face Camera component follows a well-defined lifecycle from initialization through capture to closure. Understanding this flow helps you implement proper event handling and state management.

Face Camera Lifecycle

Key Lifecycle Stages:

  1. beforeInitialize: Preparation phase before SDK loads
  2. initialize: SDK models loaded and ready
  3. beforeOpen: Camera access requested
  4. open: Camera feed active (WebRTC established)
  5. detection: Continuous face detection loop with real-time feedback
  6. beforeCapture: Face validation passed, capture initiated
  7. capture: Image captured and encrypted
  8. preview (optional, opt-in): The user reviews the captured selfie, with the option to Continue or Take another photo. Only happens when showPreviewScreen is set to true — see the Core Properties section.
  9. close: Camera released and resources cleaned up (always emitted)

Events​

  • BeforeInitializeEventName
    Dispatched before initialization begins (no models loaded yet). Useful to prepare UI state or start timers.

  • InitializeEventName
    Dispatched when the component is initialized and ready.

  • BeforeOpenEventName
    Dispatched when the camera begins to open.

  • OpenEventName
    Dispatched when the camera is fully open.

  • DetectEventName
    Dispatched on each detection. detail.errors contains an array of detection issues (if any).

  • BeforeCaptureEventName
    Dispatched when the capture process begins.

  • CaptureEventName
    Dispatched on successful capture. detail includes:

    • imageBase64: Base64-encoded image string.
    • encryptedFile: Encrypted Blob for verification.
  • CloseEventName
    Dispatched when the camera closes. This event is always emitted, regardless of how the camera session ends (successful capture, user cancellation, error, or timeout). After a successful capture, the capture event is dispatched first, followed by the close event. When the preview screen is enabled (showPreviewScreen: true, opt-in), close additionally waits for the user's Continue decision — choosing "Take another photo" instead restarts the capture session internally without ever dispatching capture or close.

  • UserCanceledEventName
    Dispatched when the user taps the back arrow to exit the camera without capturing an image. The close event is dispatched after this event.

  • FailureEventName
    Dispatched on error. detail.error is of type FaceCameraError. The close event is dispatched after this event.

Error Codes​

FaceCameraError.code identifies what failed. Branch on the code, and surface message when you need the underlying cause.

CodeMeaningTypical cause
1Camera permission was denied.The user declined the camera prompt, or the page is not in a secure context.
2An unexpected failure was reported. message retains the underlying provider text after an SDK-added prefix.Anything the capture provider reports that is not a permission denial — a licensing failure, a busy camera, or a device that cannot run face detection (for example a browser whose WebGL stack rejects the detector's shaders).
3Face detection did not start before initializationTimeoutDuration elapsed.The detector never became ready. This is not a permissions problem — the camera prompt has already been answered by this point.
4Auto-capture did not complete before autoCaptureTimeoutDuration elapsed.No acceptable frame was captured in time.

Message Format​

message is not the raw underlying text. Every code except 1 prepends a fixed prefix, so match on code rather than parsing message, and strip the prefix if you surface the text to end users.

Codemessage format
1the underlying text, with no prefix
2Unexpected error: + the underlying text
3Timeout error: + the reason
4Auto-capture timeout: + the reason

Do not treat code 2 as a permission problem. Only code 1 indicates that camera access was refused; prompting the user to grant permissions in response to any other code sends them to a setting that is already correct.

Code 1 is best-effort when the denial comes from inside the capture provider: the provider reports every failure through a single channel that carries only a message string, so the classification matches the wording browsers use for a denied getUserMedia call. If your integration needs certainty, call navigator.mediaDevices.getUserMedia yourself before setting isOpen, and handle the rejection directly — the demo app takes this approach.

Type Definitions​

type FaceDetectionHint = {
notInitializedHint?: string;
initializingHint?: string;
faceNotFoundHint?: string;
tooManyFacesHint?: string;
faceAngleTooLargeHint?: string;
probabilityTooSmallHint?: string;
faceTooSmallHint?: string;
faceCloseToBorderHint?: string;
};

enum FaceDetectionState {
NotInitialized = 'NOT_INITIALIZED',
FaceNotFound = 'FACE_NOT_FOUND',
TooManyFaces = 'TOO_MANY_FACES',
FaceAngleTooLarge = 'FACE_ANGLE_TOO_LARGE',
ProbabilityTooSmall = 'PROBABILITY_TOO_SMALL',
FaceTooSmall = 'FACE_TOO_SMALL',
FaceCloseToBorder = 'FACE_CLOSE_TO_BORDER',
}

type FaceCameraError = {
code: number;
message: string;
};