Developer cookbook

10-minute integration cookbook for adding European Digital Identity Wallet sign-in to your app.

Six framework recipes for the client side, three stacks for server-side verify. Every snippet compiles or parses standalone. The widget calls the same public endpoints (/oidc.ashx?action=vp-start / vp-status) documented on the EU Wallet integrations page. Reference: docs.eudi.dev.

Scope. These are documented recipes, not a certified widget SDK. There is no marketplace listing behind them; they are honest documentation of what a browser and a server need to do to accept a European Digital Identity Wallet sign-in against a CodeB tenant.

Recipe cards

Vanilla HTML

One <script> tag, one mount div. Works on any static page.

React

Import <EudiSignInButton> and pass an onSuccess handler.

Vue 3

Composition-API component. Emits success, error, cancelled.

Angular

Standalone component <eudi-sign-in>. Angular 15+.

WordPress

Shortcode [eudi_signin]. Copy-paste into functions.php.

Static site / JAMstack

Copy-paste script block. No build step. Works in Netlify, Cloudflare Pages, Hugo, Eleventy.

Vanilla HTML drop-in

  1. Add one script tag pointing at your CodeB tenant.
  2. Add one mount div with the data-eudi-signin attribute.
  3. Define an onEudiSuccess(claims) handler.
<div data-eudi-signin data-query="pid-minimal" data-on-success="onEudiSuccess"></div> <script src="https://phone.aloaha.com/signin-widget.js" defer></script> <script> function onEudiSuccess(claims) { // POST claims (or the session id) to your own /login handler. console.log('signed in with European Digital Identity Wallet', claims); } </script>

Full minimum-viable HTML file: signin-widget-vanilla.html.

React JSX

  1. Copy verifier-react-hook.jsx and signin-widget-react.jsx into your project.
  2. Import and render <EudiSignInButton>. Provide onSuccess.
import { EudiSignInButton } from './signin-widget-react.jsx'; function LoginPage() { return ( <EudiSignInButton query="pid-minimal" onSuccess={function (claims) { /* your handler */ }} > Sign in with European Digital Identity Wallet </EudiSignInButton> ); }

Download: signin-widget-react.jsx, hook: verifier-react-hook.jsx.

Vue 3 composition API

import { EudiSignIn } from './signin-widget-vue.js'; export default { components: { EudiSignIn }, methods: { onOk(claims){ /* your handler */ } }, template: '<eudi-sign-in query="pid-minimal" @success="onOk" />' };

Download: signin-widget-vue.js.

Angular standalone component

import { EudiSignInComponent } from './signin-widget-angular'; @Component({ standalone: true, imports: [EudiSignInComponent], template: '<eudi-sign-in query="pid-minimal" (success)="onOk($event)"></eudi-sign-in>' }) export class LoginPage { onOk(claims: any){ /* your handler */ } }

Download: signin-widget-angular.ts.

WordPress shortcode

  1. Copy wordpress-shortcode-snippet.php into your active theme's functions.php, or drop it as an mu-plugin.
  2. Use the shortcode in any post, page, or Gutenberg shortcode block: [eudi_signin query="pid-minimal"].
  3. Optionally add a settings page to let admins change the tenant URL - not required.

Not a plugin binary. This is copy-paste PHP, not a plugin distributable on WordPress.org. Ships as-is under Aloaha Limited copyright, permissive use.

Static site / JAMstack no build step

Same as the vanilla-HTML recipe, but paste the block directly into your Hugo partial, Eleventy layout, or Astro .astro file.

<div data-eudi-signin data-query="pid-minimal" data-on-success="onEudiSuccess"></div> <script src="https://phone.aloaha.com/signin-widget.js" defer></script>

Server-side verify

Once the widget resolves and you have a session id, your server SHOULD re-fetch vp-status before granting access. This prevents a spoofed browser callback from creating a session your server never authorized.

StackEndpointDownload
Node.js 18+POST /oidc.ashx?action=vp-statusserver-verify-nodejs.js
Python (requests)POST /oidc.ashx?action=vp-statusserver-verify-python.py
PHP 7.4+ (curl)POST /oidc.ashx?action=vp-statusserver-verify-php.php

All three verify that status === "completed", then return the claims object for your app to consume. Send the API key in the Authorization: Bearer header. Issue keys at /oidc-clients.html.

Error handling

Render each honestly - no synthetic success on failure.

StatusMeaningSuggested UX
waitingSession open, holder has not yet completed the wallet flow.Show QR + progress spinner.
completedWallet signed the presentation; claims available.Continue to your protected page.
expiredThe session timed out (default 180 s).Offer "Try again" that restarts vp-start.
errorWallet returned an OID4VP error (cancelled, unsupported credential type, unknown query).Show the error and a retry button.

Wallet not installed on the device: the deep-link click will resolve to the browser's default handler. Detect this by wrapping the click and starting a fallback QR after ~800 ms with no visibility change.

Testing

The verifier-test harness on this site runs the full spec-conformance suite against your tenant: OID4VP request-object shape, HAIP wallet attestation, presentation-definition parse, and (opt-in) x5c chain validation to the LOTL. Use it before every release.

Reference: docs.eudi.dev. Nothing on this page is endorsed by the European Commission.

Developer cookbooks: OIDC sign-in - JWT validation - M2M API keys - Webhooks