Getting Started
Set up the Riftix Console Bridge end to end in five minutes.
Prerequisites
- pnpm 10+, Node 22+
- A host app (the shell — e.g.
apps/console): React + Vite or any framework that can render<iframe>elements. - A client app (a product page embedded inside the host): any stack that can include a
<script>tag.
1. Host setup
Install
pnpm add @riftix/console-bridge-hostWrap your app in ConsoleHostProvider
import { ConsoleHostProvider } from "@riftix/console-bridge-host/react";
export function App() {
return (
<ConsoleHostProvider
defaultContextProvider={() => ({ theme: "light", locale: "en-US" })}
defaultAuthorizationProvider={(channel) => ({
clientId: channel.productId,
organizationId: "org_123",
token: "jwt.goes.here",
expiresAt: Date.now() + 3_600_000,
})}
>
{/* your routes / shell */}
</ConsoleHostProvider>
);
}Render an iframe
import { ConsoleIframe } from "@riftix/console-bridge-host/react";
export function BillingPage() {
return (
<ConsoleIframe
src="https://billing.example.com"
origin="https://billing.example.com"
productId="billing"
style={{ width: "100%", height: "100%", border: "none" }}
/>
);
}Handle RPCs from client products
import { useConsoleHost } from "@riftix/console-bridge-host/react";
import { toast } from "sonner";
function ToastHandler() {
const host = useConsoleHost();
useEffect(() => {
return host.handle("toast.show", ({ message, variant }) => {
toast[variant ?? "info"](message);
});
}, [host]);
return null;
}2. Client setup
The client page is loaded inside the host <iframe>. The only distribution is the IIFE snippet — there is no npm client package.
Load the snippet
Add to your index.html:
<!-- Tell the snippet which origin to accept messages from -->
<meta name="riftix-host" content="https://console.example.com" />
<!-- Load the snippet from the host's snippet dev server or CDN -->
<script src="https://console.example.com/riftix.js"></script>TypeScript types (optional but recommended)
pnpm add -D @riftix/console-bridge-snippet-typesThen in any .ts / .tsx file (or in tsconfig.json > types):
import "@riftix/console-bridge-snippet-types";
// window.Riftix is now typedWait for the bridge and call APIs
await window.Riftix!.ready;
window.Riftix!.toast.show({ message: "Hello from billing!", variant: "success" });
const confirmed = await window.Riftix!.modal.confirm({
title: "Delete invoice?",
body: "This cannot be undone.",
confirmLabel: "Delete",
cancelLabel: "Cancel",
destructive: true,
});React hooks
pnpm add @riftix/console-bridge-snippet-reactimport { useRiftixContext, useRiftixAuthorization } from "@riftix/console-bridge-snippet-react";
function Dashboard() {
const { status, context } = useRiftixContext();
const auth = useRiftixAuthorization();
if (status === "loading") return <p>Connecting…</p>;
return (
<div>
<p>Theme: {context.theme}</p>
<p>Token: {auth?.token ?? "none"}</p>
</div>
);
}Declarative breadcrumbs
Instead of calling Riftix.navigation.setBreadcrumbs() imperatively, use the built-in web components:
<riftix-page>
<riftix-breadcrumb href="/billing">Billing</riftix-breadcrumb>
<riftix-breadcrumb>Invoices</riftix-breadcrumb>
</riftix-page>The host navbar updates live as the DOM changes. See Web Components for full details.
3. Running the demo
The monorepo ships with a full working demo.
# From repo root — builds packages then starts all dev servers
bun run dev| URL | What it is |
|---|---|
http://localhost:6173 | console shell |
http://localhost:6174 | demo-client (billing product) |
http://localhost:6175 | snippet dev server |
Open http://localhost:6173/billing. The billing iframe loads, the bridge handshakes, and breadcrumbs in the host navbar update when you switch sections inside the iframe.