Skip to main content

Integrate TLSNotary (Any Framework)

The standard Build a TLSNotary Webapp guide uses webpack directly, which requires complex WASM polyfills, worker setup, and browser polyfill configuration. If you use Vite, Next.js, SvelteKit, Nuxt, Remix, Astro, or any other bundler, you can skip all of that. The TlsnClient approach runs all the heavy TLSNotary WASM machinery inside a hosted iframe, and your app communicates with it through a simple async API over postMessage.

Why Use the Iframe Approach?

How It Works

Your app loads a hidden <iframe> pointing to a hosted TLSNotary embed. The embed contains the full webpack build with WASM, workers, and polyfills. Your app calls methods on TlsnClient, which sends postMessage commands to the iframe and returns promises with the results.

Quick Start

Step 1: Copy the TlsnClient

The TlsnClient is a single TypeScript file with zero dependencies. Copy it into your project:
TlsnClient.ts

Step 2: Use in Your App

That’s it. No webpack configuration, no WASM polyfills, no worker setup.

Framework Examples

Vite + TypeScript

Copy TlsnClient.ts into src/, then use it in src/main.ts:
src/main.ts

React (Vite or CRA)

src/hooks/useTlsn.ts
src/App.tsx

Next.js

Since TlsnClient uses document and window, it must run client-side only:
app/components/TlsnAttest.tsx
Do not import TlsnClient in server components or getServerSideProps. It requires browser APIs (document, window, postMessage).

SvelteKit

src/lib/components/TlsnAttest.svelte

Vue / Nuxt

components/TlsnAttest.vue

TlsnClient API Reference

Constructor Options

Methods

Events

Self-Hosting the TLSN Embed (Optional)

The public instance at https://tlsn.demos.sh is the easiest way to get started. If you need to host the embed yourself (for example, on a private network or for development), you can use Docker Compose.

Prerequisites

Clone the tlsn-component repository and build:

Run with Docker Compose

docker-compose.yml
The embed will be available at http://localhost:8443. Caddy handles the required Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers automatically. Then point your client to the local instance:
The COOP/COEP headers (Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp) are required because TLSNotary uses SharedArrayBuffer for WASM threads. These headers are configured on the embed server, not on your app’s server. If you use the public https://tlsn.demos.sh instance, you don’t need to worry about this.

Troubleshooting

“iframe did not become ready within 30000ms”
  • Verify the iframe URL is reachable: open https://tlsn.demos.sh directly in a browser tab
  • Check your browser’s console for CORS or CSP errors
  • If self-hosting, ensure COOP/COEP headers are being served
“TlsnClient call timed out”
  • Attestation can take 2-5 seconds. The default timeout is 5 minutes.
  • Check network connectivity to the Demos RPC node
  • Enable debug: true in constructor options to see postMessage traffic
Blank page or hydration errors (Next.js / Nuxt)
  • TlsnClient uses browser APIs (document, window). Only import and instantiate it in client-side code.
  • In Next.js: use 'use client' directive or dynamic imports with { ssr: false }
  • In Nuxt: use <ClientOnly> wrapper or onMounted() lifecycle hook