Skip to main content
End a user’s authenticated session and remove their access credentials from the device. Logging out a user removes their session from the device and requires them to authenticate again to access protected resources.

Using the React SDK

To log a user out, use the logout method from the useMoonKey hook:
logout: () => Promise<void>

Basic Usage

import { useMoonKey } from '@moon-key/react-auth';

function LogoutButton() {
  const { ready, isAuthenticated, logout } = useMoonKey();

  // Disable logout when SDK is not ready or user is not authenticated
  const disableLogout = !ready || (ready && !isAuthenticated);

  return (
    <button disabled={disableLogout} onClick={logout}>
      Log out
    </button>
  );
}

With Async Handling

Since logout returns a Promise, you can await it to run code after the user has been logged out:
import { useMoonKey } from '@moon-key/react-auth';
import { useRouter } from 'next/router';

function LogoutButton() {
  const { logout } = useMoonKey();
  const router = useRouter();

  const handleLogout = async () => {
    try {
      await logout();
      // Perform actions after logout completes
      console.log('User logged out successfully');
      router.push('/');
    } catch (error) {
      console.error('Logout failed:', error);
    }
  };

  return (
    <button onClick={handleLogout}>
      Log out
    </button>
  );
}

Common Patterns

Logout with Confirmation

Ask the user to confirm before logging out:
import { useMoonKey } from '@moon-key/react-auth';
import { useState } from 'react';

function LogoutWithConfirmation() {
  const { logout } = useMoonKey();
  const [showConfirm, setShowConfirm] = useState(false);

  const handleLogout = async () => {
    await logout();
    setShowConfirm(false);
  };

  return (
    <>
      <button onClick={() => setShowConfirm(true)}>
        Log out
      </button>

      {showConfirm && (
        <div className="modal">
          <p>Are you sure you want to log out?</p>
          <button onClick={handleLogout}>Yes, log out</button>
          <button onClick={() => setShowConfirm(false)}>Cancel</button>
        </div>
      )}
    </>
  );
}

Logout with Loading State

Show a loading state during logout:
import { useMoonKey } from '@moon-key/react-auth';
import { useState } from 'react';

function LogoutButton() {
  const { logout } = useMoonKey();
  const [isLoggingOut, setIsLoggingOut] = useState(false);

  const handleLogout = async () => {
    setIsLoggingOut(true);
    try {
      await logout();
      // Redirect or show success message
    } catch (error) {
      console.error('Logout failed:', error);
    } finally {
      setIsLoggingOut(false);
    }
  };

  return (
    <button onClick={handleLogout} disabled={isLoggingOut}>
      {isLoggingOut ? 'Logging out...' : 'Log out'}
    </button>
  );
}

Logout in Header/Navigation

Common pattern for a header component:
import { useMoonKey } from '@moon-key/react-auth';
import { useRouter } from 'next/router';

function Header() {
  const { ready, isAuthenticated, user, logout } = useMoonKey();
  const router = useRouter();

  const handleLogout = async () => {
    await logout();
    router.push('/');
  };

  if (!ready) {
    return <header>Loading...</header>;
  }

  return (
    <header>
      <nav>
        <a href="/">Home</a>
        {isAuthenticated ? (
          <>
            <span>Welcome, {user.email}!</span>
            <button onClick={handleLogout}>Logout</button>
          </>
        ) : (
          <a href="/login">Login</a>
        )}
      </nav>
    </header>
  );
}

Logout with Redirect

Redirect to a specific page after logout:
import { useMoonKey } from '@moon-key/react-auth';
import { useRouter } from 'next/router';

function LogoutButton() {
  const { logout } = useMoonKey();
  const router = useRouter();

  const handleLogout = async () => {
    await logout();
    // Redirect to home page or login page
    router.push('/login');
  };

  return (
    <button onClick={handleLogout}>
      Log out
    </button>
  );
}
Common pattern for user menus:
import { useMoonKey } from '@moon-key/react-auth';
import { useState } from 'react';

function UserMenu() {
  const { user, logout } = useMoonKey();
  const [isOpen, setIsOpen] = useState(false);

  const handleLogout = async () => {
    setIsOpen(false);
    await logout();
  };

  return (
    <div className="user-menu">
      <button onClick={() => setIsOpen(!isOpen)}>
        {user.email}
      </button>

      {isOpen && (
        <div className="dropdown">
          <a href="/profile">Profile</a>
          <a href="/settings">Settings</a>
          <button onClick={handleLogout}>Log out</button>
        </div>
      )}
    </div>
  );
}

Effect of Logout

When you call logout(), MoonKey will:
  1. Clear the session - Remove session tokens and JWTs from IndexedDB
  2. Reset authentication state - Set isAuthenticated to false
  3. Clear user data - Remove the user object from the SDK state
  4. Revoke session on server - Invalidate the session on MoonKey’s backend
After logout, the user will need to authenticate again to access protected resources.

Using the REST API

For backend or custom implementations, you can logout by deleting the session via the REST API:
curl -X DELETE "https://api.moonkey.fun/v1/auth/sessions/delete" \
  -H "Authorization: Bearer sk_test_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "session_token": "session_abc123..."
  }'

Backend Implementation

// Express.js example
app.post('/api/logout', async (req, res) => {
  const sessionToken = req.cookies.session_token;

  if (!sessionToken) {
    return res.status(400).json({ error: 'No session found' });
  }

  try {
    const response = await fetch(
      'https://api.moonkey.fun/v1/auth/sessions/delete',
      {
        method: 'DELETE',
        headers: {
          'Authorization': `Bearer ${process.env.MOONKEY_SECRET_KEY}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          session_token: sessionToken
        })
      }
    );

    if (!response.ok) {
      throw new Error('Failed to delete session');
    }

    // Clear the cookie
    res.clearCookie('session_token');
    
    res.json({ success: true });
  } catch (error) {
    res.status(500).json({ error: 'Logout failed' });
  }
});

Best Practices

Always Handle Errors

Logout can fail due to network issues or other reasons:
const handleLogout = async () => {
  try {
    await logout();
    console.log('Logout successful');
  } catch (error) {
    console.error('Logout failed:', error);
    // Still clear local state and redirect
    // The session will be invalid on the server anyway
  }
};

Clear Local State

If you have additional local state, clear it on logout:
const handleLogout = async () => {
  await logout();
  
  // Clear any local storage
  localStorage.removeItem('user_preferences');
  
  // Reset any app state
  resetAppState();
  
  // Redirect
  router.push('/');
};

Redirect After Logout

Always redirect users to an appropriate page after logout:
const handleLogout = async () => {
  await logout();
  router.push('/'); // or '/login'
};

Show Confirmation for Important Actions

For applications with unsaved data, confirm before logging out:
const handleLogout = async () => {
  if (hasUnsavedChanges) {
    const confirmed = window.confirm(
      'You have unsaved changes. Are you sure you want to log out?'
    );
    if (!confirmed) return;
  }
  
  await logout();
  router.push('/');
};