> For the complete documentation index, see [llms.txt](https://sdkdocs.deva.me/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sdkdocs.deva.me/hooks-api/use-deva.md).

# useDeva

React hook for accessing authentication state and user information.

***

## Import

```typescript
import { useDeva } from "@bitplanet/deva-sdk";
```

***

## Relationship with DevaProvider

`useDeva` and `DevaProvider` work together as a React Context pattern:

**DevaProvider** (Component):

* Wraps your application at the root level
* Manages OAuth authentication flow
* Handles token refresh automatically
* Stores authentication state in React Context
* Provides configuration (clientId, redirectUri, env)

**useDeva** (Hook):

* Consumes the Context created by DevaProvider
* Provides a simplified API for child components
* Returns only essential properties for application use
* Cannot be used outside of DevaProvider

**Relationship:**

```tsx
<DevaProvider clientId="..." redirectUri="..." env="...">
  {/* DevaProvider creates and manages auth state */}

  <MyComponent />
  {/* useDeva() accesses the auth state */}
</DevaProvider>
```

Think of it as:

* **DevaProvider** = Authentication engine (does the work)
* **useDeva** = Dashboard (shows you the results)

[Learn more about DevaProvider →](/api-reference/deva-provider.md)

***

## What It Does

Provides access to:

* User authentication status
* User profile information
* Login/logout functions
* Access token for API calls

Must be used inside a `DevaProvider` component.

***

## Basic Usage

```tsx
import { useDeva } from "@bitplanet/deva-sdk";

function MyComponent() {
  const { isAuthenticated, user, login, logout } = useDeva();

  if (!isAuthenticated) {
    return <button onClick={login}>Login with Deva</button>;
  }

  return (
    <div>
      <p>Welcome, {user?.persona?.display_name}!</p>
      <button onClick={logout}>Logout</button>
    </div>
  );
}
```

***

## Return Values

```typescript
interface UseDevaReturn {
  isAuthenticated: boolean;       // Is user logged in?
  isReady: boolean;              // Is SDK initialized?
  user: UserInfo | null;         // User profile data
  accessToken: string | null;    // JWT token for API calls
  login: () => Promise<void>;    // Start login flow
  logout: () => Promise<void>;   // End session
}
```

### isAuthenticated

**Type:** `boolean`

Indicates whether the user is currently authenticated.

**Values:**

* `true` - User has valid access token
* `false` - User not logged in or token expired

**Usage:** Check if user is logged in

```typescript
const { isAuthenticated } = useDeva();

if (isAuthenticated) {
  return <Dashboard />;
}
return <LoginPage />;
```

***

### isReady

**Type:** `boolean` Indicates whether the SDK has finished initializing.

**Values:**

* `true` - SDK initialization complete, safe to check authentication
* `false` - SDK still loading OpenID configuration

**Usage:** Check if SDK finished initializing

**Important:** Always check `isReady` before using `isAuthenticated`

```typescript
const { isReady, isAuthenticated } = useDeva();

if (!isReady) {
  return <div>Loading...</div>;
}

if (!isAuthenticated) {
  return <LoginPage />;
}

return <App />;
```

***

### user

**Type:** `UserInfo | null`

Complete user information including profile and persona data.

**Contains:**

```typescript
interface UserInfo {
  sub: string;                 // User ID
  preferred_username: string;  // Username
  email?: string;             // Email
  email_verified?: boolean;   // Email verified?
  picture?: string;           // Profile picture URL
  persona: {
    id: string;
    username: string;
    display_name: string;
    avatar: string;
    bio?: string;
  };
}
```

**Usage:**

```typescript
const { user } = useDeva();

return (
  <div>
    <img src={user?.persona.avatar} />
    <h2>{user?.persona.display_name}</h2>
    <p>@{user?.preferred_username}</p>
  </div>
);
```

***

### accessToken

**Type:** `string | null`

The current OAuth access token.

**Values:**

* JWT string when authenticated
* `null` when not authenticated

**Usage:** Include in API requests

```typescript
const { accessToken } = useDeva();

// Use for custom API calls
if (accessToken) {
  fetch("https://api.deva.me/custom", {
    headers: {
      Authorization: `Bearer ${accessToken}`
    }
  });
}
```

**Note:** SDK components automatically include the token. You only need this for custom API calls.

***

### login

**Type:** `() => Promise<void>`

Initiates the OAuth 2.0 authentication flow.

**Usage:** Initiate OAuth login flow

```tsx
const { login } = useDeva();

<button onClick={login}>Sign in with Deva</button>
```

**What happens:**

1. Redirects user to Deva login page
2. User authenticates
3. Redirects back to your app
4. SDK exchanges code for tokens
5. `isAuthenticated` becomes `true`

***

### logout

**Type:** `() => Promise<void>`

Revokes tokens and clears authentication state.

**Usage:** End user session

```typescript
const { logout } = useDeva();

<button onClick={logout}>Logout</button>
```

**What happens:**

1. Revokes tokens on server
2. Clears local session data
3. `isAuthenticated` becomes `false`
4. `user` becomes `null`

***

## Common Patterns

### Protected Route

```tsx
function ProtectedRoute({ children }) {
  const { isReady, isAuthenticated, login } = useDeva();

  if (!isReady) {
    return <div>Loading...</div>;
  }

  if (!isAuthenticated) {
    return <button onClick={login}>Login Required</button>;
  }

  return <>{children}</>;
}
```

***

### User Profile Display

```tsx
function UserProfile() {
  const { user, isAuthenticated } = useDeva();

  if (!isAuthenticated || !user) {
    return null;
  }

  return (
    <div>
      <img src={user.persona.avatar} alt={user.preferred_username} />
      <h3>{user.persona.display_name}</h3>
      <p>@{user.preferred_username}</p>
      {user.email_verified && <span>✓ Verified</span>}
    </div>
  );
}
```

***

### Login/Logout Toggle

```tsx
function AuthButton() {
  const { isAuthenticated, user, login, logout } = useDeva();

  return isAuthenticated ? (
    <button onClick={logout}>
      Logout ({user?.preferred_username})
    </button>
  ) : (
    <button onClick={login}>Login</button>
  );
}
```

***

### Custom API Call

```tsx
function CustomData() {
  const { accessToken, isAuthenticated } = useDeva();
  const [data, setData] = useState(null);

  const fetchData = async () => {
    if (!isAuthenticated || !accessToken) return;

    const response = await fetch("/api/custom", {
      headers: {
        Authorization: `Bearer ${accessToken}`,
      },
    });

    setData(await response.json());
  };

  return <button onClick={fetchData}>Fetch Data</button>;
}
```

***

## Important Notes

### Must Use Inside DevaProvider

```tsx
// ❌ Error: useDeva must be used within a DevaProvider
function App() {
  const { user } = useDeva(); // Will throw error
  return <div>{user?.name}</div>;
}
```

```tsx
// ✅ Correct
import { DevaProvider } from "@bitplanet/deva-sdk";

function App() {
  return (
    <DevaProvider clientId="..." redirectUri="..." env="...">
      <MyComponent /> {/* Can use useDeva here */}
    </DevaProvider>
  );
}
```

***

### Always Check isReady First

```tsx
// ❌ Bad: May flash wrong state during initialization
const { isAuthenticated } = useDeva();
if (!isAuthenticated) return <Login />;
```

```tsx
// ✅ Good: Wait for SDK to initialize
const { isReady, isAuthenticated } = useDeva();
if (!isReady) return <Loading />;
if (!isAuthenticated) return <Login />;
```

***

### Handle Null User

```tsx
// ✅ Use optional chaining
const displayName = user?.persona.display_name || "Guest";
const avatar = user?.picture || user?.persona.avatar || "/default.png";
```

***

## TypeScript

Full type definitions:

```typescript
import { useDeva } from "@bitplanet/deva-sdk";
import type { UserInfo } from "@bitplanet/deva-sdk";

interface UseDevaReturn {
  isAuthenticated: boolean;
  isReady: boolean;
  accessToken: string | null;
  user: UserInfo | null;
  login: () => Promise<void>;
  logout: () => Promise<void>;
}

const useDeva: () => UseDevaReturn;
```

***

## Related Documentation

* [DevaProvider Setup](/api-reference/deva-provider.md)
* [Authentication Flow](/core-concepts/authentication-flow.md)
* [User Types](/api-reference/user-types.md)
* [Quickstart Guide](/getting-started/quickstart.md)
