> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hexclave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# User Onboarding

> Implementing a user onboarding page and collecting information on sign-up

Sometimes, you may want to collect additional information from users during sign-up, for example a real name or address.

The most straightforward approach is to redirect users to an onboarding page right after they sign up. However, this is not recommended for the following reasons:

1. Users can accidentally (or purposefully) close or navigate away from the page before completing the onboarding.
2. Redirect URLs may vary depending on the context. For instance, if a user is redirected to a sign-in page after trying to access a protected page, they'll expect to return to the original protected page post-authentication.

Instead, a more reliable strategy is to store an `onboarded` flag in the user's metadata and redirect users to the onboarding page if they haven't completed it yet.

## Example implementation

Let's say you have an onboarding page that asks for an address and stores it in the user's [metadata](https://docs.hexclave.com/guides/getting-started/user-fundamentals.md#custom-metadata):

```jsx theme={null}
export default function OnboardingPage() {
  const user = useUser();
  const router = useRouter();
  const [address, setAddress] = useState('');

  return <>
    <input 
      type="text" 
      value={address} 
      onChange={(e) => setAddress(e.target.value)} 
    />

    <button onClick={async () => {
      await user.update({
        clientMetadata: {
          onboarded: true,
          address,
        },
      });
      router.push('/');
    }}>
      Submit
    </button>
    </>
  );
}
```

> [!NOTE]
>
> While the above implementation offers a basic onboarding process, users can still skip onboarding by directly sending an API request to update the `clientMetadata.onboarded` flag. If you want to ensure that onboarding cannot be bypassed on the API level, you should create a server endpoint to validate and store the data, then save the `onboarded` flag in the `clientReadOnlyMetadata` on the server side after validation.

Next, we can create a hook/function to check if the user has completed onboarding and redirect them to the onboarding page:

> [tab] Client Component
>
> ```jsx theme={null}
> 'use client';
> import { useEffect } from 'react';
> import { useUser } from '@hexclave/next';  // replace `next` with the correct framework SDK package
> import { useRouter } from 'next/navigation';
>
> export function useOnboarding() {
>   const user = useUser();
>   const router = useRouter();
>
>   useEffect(() => {
>     if (!user.clientReadOnlyMetadata.onboarded) {
>       router.push('/onboarding');
>     }
>   }, [user]);
> }
> ```

> [tab] Server Component
>
> ```jsx theme={null}
> import { hexclaveServerApp } from '@/hexclave/server';
> import { redirect } from 'next/navigation';
>
> export async function ensureOnboarded() {
>   const user = await hexclaveServerApp.getUser();
>   if (!user.clientReadOnlyMetadata.onboarded) {
>     redirect('/onboarding');
>   }
> }
> ```

You can then use these functions wherever onboarding is required:

> [tab] Client Component
>
> ```jsx theme={null}
> import { useOnboarding } from '@/app/onboarding-hooks';
> import { useUser } from '@hexclave/next';  // replace `next` with the correct framework SDK package
>
> export default function HomePage() {
>   useOnboarding();
>   const user = useUser();
>
>   return (
>     <div>Welcome to the app, {user.displayName}</div>
>   );
> }
> ```

> [tab] Server Component
>
> ```jsx theme={null}
> import { ensureOnboarding } from '@/app/onboarding-functions';
> import { hexclaveServerApp } from '@/hexclave/server';
>
> export default async function HomePage() {
>   await ensureOnboarding();
>   const user = await hexclaveServerApp.getUser();
>
>   return (
>     <div>Welcome to the app, {user.displayName}</div>
>   );
> }
> ```
