# Onboarding

Shipped provides a basic onboarding to collect information about the users that signup into your product for the first time.

&#x20;

<figure><img src="https://3985976695-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT3t4pDs63s3Soj1JetJw%2Fuploads%2FuLfPlYhFRHvch94amTUH%2Fonboarding.gif?alt=media&#x26;token=ee4156da-f879-4489-9079-7300cb9994bc" alt=""><figcaption><p>Example of onboarding</p></figcaption></figure>

When the button Next is clicked, the answers are saved to the database, and the onboarding is marked as complete for the currently authenticated user.

The page also checks if:

* the user is logged in, otherwise redirects the page to `/login`
* the onboarding is complete, in positive case, it redirects to `/dashboard`

You reach the onboarding page by browsing  `/onboarding`.

## Redirect to onboarding after sign-up

Update the file `src/config/config.ts`

```typescript
// the users will be redirected to this page after sign in
export const signInCallbackUrl = "/onboarding";
```

## Customize the questions

You can customize the questions by updating the file `src/components/UserOnboarding/onboarding.questions.ts`

You can define free text and questions with predefined answers.

```typescript
export const questions: Question[] = [
  {
    question: "What's your name?",
    type: "text",
    name: "name",
  },
  {
    question: "What's your role?",
    type: "select",
    name: "role",
    options: ["Founder", "Product Manager", "Engineer", "Designer"],
  },
  {
    question: `Where did you find ${brandName}?`,
    type: "select",
    name: "source",
    options: [
      "Twitter / X",
      "Facebook",
      "LinkedIn",
      "Instagram",
      "Google",
      "Newsletter",
      "Other",
    ],
  },
];
```

A database table named `UserOnboarding` is required (already included `prisma.schema`)

```prisma
model UserOnboarding {
  id         String   @id @default(cuid())
  userId     String
  isComplete Boolean  @default(false)
  role       String?
  source     String?
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt
  user       User     @relation(fields: [userId], references: [id])
}
```

To customize the questions, you need to:

* update table `UserOnboarding` to include the question key you want to use (by default `role` and `source`)
* run `npx prisma generate` to update the database types
* update the file `src/components/UserOnboarding/onboarding.questions.ts`
* update `PostOnboardingRequest` in `src/app/api/onboarding/route.ts` with the expected question keys
* update the question keys in `src/app/api/onboarding/route.ts` (validity checks and the prisma record creation `await prismaClient.userOnboarding.create({`)
* finally run `npx prisma db push` to apply the updated table to your database

{% hint style="info" %}
By default, the `name` question value is stored in the table `User` in the column `name` if it's not present.

This is particularly useful if you are using email authentication.
{% endhint %}

## Hook: useOnboarding

```typescript
const { isLoadingOnboarding, isOnboardingCompleted } = useOnboarding();
```

This hook is particularly useful to check if the onboarding, for the current user, is completed or not.

If you have an onboarding, you probably want to redirect the user after the signup, but only if it is not complete.

To do that you can use `isOnboardingCompleted` in the `SignUp` component and update the redirect URL accordingly. Here's an example:

{% code title="SignUp.tsx" %}

```typescript
const { isLoadingOnboarding, isOnboardingCompleted } = useOnboarding();
const redirectRoute = isOnboardingCompleted ? Routes.dashboard : Routes.onboarding
const redirectUrl = window?.location ? `${window.location.origin}${redirectRoute}` : "",

const onGoogleSignUp = () => {
    setSigningUpWithGoogle(true);
    signIn("google", {
      callbackUrl: redirectUrl
    });
};

const onEmailSignUp = async () => {
    setSigningUpWithEmail(true);
    await signIn("email", {
      email,
      callbackUrl: redirectUrl
    });
    setSigningUpWithEmail(false);
};
```

{% endcode %}
