Skip to main content

Web Integration

The @trezor/connect-web package provides a high-level JavaScript interface for integrating Trezor hardware wallets into web applications. It presents a secure popup-based UI served from connect.trezor.io and supports both WebUSB and Trezor Bridge communication protocols.

Installation

Install the package using npm or yarn:
npm install @trezor/connect-web

Basic Setup

Import and initialize TrezorConnect in your application:
import TrezorConnect from '@trezor/connect-web';

await TrezorConnect.init({
    manifest: {
        email: '[email protected]',
        appName: 'My Web App',
        appUrl: 'https://myapp.example.com',
        appIcon: 'https://myapp.example.com/icon.png',
    },
});
The manifest object is required and identifies your application to users. All fields should accurately represent your application.

Configuration Options

Customize TrezorConnect behavior with these initialization options:
await TrezorConnect.init({
    manifest: {
        email: '[email protected]',
        appName: 'My Web App',
        appUrl: 'https://myapp.example.com',
    },
    // Core execution mode
    coreMode: 'auto', // 'auto' | 'popup' | 'iframe'
    
    // Enable debug logging
    debug: true,
    
    // Lazy load resources
    lazyLoad: true,
    
    // Automatic transport reconnection
    transportReconnect: true,
});

Core Modes

Automatically selects the best mode based on the environment. This is the recommended default.
Embeds the Suite interface in an iframe (legacy mode for specific use cases).

Making API Calls

Once initialized, you can call any TrezorConnect method:

Get Bitcoin Address

const result = await TrezorConnect.getAddress({
    path: "m/49'/0'/0'/0/0",
    coin: 'btc',
    showOnTrezor: true,
});

if (result.success) {
    console.log('Address:', result.payload.address);
    console.log('Path:', result.payload.serializedPath);
} else {
    console.error('Error:', result.payload.error);
}

Get Ethereum Address

const result = await TrezorConnect.ethereumGetAddress({
    path: "m/44'/60'/0'/0/0",
    showOnTrezor: true,
});

if (result.success) {
    console.log('ETH Address:', result.payload.address);
}

Sign Message

const result = await TrezorConnect.signMessage({
    path: "m/49'/0'/0'/0/0",
    message: 'Hello from my web app!',
    coin: 'btc',
});

if (result.success) {
    console.log('Signature:', result.payload.signature);
}

Event Handling

Listen to device and transport events:
import TrezorConnect, { DEVICE_EVENT, TRANSPORT_EVENT } from '@trezor/connect-web';

// Device events: connect, disconnect, changed
TrezorConnect.on(DEVICE_EVENT, (event) => {
    console.log('Device event:', event.type);
    console.log('Device:', event.payload);
});

// Transport events: bridge start/stop, WebUSB availability
TrezorConnect.on(TRANSPORT_EVENT, (event) => {
    console.log('Transport event:', event.type);
});

DEVICE_EVENT

Fired when a device connects, disconnects, or changes state.

TRANSPORT_EVENT

Fired when Trezor Bridge starts/stops or transport layer changes.

Browser Support

TrezorConnect Web has different support levels across browsers:
EnvironmentChromeFirefoxSafariChrome AndroidFirefox Android
WebUSB
Bridge
WebUSB allows direct browser communication with Trezor devices (Chromium-based browsers only).Trezor Bridge is required for Firefox and provides a more stable desktop connection.

Framework Integration

React Example

import { useEffect, useState } from 'react';
import TrezorConnect from '@trezor/connect-web';

function App() {
    const [address, setAddress] = useState('');
    const [loading, setLoading] = useState(false);

    useEffect(() => {
        TrezorConnect.init({
            manifest: {
                email: '[email protected]',
                appName: 'My React App',
                appUrl: 'https://myapp.example.com',
            },
        });
    }, []);

    const getAddress = async () => {
        setLoading(true);
        const result = await TrezorConnect.getAddress({
            path: "m/49'/0'/0'/0/0",
            coin: 'btc',
        });
        
        if (result.success) {
            setAddress(result.payload.address);
        }
        setLoading(false);
    };

    return (
        <div>
            <button onClick={getAddress} disabled={loading}>
                {loading ? 'Loading...' : 'Get Address'}
            </button>
            {address && <p>Address: {address}</p>}
        </div>
    );
}

Vue Example

<template>
  <div>
    <button @click="getAddress" :disabled="loading">
      {{ loading ? 'Loading...' : 'Get Address' }}
    </button>
    <p v-if="address">Address: {{ address }}</p>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import TrezorConnect from '@trezor/connect-web';

const address = ref('');
const loading = ref(false);

onMounted(async () => {
  await TrezorConnect.init({
    manifest: {
      email: '[email protected]',
      appName: 'My Vue App',
      appUrl: 'https://myapp.example.com',
    },
  });
});

const getAddress = async () => {
  loading.value = true;
  const result = await TrezorConnect.getAddress({
    path: "m/49'/0'/0'/0/0",
    coin: 'btc',
  });
  
  if (result.success) {
    address.value = result.payload.address;
  }
  loading.value = false;
};
</script>

Error Handling

All TrezorConnect methods return a response object with a success boolean:
const result = await TrezorConnect.getAddress({
    path: "m/49'/0'/0'/0/0",
    coin: 'btc',
});

if (result.success) {
    // Success - use result.payload
    const { address, path, serializedPath } = result.payload;
    console.log('Address:', address);
} else {
    // Error - handle result.payload.error
    console.error('Error code:', result.payload.code);
    console.error('Error message:', result.payload.error);
}
Always check the success field before accessing result.payload to ensure proper error handling.

Cleanup

Dispose of TrezorConnect when unmounting your application:
// Clean up when your app unmounts
TrezorConnect.dispose();

Advanced Features

Update Settings at Runtime

TrezorConnect.updateConnectSettings({
    debug: false,
    transportReconnect: false,
});

Cancel Pending Requests

// Cancel the current pending request
TrezorConnect.cancel();

UI Response Handling

For custom UI implementations, you can respond to UI requests:
import { UI_REQUEST } from '@trezor/connect-web';

TrezorConnect.on(UI_REQUEST.ADDRESS_VALIDATION, (event) => {
    // Custom address validation UI
    TrezorConnect.uiResponse({
        type: UI_REQUEST.ADDRESS_VALIDATION,
        payload: true, // User confirmed
    });
});

Next Steps

API Methods

Explore all available TrezorConnect methods

Examples

Browse complete integration examples

Troubleshooting

Common issues and solutions

API Explorer

Interactive API testing tool

Build docs developers (and LLMs) love