> ## 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](/guides/getting-started/user-fundamentals#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>
    </>
  );
}
```

<Info>
  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.
</Info>

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

<Tabs>
  <Tab title="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>

  <Tab title="Server Component">
    ```jsx theme={null}
    import { hexclaveServerApp } from '@/stack/server';
    import { redirect } from 'next/navigation';

    export async function ensureOnboarded() {
      const user = await hexclaveServerApp.getUser();
      if (!user.clientReadOnlyMetadata.onboarded) {
        redirect('/onboarding');
      }
    }
    ```
  </Tab>
</Tabs>

You can then use these functions wherever onboarding is required:

<Tabs>
  <Tab title="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>

  <Tab title="Server Component">
    ```jsx theme={null}
    import { ensureOnboarding } from '@/app/onboarding-functions';
    import { hexclaveServerApp } from '@/stack/server';

    export default async function HomePage() {
      await ensureOnboarding();
      const user = await hexclaveServerApp.getUser();

      return (
        <div>Welcome to the app, {user.displayName}</div>
      );
    }
    ```
  </Tab>
</Tabs>
