Manual installation

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/react
pnpm add @sunboard/react
yarn add @sunboard/react
bun add @sunboard/react

Add 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).

.env.local
NEXT_PUBLIC_SUNBOARD_KEY=pk_live_xxx

Create the runtime wrapper

This client component subscribes to the current route and renders the Sunboard widgets. Create it next to your root layout.

app/sunboard-provider.tsx
"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}.

app/layout.tsx
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.

Next steps

On this page