# 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)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sdkdocs.deva.me/hooks-api/use-deva.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
