Installation
Five steps from zero to a working texting surface. Assumes a Next.js app with Tailwind v4 and the shadcn CLI initialized.
1. Register the Handset registry
Teach the shadcn CLI where @handset items live. This writes one line into your components.json.
npx shadcn@latest registry add @handset=https://ui.handset.dev/r/{name}.json2. Install components
The messaging block pulls in inbox, thread, and composer automatically; next-routes adds the server proxy. The CLI also installs @handset/react from npm.
npx shadcn@latest add @handset/messaging @handset/next-routes3. Set your API key
Server-side only — it never reaches the browser. Use your test key (sk_test_…) while building; simulated numbers and instant compliance are free.
# .env.local
HANDSET_API_KEY=sk_test_…4. Wire tenant scoping
Open the generated app/api/handset/[...handset]/route.ts and implement resolveTenantId() against your session. Single-tenant account? Return null and move on.
async function resolveTenantId(req: NextRequest): Promise<string | null> {
const session = await auth(); // your auth library
if (!session) throw new Response(null, { status: 401 });
return session.organization.handsetTenantId; // "tnt_…"
}5. Render it
import { HandsetProvider } from "@handset/react";
import { Messaging } from "@/components/handset/messaging";
export default function MessagesPage() {
return (
<HandsetProvider>
<div className="h-[600px]">
<Messaging />
</div>
</HandsetProvider>
);
}HandsetProvider defaults to /api/handset — the path the proxy route installed at. Pass baseUrl if you mounted it elsewhere.