This page walks through every supported integration path. Start with What you need; then jump to the section for your stack.Documentation Index
Fetch the complete documentation index at: https://companyname-a7d5b98e-feature-fumodocs.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
- What you need
- Build a dApp with React
- Build a dApp with Next.js
- Build a dApp with vanilla JS
- Build without a UI (
@tonconnect/sdk)
What you need
Before you start integrating, two things need to be in place: a hosted app manifest and a chosen SDK.1. The manifest
tonconnect-manifest.json is the JSON file the wallet fetches to learn your app’s name, icon, and policy URLs. The wallet shows this metadata to the user before approving the connection.
The minimum:
Hosting requirements
- The file must be reachable with a
GETfrom any origin, without CORS restrictions, without auth and without a Cloudflare-style proxy challenge. - The icon at the URL listed in
iconUrlmust be PNG or ICO. SVG is not supported. Use a 180×180 px PNG. - The manifest must be served over HTTPS. Wallets do not guarantee they will fetch a manifest served over plain HTTP.
- Any reachable HTTPS URL is valid. Hosting the manifest at the root of your domain (e.g.
https://yourapp.com/tonconnect-manifest.json) keeps access simple.
MANIFEST_NOT_FOUND_ERROR (code 2) or MANIFEST_CONTENT_ERROR (code 3). See Manifest 404 and CORS.
For the full field reference, see Manifest.
2. Pick an SDK
Three dApp-facing packages, all published fromton-connect/sdk:
| Package | When to use |
|---|---|
@tonconnect/ui-react | React or Next.js dApps. Recommended. Hooks, prebuilt button, modal. |
@tonconnect/ui | Vanilla JS or non-React frameworks. Same UI components, no React bindings. |
@tonconnect/sdk | Headless integrations — server-side flows, custom UI from scratch. |
ui-react if your app is React. Pick ui if it is not. Reach for sdk only when you need low-level control.
Build a dApp with React
Install the UI kit, host the manifest, mount the provider, add a connect button, and send a test transaction. For Next.js-specific notes (App Router,'use client', SSR), see Build a dApp with Next.js.
1. Install
2. Host the manifest
Placetonconnect-manifest.json at the root of your app’s domain. See What you need for the full requirements.
3. Wrap the app in TonConnectUIProvider
4. Add the connect button
className or style prop:
5. Read connection state
6. Send a transaction
The destination here is the connected wallet’s own address, returned byuseTonAddress() in user-friendly form. Replace it with your recipient.
address must be in user-friendly format (base64url with the bounce flag — EQ… for bounceable, UQ… for non-bounceable). Wallets reject raw 0:<hex> addresses. To convert one, use toUserFriendlyAddress from @tonconnect/ui-react. Each message also accepts optional payload, stateInit, and extraCurrency fields. Amounts use nanoTON: 1 TON = 10⁹ nanoTON. Send 100000000 for 0.1 TON.
Open the modal manually
Customise the UI
uiOptions is a setter, not a plain object. Assigning to it runs the merge, theme switch, and re-render logic; mutating a nested property (e.g. tonConnectUi.uiOptions.uiPreferences.theme = ...) bypasses the setter and has no effect. Always reassign the whole object.
Build a dApp with Next.js
Next.js needs two adjustments on top of the React tutorial:TonConnectUIProvider must run on the client, and the manifest is served from public/. The hooks behave the same as in plain React.
1. Install
2. Host the manifest in public/
Drop tonconnect-manifest.json into your project’s public/ directory:
https://yourapp.com/tonconnect-manifest.json. Make sure your hosting layer does not add CORS or auth gates — see Manifest 404 and CORS.
3. App Router
TonConnectUIProvider reads from local storage and opens modals — both browser-only. Mount it in a client component:
useTonWallet, useTonConnectUI, etc. must also start with 'use client'.
4. Pages Router
Dynamic-import the provider with SSR off so it does not run on the server:SSR pitfalls
- Local storage. TON Connect persists the session in
localStorage. Code that reads the wallet state during SSR will see “not connected” until hydration. Render the wallet-dependent UI inside a client component so the hooks run after hydration, or return a skeleton whileuseTonWallet()is stillnull. - Browser-only APIs. Anything from
@tonconnect/ui-reactthat toucheswindow, modals, or storage must run in a client component or be lazy-loaded withssr: false.
Build a dApp with vanilla JS
Same flow as the React tutorial — connect button, status subscription, transaction — built with@tonconnect/ui for plain HTML / JavaScript.
1. Install
Via npm:window.TON_CONNECT_UI.
2. Host the manifest
Placetonconnect-manifest.json at the root of your domain. Hosting rules in What you need.
3. Mark up a connect-button container
4. Initialise the UI
#ton-connect. Tapping it opens the wallet picker.
If you imported via npm:
5. Subscribe to connection status
wallet is null when disconnected, or a connected Wallet (with device, account, and optional connectItems) otherwise.
6. Send a transaction
address must be in user-friendly format; see the note in the React example. Amounts are in nanoTON: 1 TON = 10⁹ nanoTON.
Restore on reload
onStatusChange fires whenever the wallet state changes — connect, disconnect, and a successful session restore.
Build without a UI (@tonconnect/sdk)
@tonconnect/sdk is the headless TON Connect implementation — the same protocol layer that ships inside @tonconnect/ui-react and @tonconnect/ui, with no wallet picker, no modal, and no DOM dependencies. Use it on a server, in a custom UI you render yourself, or as a reference when porting TON Connect to another language.
For a regular browser dApp, prefer @tonconnect/ui-react (React, Next.js) or @tonconnect/ui (vanilla JS). They wrap this SDK and add the wallet picker, connect button, and notifications.
This section covers the headless API end-to-end: install, connector setup, custom storage, wallet discovery, the connect handshake, status events, and sendTransaction. The same shape applies whether you call it from a server or a custom in-browser UI.
1. Install
2. Create a connector
manifestUrl is the public URL of your tonconnect-manifest.json. The wallet fetches it during connect and shows the metadata to the user. See What you need for hosting rules.
storage is an IStorage implementation. In a browser, the SDK falls back to window.localStorage if you omit it. Anywhere else — Node.js, a worker — supply your own. restoreConnection() reads from storage and wires the connector back to the bridge if a session is already there. Call it once per instance, not on every request.
3. Custom storage
IStorage with a per-user record in your database (Postgres, Redis, etc.) keyed by your user ID. See Long-lived servers.
4. Discover wallets
WalletInfo with the fields a custom UI needs to render a picker and start a connect:
'universalLink' in wallet for HTTP wallets and 'jsBridgeKey' in wallet for injected ones.
5. Connect
For an HTTP wallet,connect() returns a universal link. Show it to the user as a clickable URL, a deep link, or a QR code:
connect() returns void:
ton_proof alongside the address, pass it under request:
6. Listen for status changes
unsubscribe() when you no longer need it.
7. Send a transaction
SendTransaction feature entry: wallet.device.features.find(f => typeof f === 'object' && f.name === 'SendTransaction')?.maxMessages.
Long-lived servers
- One
TonConnectinstance per signed-in user, with anIStoragekeyed by user ID, and an in-process cache so the same instance is reused across requests. - The HTTP bridge stays open over SSE for as long as the connector is live. Call
pauseConnection()when a user goes idle andunPauseConnection()when they return. - React to wallet-initiated disconnects through
onStatusChange. When the callback fires withnull, evict the cached connector and clear any session token you issued. - Persist the session per user, not globally. Two users sharing one
TonConnectwill leak addresses and overwrite each other’s session keypairs.
What’s next
- Authenticate the user with
ton_proof→ Connect a wallet - Send a structured transaction → Send a transaction
- Sign data on the wallet → Sign data
- Gasless transactions → Sign and relay a message (gasless)
- One-tap connect-and-pay → Connect-and-act in one tap
- Handle wallet-initiated disconnects → Disconnect a session
- Filter wallets by feature → Filter wallets by required features
- WalletConnect support → Add WalletConnect support