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

# Guest Mode

> Enable guest mode to support unauthenticated users with fingerprinting

Guest mode allows your application to work with both authenticated and unauthenticated users, providing a seamless experience with built-in fingerprint-based guest IDs.

## Overview

When guest mode is enabled:

* Unauthenticated users automatically get a unique guest ID
* Guest IDs are stored in the `guest_logto_authtoken` cookie for persistence
* Your app can track guest users across sessions
* Guest users can later sign in without losing their data

## Frontend Setup

Use the `useAuth` hook with the `guest` middleware:

```tsx theme={null}
import { useAuth } from '@ouim/logto-authkit'

function MixedContent() {
  const { user } = useAuth({
    middleware: 'guest', // Allow guest users
  })

  return (
    <div>
      {user ? (
        <p>Welcome back, {user.name}!</p>
      ) : (
        <p>You're browsing as a guest</p>
      )}
    </div>
  )
}
```

### Middleware Options

The `useAuth` hook supports different middleware modes:

<ParamField path="middleware" type="'auth' | 'guest'">
  * `'auth'`: Require authentication (redirect if not logged in)
  * `'guest'`: Allow both authenticated and guest users
</ParamField>

<ParamField path="redirectTo" type="string">
  URL to redirect to when authentication is required (used with `middleware: 'auth'`)
</ParamField>

### Route Protection with Auth Middleware

```tsx theme={null}
function ProtectedPage() {
  const { user } = useAuth({
    middleware: 'auth',
    redirectTo: '/login', // Redirect if not authenticated
  })

  if (!user) return null // or loading indicator
  
  return <div>Protected content for {user.name}</div>
}
```

## Server Setup

Enable guest mode in your server authentication middleware:

### Express.js

```javascript theme={null}
import { createExpressAuthMiddleware } from '@ouim/logto-authkit/server'

const authMiddleware = createExpressAuthMiddleware({
  logtoUrl: 'https://your-logto-domain.com',
  audience: 'your-api-resource-identifier',
  cookieName: 'logto_authtoken',
  allowGuest: true, // Enable guest mode
})

app.get('/api/content', authMiddleware, (req, res) => {
  res.json({
    userId: req.auth.userId,
    isAuthenticated: req.auth.isAuthenticated,
    isGuest: req.auth.isGuest,
    guestId: req.auth.guestId, // Available when isGuest is true
  })
})
```

### Next.js API Routes

```javascript theme={null}
import { verifyNextAuth } from '@ouim/logto-authkit/server'

export async function GET(request) {
  const authResult = await verifyNextAuth(request, {
    logtoUrl: 'https://your-logto-domain.com',
    audience: 'your-api-resource-identifier',
    allowGuest: true, // Enable guest mode
  })

  if (!authResult.success) {
    return Response.json({ error: authResult.error }, { status: 401 })
  }

  return Response.json({
    userId: authResult.auth.userId,
    isAuthenticated: authResult.auth.isAuthenticated,
    isGuest: authResult.auth.isGuest,
    guestId: authResult.auth.guestId,
  })
}
```

## Auth Context Structure

When guest mode is enabled, the auth context includes additional fields:

```typescript theme={null}
interface AuthContext {
  userId: string | null        // User ID from token (null for guests)
  isAuthenticated: boolean     // true for authenticated users
  isGuest: boolean            // true for guest users
  payload: AuthPayload | null // Full JWT payload (null for guests)
  guestId?: string            // Guest fingerprint ID (when allowGuest is true)
}
```

## How Guest IDs Work

<Steps>
  <Step title="Guest ID Generation">
    When a user visits your site without authentication, logto-authkit automatically generates a unique guest ID using browser fingerprinting.
  </Step>

  <Step title="Persistence">
    The guest ID is stored in the browser's `guest_logto_authtoken` cookie, ensuring the same ID is used across sessions.
  </Step>

  <Step title="Server Verification">
    When `allowGuest: true` is set, the server helpers can return a guest auth context when no valid JWT token is available, using the guest cookie to persist the guest ID.
  </Step>

  <Step title="Upgrade to Authenticated">
    When a guest user signs in, they receive a proper JWT token. You can associate their previous guest activity with their authenticated account using the guest ID.
  </Step>
</Steps>

## Use Cases

<CardGroup cols={2}>
  <Card title="Shopping Cart" icon="cart-shopping">
    Allow users to add items to cart before signing in, then associate the cart with their account after login.
  </Card>

  <Card title="Content Personalization" icon="sparkles">
    Track guest preferences and browsing history, then merge with their profile when they sign in.
  </Card>

  <Card title="Analytics" icon="chart-line">
    Track user behavior for both authenticated and guest users with a consistent identifier.
  </Card>

  <Card title="Gradual Onboarding" icon="stairs">
    Let users explore your app as guests, then prompt them to sign in when they need advanced features.
  </Card>
</CardGroup>

## Example: Tracking Guest to User Conversion

```tsx theme={null}
import { useAuth } from '@ouim/logto-authkit'
import { useEffect, useState } from 'react'

function ProductPage() {
  const { user, isLoadingUser } = useAuth({ middleware: 'guest' })
  const [guestId, setGuestId] = useState<string | null>(null)

  useEffect(() => {
    // Store guest ID before user signs in
    if (!user && typeof window !== 'undefined') {
      const storedGuestId = document.cookie
        .split('; ')
        .find((entry) => entry.startsWith('guest_logto_authtoken='))
        ?.split('=')[1] ?? null
      setGuestId(storedGuestId)
    }
  }, [user])

  useEffect(() => {
    // User just signed in - migrate guest data
    if (user && guestId) {
      migrateGuestData(guestId, user.id)
      setGuestId(null)
    }
  }, [user, guestId])

  async function migrateGuestData(guestId: string, userId: string) {
    // Call your API to associate guest data with the user
    await fetch('/api/migrate-guest-data', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ guestId, userId }),
    })
  }

  if (isLoadingUser) return <div>Loading...</div>

  return (
    <div>
      {user ? (
        <p>Welcome back, {user.name}!</p>
      ) : (
        <p>Browsing as guest (ID: {guestId})</p>
      )}
    </div>
  )
}
```

<Warning>
  Guest IDs are stored in a browser cookie and can still be cleared by the user. Don't rely on them for critical functionality or security. They're best used for convenience features like cart persistence.
</Warning>

## Configuration Options

<ParamField path="allowGuest" type="boolean" default="false">
  Enable guest mode in server middleware
</ParamField>

<ParamField path="cookieName" type="string" default="'logto_authtoken'">
  Custom cookie name for both JWT tokens and guest IDs
</ParamField>

## Next Steps

<CardGroup cols={2}>
  <Card title="Server Authentication" icon="shield" href="/logto-authkit/server/overview">
    Learn more about server authentication
  </Card>

  <Card title="useAuth Hook" icon="hook" href="/logto-authkit/frontend/use-auth">
    Explore all useAuth hook options
  </Card>
</CardGroup>
