Docs

Build a custom sign-out flow

Caution

This guide is for users who want to build a custom user interface using the Clerk API. To allow users to sign-out using a prebuilt UI, you should use Clerk's Account Portal pages or prebuilt components

Clerk's <UserButton /> and <SignOutButton /> components provide a way to sign out users, out of the box. However, if you are building a custom solution, you can use the signOut() function to sign out users.

The signOut() function signs a user out of all sessions in a multi-session application, or simply the current session in a single-session context. You can also specify a specific session to sign out by passing the sessionId parameter.

Please note that the sign-out flow only deactivates the current session. Other valid sessions corresponding to the same user (for example, if the user is signed in on another computer) will continue to work.

The useClerk() hook is used to access the signOut() function, which is then called when the user clicks the sign-out button.

The Next.js useRouter() hook is used to redirect the user to the home page after they sign out.

This example is written for Next.js App Router but it can be adapted for any React meta framework, such as Remix or Gatsby.

/app/components/SignOutButton.tsx
'use client'

import { useClerk } from '@clerk/nextjs';

export const SignOutButton = () => {
  const { signOut } = useClerk();

  return (
    // Clicking on this button will sign out a user
    // and reroute them to the "/" (home) page.
    <button onClick={() => signOut({ redirectUrl: '/' })}>
      Sign out
    </button>
  );
};

For the following example, your HTML file should look like this:

index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Clerk + JavaScript App</title>
  </head>
  <body>
    <button id="sign-out">Sign out</button>

    <script
      type="module"
      src="/src/main.js"
      async
      crossorigin="anonymous"
    ></script>
  </body>
</html>

And your JavaScript file should look like this:

main.js
import Clerk from '@clerk/clerk-js';

// Initialize Clerk with your Clerk publishable key
const clerk = new Clerk('YOUR_PUBLISHABLE_KEY');
await clerk.load();

if (clerk.user) {
  document.getElementById('sign-out').addEventListener('click', async () => { await clerk.signOut() });
}
index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Clerk + JavaScript App</title>
  </head>
  <body>
    <button id="sign-out">Sign out</button>

    <script
      async
      crossorigin="anonymous"
      data-clerk-publishable-key="YOUR_PUBLISHABLE_KEY"
      src="https://YOUR_FRONTEND_API_URL/npm/@clerk/clerk-js@latest/dist/clerk.browser.js"
      type="text/javascript"
    ></script>

    <script>
      window.addEventListener('load', async function () {
        await Clerk.load();

        if (Clerk.user) {
          document.getElementById('sign-out')
            .addEventListener('click', async () => {
              await Clerk.signOut();
            });
        }
      });
    </script>
  </body>
</html>

Feedback

What did you think of this content?