Drop-in widget · Tier B1

Sign in with EU Wallet — one script tag

Add EU Wallet sign-in to any web page in about 30 seconds. The widget renders a branded button, opens a QR modal on click, polls the CodeB verifier for the wallet’s response, and fires a codeb:wallet-signed-in DOM event on the host page. No backend integration is required on your side beyond verifying the returned assertion server-side.

Live demo

Click the button below. A modal will open with a scannable QR pointing at the CodeB verifier on this domain.

Nothing wires the button to your app until you handle the event — the demo just prints the payload below.

Waiting for a wallet response…

Integration snippet (copy-paste)

<!-- 1. Placeholder where the button should render --> <div id="my-login" data-codeb-widget="signin" data-label="Sign in with EU Wallet"></div> <!-- 2. Load the widget from your CodeB verifier origin --> <script src="https://phone.aloaha.com/signin-widget.min.js" data-verifier="https://phone.aloaha.com" data-mode="signin" data-theme="auto" async defer></script> <!-- 3. Handle the callback and POST the assertion to your backend --> <script> window.addEventListener('codeb:wallet-signed-in', function(e) { var assertion = e.detail.assertion; var claims = e.detail.claims; console.log('Verified claims:', claims); // POST assertion to your server; verify it against the CodeB verifier // JWKS at https://phone.aloaha.com/.well-known/openid-configuration. }); </script>

Data attributes on the <script> tag

AttributeDefaultEffect
data-verifierhttps://phone.aloaha.comOrigin serving oidc.ashx. Set to your own tenant domain.
data-modesigninCurrently signin only. age-verify lands with the dedicated backend endpoint in the next iteration.
data-themeautolight, dark, or auto (follows the browser’s prefers-color-scheme).
data-debugfalseSet to true to see widget lifecycle in the browser console.

Data attributes on the placeholder <div>

AttributeEffect
data-codeb-widget="signin"Required. Marks the div for widget insertion.
data-labelOverride the button label (default: Sign in with EU Wallet).

Events fired on window

codeb:wallet-signed-in e.detail.claims holds the verified SD-JWT VC claims (given_name, family_name, age_over_*, whatever the wallet released). e.detail.assertion holds a signed CodeB assertion your server verifies against the verifier JWKS.
codeb:wallet-declined User pressed “deny” in the wallet. Nothing to verify server-side.
codeb:wallet-expired The 5-minute presentation session timed out. Ask the user to try again.
codeb:wallet-error Wallet or verifier returned an error. e.detail.error holds the reason.

Programmatic API

If you prefer not to use the auto-rendered button, call the API directly:

CodeBEuWallet.open({ mode: 'signin' }); // opens the modal CodeBEuWallet.close(); // closes it CodeBEuWallet.config(); // reads current config CodeBEuWallet.version; // '2026-07-12-nadur'

Security & privacy

Origin isolation The widget only talks to the data-verifier origin. No third-party trackers, no cookies, no analytics.
Cross-origin fetches use credentials: 'omit' Your visitor’s session cookies never leave your site.
Modal cannot be spoofed by other origins Rendered from the widget script only; no iframes, no cross-frame messaging.
Assertion verification is server-side Never trust the browser’s e.detail.claims alone. POST e.detail.assertion to your backend and verify against the CodeB verifier JWKS.
Legal footing. The widget makes no certification claim. See HAIP implementation notes for our honest position on OpenID Foundation conformance testing.

EU Wallet verifier overview · HAIP notes · Try full sign-in · Age verification