Every published release of the Incode Web SDK 2.x packages, newest first.
@incodetech/core and @incodetech/web are versioned in lock-step — a given release number always
refers to both packages, and they must be installed at matching versions. New integrations should
start from Getting Started.
npm install @incodetech/web@latest @incodetech/core@latest
Info
Looking for Web SDK 1.x? Its release notes are on
Web SDK Release Notes. The 1.x
(@incodetech/welcome) and 2.x package lines are versioned independently.
2.2.0 — 2026-08-21
Added
- Asset overrides — replace the built-in SVG illustrations and Lottie animations by key. Set
assetsandanimationsonUiConfigglobally, or onFlowConfigand any module component'sconfigfor one element; per-instance wins over global wins over the built-in default. An override takes a URL, raw SVG markup, a precompiled SVG component, or Lottie JSON, and falls back to the default if it fails. Accessibility metadata always comes from the SDK, not your input. New types:AssetKey,AnimationKey,AssetOverride,AnimationOverride,AssetOverrides,AnimationOverrides,SvgComponent. See Asset Overrides. - Loader presentation control —
spinner?: SpinnerPresentationonUiConfigglobally, and onFlowConfig,WorkflowComponentConfig, and any module component'sconfigper instance. It carriesrenderMode('spinnerAndText' | 'spinnerOnly' | 'textOnly') andsize. One global setting now reaches module-internal loaders — ID camera preparation, camera permissions — that a flow-level setting never reached. New types:SpinnerConfig,SpinnerPresentation,SpinnerRenderMode. - Feature management —
setup({ featureManagement, environment })lets the SDK evaluate Incode-managed feature gates, experiments, layers, and parameter stores. Enabled by default; passfeatureManagement: falseto skip it, and no third-party code is fetched. Identity is anonymous by default — no API key is sent, the stable device ID and cross-page persistence are off, andipandcountryare redacted. Configure withclientExperimentId,disableStableId,disablePersistence,custom,appVersion, andredactedUserInfo. Reads live on@incodetech/core/feature-managementand never throw — they fall back to the default you pass. This adds the Statsig browser client, loaded lazily and only when enabled. See Third-Party Dependencies. setup({ trueSight: { enabled: false } })opts the session out of Incode SDK-health diagnostics, which are enabled by default.setup({ flow })andsetup({ theme })control what a standalone module loads up front.flow: falseskips flow prefetch and config merging,flow: { preload, mergeConfig }enables each on its own;theme: falsedisables the session theme,theme: { preload: true }fetches it duringsetup(). See Individual Modules.- US Smart Capture reads the ID barcode end-to-end, matching 1.x. On-device barcode scanning runs alongside back-of-ID capture, and a back-only US ID can skip front capture, ID processing, and Face Match. If no barcode is read, capture falls back to the normal back-of-ID upload. See ID Capture.
- Document Capture gains an
onlyPdfflag that restricts uploads to PDF files, plus method-selection and common-issues screens. See Document Capture. - Dynamic Forms gains prefill and login-hint handling. See Dynamic Forms.
prefillValueonDynamicFormsConfig, andloginHintPrefillonFlowBaseConfigandWorkflowBaseConfig, seed the single answer of a one-screen, one-question form — a login hint your page reads from a URL parameter, for example. The field stays editable, and a multi-field form is never touched.- A question with
prefillSourceis populated from the customer's captured ID.QuestiongainsprefillSourceandeditable, and theinputtingandsubmittingstates gainprefilledQuestionIdsandnonEditableQuestionIds. Non-editable prefilled fields render read-only with a "from ID" marker and still submit.PHONEandMULTISELECTare excluded; an unresolved value stays blank and editable. - An invalid login hint shows an inline field error so the customer retries in place. Exhausted
attempts park the module on a terminal screen, adding
attemptsExhaustedtoDynamicFormsState.
- Geolocation gains
maxAttempts(default3),retry()andquit()manager methods, anderrorandnoNetworkstates. Device failures no longer all report as permission denied — a timeout or unavailable position now routes to a retryable screen.@incodetech/web/extensibilityexports a sharedConnectionErrorscreen. See Geolocation. - Headless ID capture can render the optimizing phase. Declare
IdCaptureConfig.supportsOptimizingStatuswhen you rendercaptureStatus === 'optimizing'fromcandidateImageUrl ?? previewImageUrl.'optimizing'joins thecaptureStatusunion, and capture state gainscandidateImageUrl(display only) andoptimizingDwellMs. Leave the flag unset and the phase never runs. See Headless Mode. @incodetech/web/government-validationand its/styles.csssubpath export, so the module can be imported standalone like the others. See Individual Modules.- Design system (
@incodetech/web/extensibility):PasswordInputComposed, a password field with a show/hide toggle and an optional requirements checklist you supply results for; aninvalidprop onInputComposedthat setsaria-invalidwithout a message; andtextSize('M' | 'S') onRadioButtonComposed. --input-surface-hoverand--dropdown-surface-hovertokens drive the hover state on inputs and dropdowns. See Theming and Styling.
Changed
captureModesemantics changed in Document Capture.'camera'is now capture-only, where it previously offered both. OmitcaptureModeto keep capture plus upload with a method selector.'file'remains upload-only. See Document Capture.- Selfie and Authentication concealment uses one field.
selfieConcealmentOption('OPTION_NONE' | 'OPTION_SILHOUETTE' | 'OPTION_2D' | 'OPTION_3D') onBaseFaceCaptureConfigand theSELFIE/AUTHENTICATIONflow config replacesobfuscateWithAvatarandavatarVariant. Flows and workflows read it from your dashboard node configuration; standalone integrations set it directly. The avatar stays cosmetic — detection, quality, liveness, and upload run on the real frames. - Face Match is skipped when the ID has no front portrait. Under US Smart Capture, a back-only ID gives nothing to compare, so Face Match self-completes rather than running a match that cannot succeed. Flow and workflow now agree. Selfie capture is unaffected.
PermissionStatusgained'checking', distinct from'idle'. If you switch exhaustively on it, render nothing for'checking'. Reading the value needs no change.- Two CSS class names are namespaced:
SignatureCanvas*→IncodeSignatureCanvas*, andImageDocumentCapturePdfPreview*→IncodeImageDocumentCapturePdfPreview*. Update your selectors if you target either. See Theming and Styling. documentCapture.*analytics screen names were realigned. Re-check your mappings against Dashboard Events if you key logic off screen names.- Dynamic Forms and CURP Validation desktop layouts put fields in a contained scroll region with the button in a fixed footer, matching ID OCR and eKYB. Mobile is unchanged. Dynamic Forms no longer submits on Enter, also matching ID OCR and eKYB.
- A non-repeatable flow whose session already finished no longer starts. It shows the localized
finished-session screen and reports
SESSION_FINISHEDthrough the flow error callback. - Video Selfie follows the current design end to end. ID capture starts detecting immediately,
wrong-side and success feedback render in the frame, camera switches get a full-screen transition,
and the final screen releases camera and microphone first. The recording manager exposes
flippingIdandsuccess. Each step allows three validation attempts; exhausting an ID side skips the remaining ID steps. Camera, network, and upload failures no longer consume an attempt or end the recording — callmanager.retry(). See Video Selfie. - Video Selfie errors and uploads are more resilient. Error screens show translated copy instead of
raw network detail, with the raw message kept on
state.error. The recording streams in retried chunks, so an interruption salvages all but the final seconds. A failed selfie upload retries in place, then re-runs only the selfie step inside the same recording. - Redirect to Mobile applies a 30-second cooldown before an SMS link can be resent, and shows an error state when sending fails. See Redirect to Mobile.
Fixed
- Camera permission is no longer requested on every capture module inside an Android WebView. A WebView has no persistent permission store, so the "allow camera" screen reappeared before each module even though no system prompt followed. The screen also no longer flashes during a permission check. iOS WebKit and Firefox for Android genuinely re-prompt, so they are unchanged.
- The published stylesheets no longer style your page. Unscoped utility selectors (
.flex,.container,.rounded) collided with integrator design systems; every published selector is now anchored to an Incode-namespaced class, attribute, or element, enforced by a build check. Dead CSS goes with it —base.cssdrops from 464 KB to 392 KB,flow/styles.cssfrom 256 KB to 156 KB. See Bundle Optimization. - Three stylesheet subpaths resolved to files that were never built. Importing
@incodetech/web/signature/styles.css,.../electronic-signature/styles.css, or.../qe-signature/styles.cssfailed in every bundler, as the module docs instruct. All three resolve now, and the electronic-signature family shares one stylesheet. No import path changed. config.onlyFrontreaches the backend. The ID module dropped it silently. It is now sent on the front upload, and the SDK honors the answer —onlyFrontis a statement about the document that the server may decline, so a two-sided document still asks for the back, passports included. Use your dashboard's front-only configuration to force front-only capture. Manual upload hides the back slot after the front file alone, matching 1.x. See ID Capture.- Global asset and animation overrides were silently discarded by
<incode-flow>,<incode-workflow>, and standalone modules. An override that fails at runtime now falls back to the built-in default instead of rendering blank, URLs are validated, and unknown keys warn in development. - ID Capture: capture works in Firefox for Android; the frame and preview respect a detected
passport's orientation; "Unable to process" appears when Document Capture attempts are exhausted; and
the selfie Age Assurance notice appears even when
showTutorialisfalse, since that copy doubles as the age-estimation privacy notice. - Preview mirroring follows the camera actually opened, via a new
usingBackCameracapture-state flag rather than the staticassistedOnboardingconfig. A desktop without a rear camera now shows a mirrored front-camera view; mobile keeps the unmirrored rear view. - Privacy Lens and the 2D avatar are usable on low-tier devices. They render in a dedicated worker on Chromium browsers, with an improved main-thread fallback elsewhere, and no longer judder during capture. Avatar initialization also works in webpack-bundled apps, where it previously always failed.
- Workflow: the launch "Get Started" screen reopens on desktop after leaving an injected Redirect to Mobile step, instead of jumping into the first module.
- Shared components: the error icon on inputs, checkboxes, radio buttons, and phone, date, and textarea fields returns to its intended size; loaders use the default light secondary spinner color again; a long localized camera-permission title no longer overlaps the desktop modal close button; and Face Match no longer scrolls the page during its animations.
- Accessibility (WCAG 2.2 AA) across Document Capture, Electronic Signature, Redirect to Mobile, and shared components: preview images and the PDF viewer gain accessible names and a real reading path; focus is restored across review states and after closing a document; camera pages expose landmarks and correct headings; help opens in a dialog that keeps assistive technology out of the background; consent links are underlined and meet contrast minimums; the phone field reports as required and identifies its autocomplete purpose; and searchable dropdowns expose their filter as an editable combobox.
- Antifraud and device-integrity hardening.
Deprecated
SpinnerConfig.titleandSpinnerConfig.subtitle. Set loader copy through theloadingCircle.*i18n translations instead — a literal string in config does not follow a runtime language change. Still honored in 2.2.0; removal targeted for 2.3.0. See Internationalization.
Removed
- The
CPF_OCRflow key and the@incodetech/core/cpf-ocr,@incodetech/web/cpf-ocr, and@incodetech/web/cpf-ocr/styles.csssubpath exports. CPF-only capture is part of ID OCR now: a flow usinguseCPFkeeps itsID_OCRstep, preserves its configuration, and enablescpfOnly. ImportformatCPFandisValidCPFfrom@incodetech/core/id-ocr. See ID OCR. state.debugFramefromSelfieState,AuthenticationState, andIdCaptureState. It was already alwaysundefined. If you need per-frame pipeline frames, contact us — a purpose-built, opt-in hook is the intended replacement.- The Geolocation manager's
reset()method and itsRESETevent. No state handled the event, so no behavior is lost, but drop the call if you make it.
Install: npm install @incodetech/web@2.2.0 @incodetech/core@2.2.0
2.1.1 — 2026-07-30
Changed
@incodetech/coreand@incodetech/webnow publish ISC license metadata and aLICENSEfile, so automated license scanners resolve the packages instead of rejecting them for missing license information. Metadata only — no API or runtime behavior changes.- Updated the bundled on-device processing runtime.
Fixed
- The SDK now initializes on hardened hosts and in webviews where Web Storage is unavailable — removed, blocked, or replaced. Values that cannot be persisted are skipped and reads fall back to defaults, instead of the SDK failing to start.
- Antifraud, device-integrity, and anti-injection hardening.
Install: npm install @incodetech/web@2.1.1 @incodetech/core@2.1.1
2.1.0 — 2026-07-10
Added
- Certificate Issuance module (
CERTIFICATE_ISSUANCE) — password capture, digital certificate issuance, and download. Available ascreateCertificateIssuanceManagerfrom@incodetech/core/certificate-issuanceand as<incode-certificate-issuance>. See Certificate Issuance. - Fiscal QR module (
FISCAL_QR) — scans a Mexican fiscal (SAT) QR code, resolves its URL, and submits it for verification. - Field Comparison module (
FIELD_COMPARISON) — collects a first and last name and submits them for backend verification. - INE Validation (
INE_VALIDATION) — the Mexican government / INE check, available through the same manager and component as Government Validation. - ML Consent (
ML_CONSENT) — supported in both flows and workflows through the shared mandatory
consent module. - Video Selfie with local recording.
- Privacy Lens — an opt-in cosmetic avatar rendered in place of the live camera preview during selfie and authentication capture, with a reassurance banner above the capture frame. Detection, quality, liveness, and upload continue to run on the real camera frames; enable it from your dashboard configuration.
setup()gained options for controlling third-party dependencies and self-hosting:fingerprint: false— skips client-side device-fingerprint submission.ipLookup: false— skips the client IP lookup.i18n— supply your own i18n instance (@incodetech/web).wasm: { basePath }— serve the on-device processing assets from your own origin. See WASM Configuration.devModeandwasm: { showLogs }— development diagnostics. Do not enable in production.
extractIdFace: falseonIdCaptureConfigskips face extraction from the ID document, for flows that do not run a biometric comparison. See ID Capture.showFinishScreenBySessionStatuson the workflow configuration renders a finish screen specific to the resolved session status. See Workflow.- ID Capture and Face Capture emit new events:
errorTriggeredfor every front-end error state — capture and upload errors, expired document, offline or degraded network, and fatal errors — with an{ errorName, errorCode, reason }payload.backgroundandforegroundwhen the page's visibility changes during an active session, carrying the current screen. A session opened in an already-hidden tab reports it on start. See Event Callbacks.
- Form modules expose per-field validation.
validateField()on the manager triggers validation for a single field on blur, and avalidationErrorsmap on the state drives the displayed messages. Available on eKYC, eKYB, Dynamic Forms, ID OCR, and CURP Validation. - Flow and workflow failures now carry a machine-readable
moduleErrorCode, and Incode API error codes and messages are surfaced across the flow and workflow lifecycle. - A flow's
onFinishresult includes the end-screen texts configured in your dashboard. - eKYC renders phone and email fields when
riskAddonsare configured. - Dynamic Forms renders
YESNOquestions as a Yes/No dropdown. <incode-workflow>supports a self-loading mode.- Watchlist, Watchlist for Business, and Incode Watchlist nodes now resolve in workflows.
- Transactional Risk Intelligence (TRI) telemetry.
Changed
- Forms use optimistic validation. The Continue button starts enabled on each screen. Submitting with empty required fields reports every missing field at once and disables the button until they are corrected; typing clears the error for that field. Format errors (phone, email, CPF, CNPJ, SSN, postal code) report on blur. Applies to eKYC, eKYB, Dynamic Forms, ID OCR, the phone and email input screens, and the OTP code screens.
- Form state shape changed with it. If you read form state directly:
errorsis replaced byvalidationErrors, whose entries are{ key, params? }.submitAttemptedis removed — the state machine now writes errors for all invalid fields on submit, so no separate flag is needed to gate display.isValidandcanSubmitnow mean "no validation error is currently displayed" rather than "the form would pass validation". Existingdisabled={!isValid}bindings keep working under the new optimistic meaning.computeEkycDisplayErrorsandcomputeEkybDisplayErrorsare no longer exported; errors live entirely onstate.validationErrors.
- Authentication:
USER_IS_NOT_RECOGNIZEDis retryable up to the configured capture-attempt limit (default 3) and then advances the flow, matching Web SDK 1.x, instead of ending the session on the first failure. - When face authentication fails with an advanceable terminal error (
NONEXISTENT_CUSTOMER,HINT_NOT_PROVIDED), the orchestrator advances so the backend can route the customer to enrollment, rather than terminating. - A desktop-to-mobile handoff that finishes on mobile now completes the journey, instead of resuming the desktop session at the next module.
- Government Validation shows a loading spinner while a check is still in progress, replacing the success check mark that appeared prematurely.
- Manual capture is disabled when the Selfie or Authentication module runs with on-device face result submission enabled.
- Analytics screen names were realigned across modules and new typed module tokens added. If you key logic off screen names in tracked events, re-check your mappings against Dashboard Events.
- Consent and mandatory-consent copy is fetched in the active SDK language instead of always in English.
- Core JavaScript is minified, reducing bundle size. See Bundle Optimization.
- Default fonts are self-hosted with the package rather than fetched from a third-party CDN. See Third-Party Dependencies.
Fixed
- ID Capture: expired-ID retry handling restored to 1.x parity; the back-of-ID prompt is skipped
when the backend accepts a single-sided document even with
alwaysCaptureBackOfIdset; Continue buttons are labelled correctly on the front-ID success screen when no back scan is needed; the desktop preview is mirrored so on-screen movement matches the user;previewImageUrlis restored in the capture-only flow so the post-capture screen advances; the manual-capture tooltip no longer shifts the layout. - Manual ID upload: validation errors appear beneath the slot that failed instead of once at the bottom; uploaded slots survive switching between the ID and Passport tabs; images are normalized to JPEG before size validation; the quality-rejected error is no longer shown when the attempt was approved.
- Digital ID upload: an excluded country or unaccepted document shows the failure screen instead of silently continuing.
- Face Match: server-side face processing always runs before results are read; face match is
skipped and the flow continues when the session was captured with
extractIdFace: false; liveness snackbar labels are translated. - Selfie: the on-device selfie assets load reliably when a warm-up is already in flight.
- Custom Watchlist calls the custom watchlist endpoint. The global Watchlist module is unchanged.
- CURP Validation: the retry / manual-verify option is restored after a failed validation, and the verifying text is hidden while idle.
- Geolocation: an unresolvable location renders localized copy instead of a literal
"Unknown", and the desktop permission-denied screen is localized. - Electronic Signature: a session never associates more than one document; a signing error shows
for three seconds and then finishes; error states route correctly by backend error type; a
successful
signQesresponse is treated as success; the signature canvas border renders on iOS 14. - Field Comparison submits names in the shape the dashboard expects, so they appear on the session.
- Document Capture follows the camera-permission instructions before opening the camera, and PDFs render in an in-page viewer instead of a native embed that showed an OS-level "Open" button on iOS Safari and mobile Chromium.
- Workflow and Flow:
DYNAMIC_FORMSis registered and the flow advances when face-auth attempts are exhausted; the finish-status call is no longer issued on the desktop when the handoff completed on mobile; the active workflow node is used when fetching finish status, so hosts receive the completion redirect. - Redirect to Mobile: "Change phone number" works after an SMS resend hits the limit; a transient error no longer flashes on desktop right after the module loads.
- The finish-process screen shown while the session result resolves no longer renders a title-less spinner.
- Camera tracks are stopped explicitly at module transitions, and the rear camera is selected for back-camera capture on desktop and tablet devices.
- Language selection from the home-screen settings modal survives a page reload.
- A
TypeErrorno longer appears in the console immediately after a flow completes. - Standalone
@incodetech/webimports forredirect-to-mobile,cpf-ocr,document-capture, andfield-comparisonresolve correctly. See Individual Modules. - Street-level address selections are validated in eKYC and eKYB — choosing a city-level autocomplete result now reports that a street-level address is required.
- Accessibility (WCAG 2.2 AA) fixes across capture, forms, and shared components: error messages are programmatically associated with their fields; processing and transition screens announce once instead of exposing fragmented text; dropdowns announce as select-only comboboxes with their required and invalid state; buttons keep an accessible name while loading; modals move initial focus to the dialog heading; scroll containers are keyboard-operable; placeholder text meets contrast minimums; and the camera-permission "requesting" screen no longer announces behind the native OS prompt.
Install: npm install @incodetech/web@2.1.0 @incodetech/core@2.1.0
2.0.1 — 2026-05-18
Fixed
- Republished the 2.0.0 artifacts with their build output. Version 2.0.0 shipped without it and is
deprecated on npm — install
2.0.1or newer. - Digital ID upload: an excluded country or unaccepted document now shows the failure screen
instead of silently continuing the flow;
captureAttemptsis honored exactly, rather than allowing one extra attempt; the terminal "no more attempts" screen is rendered and waits for the customer before returning to the document chooser; and the analyzing screen's status announcement is no longer visible on screen.
Install: npm install @incodetech/web@2.0.1 @incodetech/core@2.0.1
2.0.0 — 2026-05-15
Initial general availability of Web SDK 2.0 — a ground-up rewrite distributed as the
@incodetech/core and @incodetech/web npm packages, replacing the 1.x
@incodetech/welcome script bundle.
Added
- Three integration paths from one package set: the
<incode-flow>drop-in component, an orchestrator driving individual module web components, and headless managers for fully custom UI. See Getting Started and Module Patterns. - Every consumer-facing module ships as a standard Web Component with its own CSS entry point, so it works in any framework. See Web Components and Framework Integration.
- Design-token theming, asset overrides, and internationalization. See Theming & Styling, Asset Overrides, and Internationalization.
- Full TypeScript types across the public API, and per-module entry points for bundle splitting. See TypeScript Types and Bundle Optimization.
Danger
Do not install 2.0.0. It was published without its build output and is deprecated on npm. Use
2.0.1 or newer.