Skip to content

toElysia(handler)

Wraps the verified function into an Elysia plugin.

Signature

ts
function toElysia(
  handler: (req: Request) => VerificationState | Promise<VerificationState>,
): Elysia

Parameters

handler

A function that takes a Request and returns a VerificationState (or a Promise of one). In practice this is always verified from an x511() instance.

Behavior

State returned by handlerPlugin behavior
{ type: 'verified' }Does nothing - the request proceeds to the route handler
{ type: 'pending', ... }Responds with HTTP 511 and the HTML verification page

The plugin registers a scoped onBeforeHandle hook ({ as: 'scoped' }). Returning a value from onBeforeHandle short-circuits the request, while returning undefined lets it proceed.

The 511 HTML page is generated by buildPage(state), which inlines provider-specific data (QR links, session ID) and UnoCSS styles.

Scoping

Because the hook uses { as: 'scoped' }, it applies to all routes on the same Elysia instance registered after .use(toElysia(...)). If you only want to protect specific routes, wrap them in a separate group or use Elysia's .guard().

Example

ts
import { Elysia } from 'elysia'
import { node } from '@elysiajs/node'
import { x511, toElysia } from 'x511-tba'

const { verify, verified } = x511({
  domain: 'https://example.com',
  basePath: '/x511',
  providers: ['self'],
  disclousures: { minAge: 18 },
})

const app = new Elysia({ adapter: node() })
  // Internal routes - must be mounted before the protected routes
  .mount('/x511', verify)
  // Apply the verification guard
  .use(toElysia(verified))
  // Protected route
  .get('/members', () => 'Members only content')
  .listen(3000)

Using verified directly (without toElysia)

If you are not using Elysia, call verified(req) directly and handle the state yourself:

WARNING

The request must be a native Request instance (WinterTC compatible).

ts
const state = verified(request)

if (state.type === 'verified') {
  // proceed
} else {
  // state.type === 'pending'
  // Return 511 with your own page, or use buildPage(state)
}