TanStack Start
Wire the Sunboard React SDK into a TanStack Start 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.
TanStack Start is Vite-based, so the setup is the same as Vite
— the one difference is where you mount the provider: your root route,
src/routes/__root.tsx, instead of a client entry.
Install the SDK
npm install @sunboard/reactpnpm add @sunboard/reactyarn add @sunboard/reactbun add @sunboard/reactAdd your publishable key
Like Vite, TanStack Start 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. The
typeof window guard keeps it safe during server rendering.
import { SunboardProvider, Sunboard } from "@sunboard/react";
import type { ReactNode } from "react";
export function SunboardRuntime({ children }: { children: ReactNode }) {
const route =
typeof window === "undefined"
? "/"
: `${window.location.pathname}${window.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) => window.location.assign(url)}
>
{children}
<Sunboard.Checklist />
<Sunboard.Hotspots />
<Sunboard.Tour />
</SunboardProvider>
);
}Client-side navigation
The default navigate does a full-page load. To keep tour route changes
client-side, swap it for TanStack Router's navigation.
Mount it in your root route
Import the Sunboard stylesheet before your own global CSS, then wrap the
{children} your root document renders (inside <body>).
import "@sunboard/react/styles.css";
import appCss from "../styles/app.css?url";
import { createRootRoute, Outlet, Scripts } from "@tanstack/react-start";
import { SunboardRuntime } from "../sunboard-provider";
export const Route = createRootRoute({
head: () => ({
links: [{ rel: "stylesheet", href: appCss }],
}),
component: RootComponent,
});
function RootComponent() {
return (
<RootDocument>
<Outlet />
</RootDocument>
);
}
function RootDocument({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<SunboardRuntime>{children}</SunboardRuntime>
<Scripts />
</body>
</html>
);
}Match your project's root
The exact shape of __root.tsx varies by TanStack Start version. The only
thing that matters is that <SunboardRuntime> wraps the {children} /
<Outlet /> your root renders. Keep your existing imports and head config.
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.