# Quickly Build a User Switcher, Just Like Gmail

Developing an authentication system from scratch can be time-consuming, and the process can be prone to bugs. If you're looking for a customer identity platform that provides user management features like authentication, authorization, and management of user profiles, roles, and permissions, check out [Clerk](https://clerk.com/). Clerk can save you time when it comes to building and testing your authentication flow. It also provides multi-session authentication, which allows users to seamlessly log in and switch between different accounts.

In this tutorial, you'll learn how to easily implement your own user profile switcher using Clerk and [Next.js](https://nextjs.org). You can follow along with this tutorial using [this GitHub repository](https://github.com/Anshuman71/clerk-user-switcher).

## What Is Clerk

Clerk is a one-stop solution for authentication and customer identity management. It helps you build a flawless user authentication flow that supports logging in with a password, multifactor authentication, or social logins with providers like [Google](https://clerk.com/blog/nextjs-google-authentication.md), LinkedIn, Facebook, and GitHub. Clerk provides components like `<SignUp/>` and `<SignIn/>` that you can plug into your application right away to quickly build an authentication flow.

It's common for users to have multiple accounts for different purposes. For instance, you may have a personal YouTube channel for your friends and family, and another one specifically intended for your audience in your work as a developer. With Clerk’s multisession feature, you can seamlessly and intuitively switch between both accounts as needed.

## Building a User Switcher

Before you begin building a user switcher, you'll need a code editor like [Visual Studio Code](https://code.visualstudio.com/download). You'll also need [Node.js](https://nodejs.org/en) (version 14 or newer) and [npm](https://www.npmjs.com) installed.

[Create your Clerk account](https://dashboard.clerk.com/sign-up) by following the steps on their website. Once registered, navigate to the Clerk dashboard, where you'll begin this tutorial:

![Clerk dashboard home for starting the tutorial](./0bc55bf7d729c611963f855cae53cafe5d8acb63-3840x2160.png)

### Set Up the Project

To set up the project, run `npx create-next-app clerk-app` in your terminal. This will initialize a Next.js project. Then you need to run `npm install @clerk/nextjs` inside the project and open your [Clerk dashboard](https://dashboard.clerk.com) in a web browser. In the left navigation, click on **API Keys** and copy the **Frontend API key**, **Backend API keys** and **JWT verification key**:

![Clerk API keys page showing frontend and backend keys](./03c567841a526a3410b52ba746eab23708ac9990-3840x2160.png)

Save the keys copied above in a `.env.local` file inside your project:

```text
NEXT_PUBLIC_CLERK_FRONTEND_API=<frontend-key>
CLERK_API_KEY=<backend-api-key>
CLERK_JWT_KEY=<jwt-verification-key>
```

### Set Up the Authentication Flow

The authentication flow of your application dictates how the users access different parts of your application. In this example, the user authentication flow works like this:

![User switcher flow diagram](./f2858db3eadd7bb4ff6eae2859b578e8a5ee217f-2264x1272.png)

To begin, implement the authentication flow in the `pages/_app.js`:

```jsx
import { ClerkProvider, SignedIn, SignedOut } from '@clerk/nextjs'

import { useRouter } from 'next/router'

import Head from 'next/head'

import Link from 'next/link'

// pages that can be accessed without an active user session.

const publicPages = ['/', '/sign-in/[[...index]]', '/sign-up/[[...index]]']

const MyApp = ({ Component, pageProps }) => {
  const router = useRouter()

  return (
    <ClerkProvider {...pageProps}>
      <Head>
        <title>Clerk app</title>

        <link rel="icon" href="/favicon.ico" />

        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      </Head>

      {/*If the route is for the home, sign-in and sign-up pages: show them without checks.*/}

      {publicPages.includes(router.pathname) ? (
        <Component {...pageProps} />
      ) : (
        <>
          {/*Show all pages if the user is signed in*/}

          <SignedIn>
            <Component {...pageProps} />
          </SignedIn>

          {/*Ask to sign in if the user isn't signed in*/}

          <SignedOut>
            <main>
              <p>
                Please{' '}
                <Link href="/sign-in">
                  <a>sign in</a>
                </Link>{' '}
                to access this page.
              </p>
            </main>
          </SignedOut>
        </>
      )}
    </ClerkProvider>
  )
}

export default MyApp
```

### Create the Sign-Up and Sign-In Pages

Next.js uses file-system-based routing, which makes it easy to create new pages. To learn more about Next.js routing check out their [official documentation](https://nextjs.org/docs/routing/introduction).

To create the sign-up and sign-in pages, navigate to the `pages/` folder in your project and create two new folders: `sign-up/` and `sign-in/`. Then create a new `[[...index]].js` file inside both of these folders. These routes will catch all the paths, including `/sign-up` and `/sign-in`.  You can read more about dynamic routing in the [Next.js documentation](https://nextjs.org/docs/routing/dynamic-routes#optional-catch-all-routes).

Use the prebuilt components for `<SignIn/>` and `<SignUp/>` to populate the pages:

```jsx
import { SignUp } from '@clerk/nextjs'

const SignUpPage = () => <SignUp path="/sign-up" routing="path" signInUrl="/sign-in" />

export default SignUpPage
```

![Clerk SignUp component page screenshot](./baf4da4192af228f95122e38d5bb1c1cdef75f38-3840x2160.png)

```jsx
import { SignIn } from '@clerk/nextjs'

const SignInPage = () => <SignIn path="/sign-in" routing="path" signUpUrl="/sign-up" />

export default SignInPage
```

![Clerk SignIn component page screenshot](./23a3986bedc299e0b5bd24170b1b10cb97c538e9-3840x2160.png)

### Create the Home Page

Now, the home page should display the greeting "Welcome to your new app." at the top of the page. If the user is signed in, it will show them their profile page. Otherwise, it will ask them to sign up or sign in:

![Home page with UserButton in navigation](./c911b489b95a6551e04b58ac4f8c1f59f6aec94b-1848x1080.png)

Update the `pages/index.js` file to use the `<SignedIn/>` component to conditionally render the child components if the user is signed in and use the `<SignedOut/>` component to render the child components if the user isn't signed in.

Inside the `<SignedIn/>` component, use the `<UserProfile/>` component provided by Clerk to show the user's profile details and allow them to edit their information.

You can also use the `<UserButton />` component in the top `<nav />` to allow users to manage their accounts and sign out of the application. The `<UserButton />` will render as a button with the user's avatar.

Inside the `<SignedOut/>`, render two `<Link />` components to send the user to the sign-in or sign-up page:

```jsx
import { SignedOut, SignedIn, UserProfile, UserButton } from '@clerk/nextjs'

import React from 'react'

import Link from 'next/link'

const Home = () => {
  return (
    <div
      style={{
        display: 'flex',

        justifyContent: 'center',

        alignItems: 'center',
      }}
    >
      <main>
        <nav
          style={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
          }}
        >
          <h1>Welcome to your new app.</h1>

          <UserButton />
        </nav>

        <div>
          <SignedIn>
            <UserProfile />
          </SignedIn>

          <SignedOut>
            <Link href="/sign-up">
              <a>Sign up </a>
            </Link>
            or
            <Link href="/sign-in">
              <a> Sign in </a>
            </Link>
            to get started.
          </SignedOut>
        </div>
      </main>
    </div>
  )
}

export default Home
```

If the user isn't signed in, the page will look like this:

![Signed-out state prompting sign-in](./c182a98f893cb71730e3ef707c27115f02b0e773-3840x2160.png)

Or if the user is signed in, it will look like this:

![Signed-in state with profile visible](./4c14e59c88acddeea0c8f6456b78f5816ddcac40-3840x2160.png)

When you click the user avatar at the top-right of your screen, a pop-up will appear containing buttons for **Manage account** and **Sign out**:

![User menu with Manage account and Sign out](./de1410f96d3edfc362d2a6cb29a1189dc80ff242-800x780.png)

### Implementing the User Switcher

Before moving on with this tutorial, you need to navigate to your [Clerk dashboard](https://dashboard.clerk.com) and enable the **Multi-session handling** feature inside the **Sessions** settings:

![Enable multi-session handling in Clerk dashboard](./c8b7ca26cacdedf785d37d16fa473ab7593f9b42-3840x2160.png)

After enabling multisession handling, go back to your application window and click on the user avatar again. Now you'll see that a new option, **Add account**, is available:

![Add account option shown in user menu](./103957875f33abe0dbf86e25a23739c7773a9468-914x1018.png)

Clicking on the **Add account** button will redirect users to the sign-in page, where they can sign in or sign up for a new account.

After signing in, Clerk will redirect the user back to the application with the new session, and the avatar pop-up menu will show all active sessions. The user can now switch between accounts by selecting them from the list:

![Multiple active sessions list in user switcher](./2b2198763b20ac5321eb634010ae6b3b907b7223-892x1310.png)

### Authenticating API Endpoints

To prevent malicious requests from coming through, it's essential to authenticate your API endpoints. With Clerk, you can access the user's authentication status in the Next.js API handlers. To do that, you must wrap your API handler function inside Clerk's `withAuth` higher-order function to access the `auth` property on the request object.

The following example uses the `request.auth` property to check if the `sessionId` is available and then sends the `userId` in the response. Otherwise, it returns a `401: Unauthorized` response code:

```jsx
import { withAuth } from '@clerk/nextjs/api'

export default withAuth((request, response) => {
  const { sessionId, userId } = request.auth

  if (!sessionId) {
    return response.status(401).json({ id: null, message: 'No user signed in!' })
  }

  return response.status(200).json({ id: userId })
})
```

On the home page, add a button to request the API endpoint and show the user ID in an alert:

```jsx
import { SignedOut, SignedIn, UserProfile, SignOutButton, UserButton, useAuth } from '@clerk/nextjs'

import React from 'react'

import Link from 'next/link'

const Home = () => {
  function showUserId() {
    fetch('/api/getUserId')
      .then((res) => res.json())

      .then(({ id }) => {
        alert(`User id: ${id}`)
      })
  }

  return (
    <div
      style={{
        display: 'flex',

        justifyContent: 'center',

        alignItems: 'center',
      }}
    >
      <main>
        <nav
          style={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
          }}
        >
          <h1>Welcome to your new app.</h1>

          <UserButton />
        </nav>

        <div>
          <SignedIn>
            <button onClick={showUserId}>Show user ID</button>

            <UserProfile />

            <SignOutButton />
          </SignedIn>

          <SignedOut>
            <Link href="/sign-up">
              <a>Sign up </a>
            </Link>
            or
            <Link href="/sign-in">
              <a> Sign in </a>
            </Link>
            to get started.
          </SignedOut>
        </div>
      </main>
    </div>
  )
}

export default Home
```

After you've added this button, your user switcher is ready:

[View video](./d3919c5803836ddbf93c4c659c1dab2a0e890056-2000x1124.mp4)

## Conclusion

After completing this tutorial, you will have successfully built a Next.js application that supports multisessions. While doing so, you learned about creating a new Next.js application, setting up a Clerk account, and integrating the Clerk SDK with your Next.js application.

You used the UI components provided by Clerk to create an authentication flow and user profile page. You also learned about the importance of multisession support in your application and how easy you can implement it with Clerk. Lastly, you created an API route in Next.js and secured it with Clerk.

Using the Clerk SDK, you can expand on the example above to add social logins and multifactor authentication to your application.
