An action that requires a multi-phase login flow to be executed.
Not ready: will show onboarding dialog when action is clicked
"use client"
import { Button } from "@/components/ui/button"
import { useOnboarding } from "@/hooks/use-onboarding"
import { toast } from "sonner"
export default function OnboardingDialogDemo() {
// Use the onboarding hook with full onboarding requirements
const { ready, require } = useOnboarding({
connectWallet: true,
signWithEthereum: true,
createSessionKey: true,
})
// Determine current status for display
const getStatusMessage = () => {
if (ready) {
return <span className="text-green-600">✓ Ready: all steps completed, action will execute</span>
}
return <span className="text-orange-600">Not ready: will show onboarding dialog when action is clicked</span>
}
const handleAction = () => {
// This will show the dialog if not ready, or continue if ready
if (!require()) return
// This code only runs if the user is fully onboarded
toast.success("🎉 Action executed successfully!", {
description: "This only runs when onboarding is complete."
})
}
return (
<div className="space-y-6 w-full">
<div className="border rounded-lg p-4 space-y-3">
<h3 className="font-semibold mb-1">Start Onboarding</h3>
<p className="text-sm mt-0 text-muted-foreground">
An action that requires a multi-phase login flow to be executed.
</p>
<div className="space-y-2">
<Button
onClick={handleAction}
className="w-full"
>
Execute Action
</Button>
{/* Status Label */}
<p className="text-sm text-left">
{getStatusMessage()}
</p>
</div>
</div>
</div>
)
}
The onboarding dialog has three optional phases. Install the components you need:
pnpm dlx shadcn@latest add "https://build.abs.xyz/r/onboarding-dialog.json"
Add the <Onboarder />
component to your app/layout.tsx
:
import { NextAbstractWalletProvider } from "@/components/agw-provider";
import { Toaster } from "@/components/ui/sonner";
import { Onboarder } from "@/components/onboarder";
import "./globals.css";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<NextAbstractWalletProvider>
<body>
{children}
<Onboarder />
<Toaster />
</body>
</NextAbstractWalletProvider>
</html>
);
}
Use the ready
flag and require()
function from the useOnboarding()
hook to gate actions behind onboarding requirements
such as requiring a wallet connection, SIWE authentication, or session key creation.
ready
The ready
flag is true
when all required steps are completed. Use this flag to conditionally render UI.
"use client"
import { useOnboarding } from "@/hooks/use-onboarding"
export default function MyComponent() {
const { ready } = useOnboarding({
connectWallet: true,
signWithEthereum: true,
createSessionKey: true,
});
return <div>{ready ? "Ready" : "Not Ready"}</div>;
}
require()
Call require()
before any logic that requires the user to be in a "ready" state (e.g. wallet connected & authenticated).
"use client"
import { Button } from "@/components/ui/button"
import { useOnboarding } from "@/hooks/use-onboarding"
export default function MyComponent() {
const { ready, require } = useOnboarding({
connectWallet: true, // Phase 1: Wallet connection
signWithEthereum: true, // Phase 2: SIWE authentication
createSessionKey: true, // Phase 3: Session key creation
});
const handleProtectedAction = () => {
// This shows the onboarding dialog if your conditions are not met
if (!require()) return;
// This code only runs if user is fully onboarded
console.log("Action executed!");
}
return (
<Button onClick={handleProtectedAction}>
{ready ? "Execute Action" : "Complete Onboarding First"}
</Button>
);
}
showDialog()
Use showDialog()
to manually trigger the onboarding dialog.
Note: The dialog will not open if all steps are already completed.
"use client";
import { Button } from "@/components/ui/button";
import { useOnboarding } from "@/hooks/use-onboarding";
export default function MyComponent() {
const { ready, isLoading, isError, showDialog } = useOnboarding({
connectWallet: true,
signWithEthereum: true,
createSessionKey: true,
});
if (isError) return <div>Error occurred during onboarding</div>;
if (isLoading) return <div>Loading...</div>;
return (
<div>
<div>{ready ? "Ready" : "Not Ready"}</div>
{!ready && (
<Button onClick={showDialog} disabled={isLoading}>
{isLoading ? "Loading..." : "Show Dialog"}
</Button>
)}
</div>
);
}
The useOnboarding()
hook returns the following:
ready: boolean
- True when all required steps are completedpending: boolean
- True when the onboarding dialog is currently openrequire(): boolean
- Shows dialog if not ready, returns true
if ready (use for early returns)showDialog(): void
- Manually show the onboarding dialog