Next.js
Wire the Sunboard React SDK into a Next.js App Router 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 wires the Sunboard runtime into a Next.js App Router app: install the SDK, mount a provider in your root layout, and point it at your project with a publishable key.
Install the SDK
npm install @sunboard/reactpnpm add @sunboard/reactyarn add @sunboard/reactbun add @sunboard/reactAdd your publishable key
Put your project's runtime key in .env.local. You'll find it in Sunboard (or
run sunboard init once to have it written for you).
NEXT_PUBLIC_SUNBOARD_KEY=pk_live_xxxCreate the runtime wrapper
This client component subscribes to the current route and renders the Sunboard widgets. Create it next to your root layout.
"use client";
import { usePathname, useRouter } from "next/navigation";
import { SunboardProvider, Sunboard } from "@sunboard/react";
import { useEffect, useState, type ReactNode } from "react";
export function SunboardRuntime({ children }: { children: ReactNode }) {
const pathname = usePathname();
const router = useRouter();
const [route, setRoute] = useState(pathname);
useEffect(() => {
const search = window.location.search;
setRoute(search ? `${pathname}${search}` : pathname);
}, [pathname]);
return (
<SunboardProvider
publishableKey={process.env.NEXT_PUBLIC_SUNBOARD_KEY}
// Replace with your real authenticated user.
user={{
id: "demo-user",
email: "demo@example.com",
group: "demo",
}}
route={route}
navigate={(url) => router.push(url)}
>
{children}
<Sunboard.Checklist />
<Sunboard.Hotspots />
<Sunboard.Tour />
</SunboardProvider>
);
}Mount it in your root layout
Import the Sunboard stylesheet before your own global CSS (so your
--sunboard-* overrides win), then wrap {children}.
import "@sunboard/react/styles.css";
import "./globals.css";
import { SunboardRuntime } from "./sunboard-provider";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<SunboardRuntime>{children}</SunboardRuntime>
</body>
</html>
);
}Using route groups?
If your app has multiple root layouts (e.g. app/(marketing)/layout.tsx and
app/(app)/layout.tsx), wrap {children} in each one so the runtime mounts
no matter which layout renders.
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 app. 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.