@truesift/widget
v0.1.0
Published
Embeddable privacy-first TrueSift human verification widget with dotLottie-powered visual states.
Maintainers
Readme
@truesift/widget
Embeddable privacy-first TrueSift human verification widget with dotLottie-powered visual states.
Status
Version: 0.1.0
This package is the first public frontend widget package for TrueSift. It is intentionally frontend-only and framework-independent.
It can be embedded in:
- plain HTML pages;
- PHP websites;
- WordPress-rendered frontend pages;
- Next.js client components;
- React applications;
- landing pages and lead forms.
It does not require React, Next.js, MUI, Tailwind, Bootstrap, Emotion, Styled Components, or any other host UI framework.
Core rule
@truesift/widget renders the visitor-facing verification UI and talks only to the host website's own challenge and verify endpoints.
It must never receive, store, log, bundle, or transmit a TrueSift secretKey.
Allowed browser-side values:
challengeUrl
verifyUrl
action
path
origin
challengeId
challengeToken
clientSignals
visual stateForbidden browser-side values:
secretKey
admin shared secret
HMAC admin secret
server credentials
internal TrueSift API credentials
private TrueSift API URL as a default public targetThe required request path is:
Website page
-> @truesift/widget
-> website challenge endpoint
-> website verify endpoint
-> website backend / proxy
-> TrueSift APIFor WebDigiTech Website Check, the expected flow is:
Next.js UI
-> Next.js API proxy
-> Express backend
-> TrueSift API through @truesift/expressNo page component should call the Express backend directly.
Verification flow
The widget must not show success before the backend verify response is available.
The locked visual flow is:
No final backend verify result yet
-> loading visual state
-> Lottie marker: thinking / jump
Backend verify result: allow
-> verified_allow
-> Lottie marker: yes
Backend verify result: block
-> verified_block
-> Lottie marker: no
Backend verify result: review, error, timeout, unavailable, or unclear
-> verified_review / unavailable / error
-> Lottie marker: alertImportant:
challenge_ready is not success.
Success is shown only after verifyUrl returns a backend decision allow.The widget itself must not submit forms automatically. The host page decides whether to continue, retry, fail-open, or block a form action.
Installation
pnpm add @truesift/widgetCSS import
import '@truesift/widget/styles.css';The package also exports the stylesheet as:
@truesift/widget/truesift-widget.cssESM usage
import {
createTrueSiftWidget,
type TrueSiftWidgetState,
type TrueSiftVerifyResult,
} from '@truesift/widget';
import '@truesift/widget/styles.css';
const widget = createTrueSiftWidget({
container: '#truesift-widget',
challengeUrl: '/api/truesift/website-check/challenge',
verifyUrl: '/api/truesift/website-check/verify',
action: 'website_check',
path: '/website-check',
visualMode: 'banner',
theme: 'auto',
autoStart: true,
verifyMode: 'before-submit',
lottie: {
enabled: true,
type: 'dotlottie',
stateMachine: {
enabled: true,
},
},
onStateChange(state: TrueSiftWidgetState) {
console.log('[TrueSift] state:', state.status);
},
onVerified(result: TrueSiftVerifyResult) {
console.log('[TrueSift] verified:', result.decision);
},
});Script tag usage
Use the generated IIFE build when the widget is embedded without a bundler.
<link rel="stylesheet" href="/vendor/truesift/truesift-widget.css" />
<div id="truesift-widget"></div>
<script src="/vendor/truesift/truesift-widget.iife.js"></script>
<script>
window.TrueSift.init({
container: '#truesift-widget',
challengeUrl: '/api/truesift/website-check/challenge',
verifyUrl: '/api/truesift/website-check/verify',
action: 'website_check',
path: '/website-check',
visualMode: 'banner',
theme: 'auto',
autoStart: true,
verifyMode: 'before-submit',
lottie: {
enabled: true,
type: 'dotlottie',
stateMachine: {
enabled: true
}
}
});
</script>The default TrueSift Lottie animation is bundled into the widget build. A host page does not need to provide lottie.src for the standard TrueSift visual experience.
Use lottie.src only when the host application intentionally wants to override the bundled default animation.
Public API
createTrueSiftWidget(config)
createTrueSiftWidget(config: TrueSiftWidgetConfig): TrueSiftWidgetInstanceCreates and renders a widget instance.
window.TrueSift.init(config)
Available in script tag mode through the IIFE build.
window.TrueSift.init(config)Configuration
type TrueSiftWidgetConfig = {
container: string | HTMLElement;
challengeUrl: string;
verifyUrl: string;
action: string;
path: string;
origin?: string;
autoStart?: boolean;
verifyMode?: 'manual' | 'before-submit' | 'auto-after-ready';
visualMode?: 'banner' | 'badge' | 'inline';
theme?: 'auto' | 'light' | 'dark';
lottie?: TrueSiftLottieConfig;
labels?: Partial<TrueSiftWidgetLabels>;
onStateChange?: (state: TrueSiftWidgetState) => void;
onVerified?: (result: TrueSiftVerifyResult) => void;
onUnavailable?: (result: TrueSiftUnavailableResult) => void;
onError?: (error: TrueSiftWidgetError) => void;
};Lottie configuration
type TrueSiftLottieConfig = {
enabled?: boolean;
src?: string;
type?: 'dotlottie' | 'json';
autoplay?: boolean;
loop?: boolean;
stateMachine?: {
enabled?: boolean;
name?: string;
triggers?: Partial<TrueSiftLottieTriggerMap>;
};
fallback?: 'svg' | 'none';
};The default bundled dotLottie animation is embedded into the package and is used automatically when lottie.src is not provided.
The current first-release visual runtime uses dotLottie markers for stable animation control:
idle
thinking
jump
yes
no
alertThe widget maps verification states to the marker-based visual states:
loading_challenge -> thinking
challenge_ready -> thinking
collecting_signals -> thinking
verifying -> jump
verified_allow -> yes
verified_block -> no
verified_review -> alert
unavailable -> alert
error -> alert
expired -> alertThe state-machine trigger names are still supported as configuration semantics:
thinkClick
jumpClick
yesClick
noClick
alertClickThe Lottie layer is replaceable and isolated behind an adapter. The verification core must continue to work even when Lottie fails to load or when the user prefers reduced motion.
State model
The widget exposes a predictable finite state model:
idle
loading_challenge
challenge_ready
collecting_signals
verifying
verified_allow
verified_review
verified_block
unavailable
error
expired
destroyedThe host page should use this state to decide whether to enable submit, retry verification, allow fail-open behavior, or delay a form action.
The widget itself must not submit forms automatically.
Challenge contract
Request:
{
"path": "/website-check",
"action": "website_check",
"origin": "https://www.webdigitech.de"
}Expected response:
{
"success": true,
"data": {
"status": "challenge_created",
"enabled": true,
"mode": "observe",
"allowed": true,
"challengeId": "bg_challenge_...",
"challengeToken": "...",
"expiresAt": "2026-06-16T14:51:13.812Z"
}
}Verify contract
Request:
{
"challengeId": "bg_challenge_...",
"challengeToken": "...",
"path": "/website-check",
"action": "website_check",
"origin": "https://www.webdigitech.de",
"clientSignals": {
"elapsedMs": 4200,
"honeypotValue": ""
}
}Expected response:
{
"success": true,
"data": {
"status": "verified",
"enabled": true,
"mode": "observe",
"allowed": true,
"decision": "allow",
"challengeId": "bg_challenge_..."
}
}Client signals
The first release collects only lightweight, privacy-conscious signals:
type TrueSiftClientSignals = {
elapsedMs: number;
honeypotValue?: string;
interactionCount?: number;
focusCount?: number;
blurCount?: number;
pointerMoveCount?: number;
keypressCount?: number;
visibilityChanges?: number;
startedAt?: string;
verifiedAt?: string;
};The first release must not collect:
canvas fingerprint
audio fingerprint
installed fonts
browser plugins
exact device fingerprint
persistent cross-site identifiers
cookies
localStorage tracking id
third-party tracking id
precise geolocationPublic wording policy
The public UI must not expose raw risk language to visitors.
Do not use visitor-facing wording such as:
Bot detected
Blocked
High risk
Fraud scoreAcceptable wording:
Checking visitor signal…
Security check ready
Verification completed
Verification could not be completed
Please try againHost applications can override labels.
For WebDigiTech, German labels should be provided by the host application, not hardcoded into this package.
CSS variables
The widget uses prefixed CSS classes and CSS custom properties.
Supported variables:
--truesift-bg
--truesift-bg-soft
--truesift-border
--truesift-text
--truesift-muted
--truesift-accent
--truesift-success
--truesift-warning
--truesift-danger
--truesift-radius
--truesift-shadow
--truesift-animation-sizeClasses are prefixed with ts-widget to avoid global collisions.
Build output
Expected output:
dist/index.js
dist/index.d.ts
dist/truesift-widget.css
dist/truesift-widget.iife.jsThe default dotLottie animation is bundled inside the JavaScript build.
The npm package may still include exported asset files for debugging, fallback, or advanced host integrations, but the standard script-tag integration must not require an external dist/assets/truesift-shield.lottie path.
Development
pnpm install
pnpm typecheck
pnpm test
pnpm buildLocal output check
ls -la dist
find dist -maxdepth 2 -type f | sortExpected core files:
dist/index.d.ts
dist/index.js
dist/truesift-widget.css
dist/truesift-widget.iife.jsOptional files depending on build settings:
dist/index.js.map
dist/truesift-widget.iife.js.map
dist/assets/truesift-shield.json
dist/assets/truesift-shield.lottiePre-publish checklist
Before publishing 0.1.0, verify:
pnpm typecheck
pnpm test
pnpm build
npm pack --dry-runThe first public package should be published only after a local WebDigiTech Website Check integration test passes.
Not included in v0.1.0
The first release does not include:
React-specific package
WordPress plugin
admin dashboard
payment/pricing logic
direct TrueSift API browser mode
complex fingerprinting
CAPTCHA puzzles
user accounts
analytics dashboard
visitor-facing risk score
visitor-facing bot/block languageAnimation Asset Attribution
The bundled TrueSift Lottie animation is based on an asset by Maxence Chanel.
License: Free to use under the Lottie Simple License.
Repository documentation screenshot:
docs/assets/lottie-source-maxence-chanel.pngThe animation is bundled inside the TrueSift widget package and used only as a visual verification state indicator.
The screenshot is intended for repository documentation only and should not be included in the npm package files.
License
Source code and package implementation:
Proprietary WebDigiTech package.
See LICENSE.Third-party animation asset:
Author: Maxence Chanel
License: Free to use under the Lottie Simple License
Usage: bundled visual asset for TrueSift verification states
Repository screenshot: docs/assets/lottie-source-maxence-chanel.pngA final public open-source license may be selected later. Until then, the package source code and implementation remain proprietary to WebDigiTech.
