Skip to content

Quick start

This is the fastest way to embed Hobba - no build step, no npm install. It works in any HTML page.

Prerequisite: a wallet must be allowlisted before it can deposit or borrow through Hobba. This is a one-time, per-wallet step - see Prerequisites.

Load the hosted widget script and add an element for each widget to mount into.

<!-- Mount targets -->
<div id="hobba-deposit-borrow"></div>
<div id="hobba-market"></div>
<!-- The hosted Hobba widget -->
<script src="https://app.hobba.io/hobba.iife.js"></script>

The script exposes a single global, window.Hobba, once it finishes loading.

The script may not have evaluated by the time your own code runs, so don’t call window.Hobba directly. Instead push your mount logic onto window.HobbaQueue

  • Hobba drains the queue as soon as it’s ready (and runs your callback immediately if it’s already loaded). This is safe to push to before or after the script tag.
<script>
window.HobbaQueue = window.HobbaQueue || [];
HobbaQueue.push(function () {
// Read-only market data - no wallet needed.
window.Hobba.mountMarketData("#hobba-market", {
variant: "full",
theme: "dark",
});
// Deposit / borrow.
window.Hobba.mountDepositBorrow("#hobba-deposit-borrow", {
collateral: "cbBTC",
theme: "dark",
onSuccess: function (signature) {
console.log("deposit/borrow confirmed:", signature);
},
onError: function (err) {
console.error("deposit/borrow failed:", err);
},
});
});
</script>

mountMarketData and mountDepositBorrow each take a target (a CSS selector string or an HTMLElement) and an options object.

The two widgets are fully independent - you don’t need both. Mount just the one you want (and add only its mount target from step 1). For example, to embed only the read-only market data widget, call mountMarketData on its own and skip the deposit/borrow widget entirely (including the wallet wiring in step 3).

To actually deposit and borrow, the deposit/borrow widget needs a Solana wallet. You have two choices:

Let the widget handle it. If you mount mountDepositBorrow without a wallet option, the widget falls back to its own built-in wallet detection and connect button. This is the zero-effort path - nothing else to wire up.

Provide your own wallet. If your page already connects a wallet (e.g. a Phantom connect button), pass it in and keep it in sync as the user connects, disconnects, or switches accounts. The widget accepts any object matching the HobbaWallet interface - which Phantom’s injected provider already satisfies:

<script>
var depositHandle = null;
window.HobbaQueue = window.HobbaQueue || [];
HobbaQueue.push(function () {
depositHandle = window.Hobba.mountDepositBorrow("#hobba-deposit-borrow", {
collateral: "cbBTC",
theme: "dark",
});
});
async function connectPhantom() {
var provider = window.phantom && window.phantom.solana;
if (!provider || typeof provider.connect !== "function") {
window.open("https://phantom.app/", "_blank");
return;
}
await provider.connect();
// Push the connected wallet into the already-mounted widget.
depositHandle && depositHandle.update({ wallet: provider });
// Keep it in sync on account switch / disconnect.
provider.on("accountChanged", function (pk) {
depositHandle && depositHandle.update({ wallet: pk ? provider : undefined });
});
provider.on("disconnect", function () {
depositHandle && depositHandle.update({ wallet: undefined });
});
}
</script>

That’s the whole integration.

Each widget mounts into its own Shadow DOM, so its styles never leak into your page and your page’s CSS never leaks into the widget. You can place the mount <div> anywhere in your layout and size it with your own container - the widget fills its container responsively.

The widget injects its @font-face declarations into the document <head> once (font faces can’t be scoped to a shadow root reliably). This is the only thing it adds outside its shadow roots.