React Router
Wire the Sunboard React SDK into a React Router (framework mode) app by hand.
Most people don't need this
sunboard init does all of this automatically — see the Quick
start. Follow this page if you'd rather wire things by hand,
or want to understand exactly what init changes.
This covers React Router framework mode (the successor to Remix). It's
Vite-based, so the setup mirrors Vite — the one
difference is where you mount the provider: your root route, app/root.tsx,
inside the Layout export.
Install the SDK
npm install @sunboard/reactpnpm add @sunboard/reactyarn add @sunboard/reactbun add @sunboard/reactAdd your publishable key
React Router framework mode runs on Vite, so it exposes VITE_-prefixed env
vars to the browser. Put your project's runtime key in .env.local:
VITE_SUNBOARD_KEY=pk_live_xxxCreate the runtime wrapper
This component reads the current location and renders the Sunboard widgets. It
uses React Router's useNavigate and useLocation so tour route changes stay
client-side. Create it next to your root route, under app/.
import { SunboardProvider, Sunboard } from "@sunboard/react";
import { useLocation, useNavigate } from "react-router";
import type { ReactNode } from "react";
export function SunboardRuntime({ children }: { children: ReactNode }) {
const navigate = useNavigate();
const location = useLocation();
const route = `${location.pathname}${location.search}`;
return (
<SunboardProvider
publishableKey={import.meta.env.VITE_SUNBOARD_KEY}
// Replace with your real authenticated user.
user={{
id: "demo-user",
email: "demo@example.com",
group: "demo",
}}
route={route}
navigate={(url) => navigate(url)}
>
{children}
<Sunboard.Checklist />
<Sunboard.Hotspots />
<Sunboard.Tour />
</SunboardProvider>
);
}Mount it in your root route
Import the Sunboard stylesheet before your own global CSS, then wrap the
{children} your Layout renders (inside <body>). The Layout export runs
inside the router context, so useNavigate / useLocation work there.
import "@sunboard/react/styles.css";
import { Links, Meta, Outlet, Scripts, ScrollRestoration } from "react-router";
import { SunboardRuntime } from "./sunboard-provider";
export function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body>
<SunboardRuntime>{children}</SunboardRuntime>
<ScrollRestoration />
<Scripts />
</body>
</html>
);
}
export default function App() {
return <Outlet />;
}Match your project's root
Keep your existing Meta / Links / Scripts and any providers — only add
the Sunboard stylesheet import and wrap {children} with <SunboardRuntime>.
If your appDirectory is src/ instead of app/, adjust the paths to match.
Wire your real user
The wrapper ships a placeholder user. Replace it with your authenticated
user so segments and analytics are accurate. Only id is required; anything you
put under properties is available for segment targeting:
user={{
id: currentUser.id,
email: currentUser.email,
group: currentUser.plan, // optional cohort, e.g. "trial" / "pro"
properties: {
// Any custom attributes you want to target on.
role: currentUser.role,
signupDate: currentUser.createdAt,
workflowsCreated: currentUser.workflowCount,
},
}}Verify
Run your dev server. Once you've authored a spec and promoted a version in
Sunboard, the checklist appears. To preview a local spec before deploying, use
/sunboard.preview, or run sunboard doctor to check the
wiring.