> ## Documentation Index
> Fetch the complete documentation index at: https://docs.streambird.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Logging Users Out

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:

```typescript theme={null}
logout: () => Promise<void>
```

### Basic Usage

```tsx theme={null}
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:

```tsx theme={null}
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:

```tsx theme={null}
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:

```tsx theme={null}
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:

```tsx theme={null}
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:

```tsx theme={null}
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>
  );
}
```

### Dropdown Menu with Logout

Common pattern for user menus:

```tsx theme={null}
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:

```bash theme={null}
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

```javascript theme={null}
// 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:

```tsx theme={null}
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:

```tsx theme={null}
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:

```tsx theme={null}
const handleLogout = async () => {
  await logout();
  router.push('/'); // or '/login'
};
```

### Show Confirmation for Important Actions

For applications with unsaved data, confirm before logging out:

```tsx theme={null}
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('/');
};
```
