Framework guide
First-run setup checklist for Remix
Onboard is a React client component. Mount it from a Remix client route or a client-only island. Pass user and workspaceKey from your session loader. Onboard does not authenticate end users.
Install
pnpm add @bootstrapware/onboard
Import @bootstrapware/onboard/styles.css from the client module that renders the checklist (or from your root stylesheet if you prefer one global import).
Client island
import { Onboard, createLocalAdapter } from "@bootstrapware/onboard";
import "@bootstrapware/onboard/styles.css";
export function SetupChecklist({
user,
workspaceKey,
}: {
user: { id: string; name?: string };
workspaceKey: string;
}) {
return (
<Onboard
user={user}
workspaceKey={workspaceKey}
adapter={createLocalAdapter({ storageKey: "remix-onboard" })}
/>
);
}Mount <SetupChecklist /> from a route that is already behind your session. Remix loaders stay for page data; BYO writes go through resource routes.
Loader → user prop
// app/routes/settings.setup.tsx
export async function loader({ request }: LoaderFunctionArgs) {
const session = await requireUserSession(request);
return json({
user: { id: session.userId, name: session.displayName },
workspaceKey: session.workspaceId,
});
}Pass that user into the client island. Opaque stable ids matter for personal vs workspace progress, see identity.
BYO resource routes
Pass an OnboardAdapter that hits your Remix resource routes. Authenticate the session cookie, re-bind authorship, and honor pinned revision plus dual generations.
// Illustrative, your routes, your schema
export async function action({ request }: ActionFunctionArgs) {
const session = await requireUserSession(request);
const body = await request.json();
// Persist progress using session.userId, not body.user.id alone.
return json({ ok: true });
}Hosted configuration and env
Expose only publishable keys to the browser. Pattern depends on your Remix setup (classic window.ENV injection from the root loader, or Vite-based Remix env). Never ship bsw_*_sec_ to the client. Mint authorToken in a resource route. Details: API keys.
<Onboard
flowId={ENV.ONBOARD_FLOW_ID}
publishableKey={ENV.BSW_PUBLISHABLE_KEY}
user={user}
workspaceKey={workspaceKey}
authorToken={authorToken}
/>Mode resolution: explicit adapter for progress → Hosted progress when flowId + publishable key and no adapter → otherwise local. Config still fetches when flowId + publishable key are set.
Pitfalls
- Rendering Onboard without a client boundary
- Forgetting styles.css
- Leaking secret keys through the root loader ENV blob
- Trusting client user ids on resource routes
- Skipping workspaceKey so shared steps never complete for teammates
Related: React guide · Next.js guide · Identity · Adapter · Quickstart