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

# Hooks (useBasic, useQuery)

# useBasic

The `useBasic` hook is used to access authentication, database, and other Basic features.

Any of these properties can be accessed by destructuring the `useBasic` hook.

## Auth State

### isReady

<ParamField query="isReady" type="boolean">
  Boolean that indicates when auth state has been determined. Use this as a loading state for your app while auth is being verified.

  ```tsx App.tsx theme={null}
  import { useBasic } from '@basictech/react'

  function App() {
    const { isReady, isSignedIn } = useBasic()

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

    return (
      <div>{isSignedIn ? "User is signed in" : "User is signed out"}</div>
    )
  }
  ```

  <Note>`isAuthReady` is a deprecated alias for `isReady` and will be removed in a future version.</Note>
</ParamField>

### isSignedIn

<ParamField query="isSignedIn" type="boolean">
  Boolean that checks if a user is signed in. Only use after `isReady` is true.

  ```tsx App.tsx theme={null}
  import { useBasic } from '@basictech/react'

  function App() {
    const { isReady, isSignedIn } = useBasic()

    return (
      <>
        {isReady ? 
          <div>{isSignedIn ? "User is signed in" : "User is signed out"}</div> :
          <div>Loading...</div>
        }
      </>
    )
  }
  ```
</ParamField>

### user

<ParamField query="user" type="User | null">
  The current user object containing the user's ID, email, and name. Returns `null` when not signed in.

  ```tsx App.tsx theme={null}
  import { useBasic } from '@basictech/react'

  function App() {
    const { user } = useBasic()

    console.log("Fetch user ID: ", user?.id)
    console.log("Fetch user email: ", user?.email)
    console.log("Fetch user name: ", user?.name)

    return (
      <>
        {/* render items */}
      </>
    )
  }
  ```

  **User type** (fields present depend on IdP / userinfo):

  ```typescript theme={null}
  type User = {
    sub?: string
    name?: string
    email?: string
    picture?: string
  }
  ```
</ParamField>

### did

<ParamField query="did" type="string | null">
  The authenticated user's Decentralized Identifier when available; `null` when not signed in or not provided by the identity layer.
</ParamField>

### scope

<ParamField query="scope" type="string | null">
  Space-separated OAuth scopes granted on the current access token (for example `profile` plus datastore scopes). Use `hasScope` and `missingScopes` for fine-grained checks.
</ParamField>

### hasScope

<ParamField query="hasScope" type="(scope: string) => boolean">
  Returns whether a given scope string is included on the current token.
</ParamField>

### missingScopes

<ParamField query="missingScopes" type="() => string[]">
  Returns scopes your app requested (via provider configuration) that are not yet granted on the current token — useful for prompting re-consent.
</ParamField>

## Auth Methods

### signIn

<ParamField query="signIn" type="() => Promise<void>">
  Function to sign a user in via the Basic OAuth flow. It will redirect the user to the Basic login page, and then redirect them back to the page they were on.

  ```tsx App.tsx theme={null}
  import { useBasic } from '@basictech/react'

  function App() {
    const { signIn } = useBasic()

    return (
      <>
        <button onClick={signIn}>Sign in</button>
      </>
    )
  }
  ```

  <Note>`signin` (lowercase) is a deprecated alias for `signIn` and will be removed in a future version.</Note>
</ParamField>

### signInWithHandle

<ParamField query="signInWithHandle" type="(handle: string) => Promise<void>">
  Starts sign-in using a user handle (resolved to a DID server-side). Useful for handle-based login flows in addition to the default `signIn()` redirect.
</ParamField>

### signOut

<ParamField query="signOut" type="() => Promise<void>">
  Function to sign a user out. User remains on your page after signing out, but `isSignedIn` will be set to false until they sign in again.

  ```tsx App.tsx theme={null}
  import { useBasic } from '@basictech/react'

  function App() {
    const { signOut } = useBasic()

    return (
      <>
        <button onClick={signOut}>Sign out</button>
      </>
    )
  }
  ```

  <Note>`signout` (lowercase) is a deprecated alias for `signOut` and will be removed in a future version.</Note>
</ParamField>

### signInWithCode

<ParamField query="signInWithCode" type="(code: string, state?: string) => Promise<AuthResult>">
  Function to complete authentication using an OAuth authorization code. Useful for custom OAuth flows or React Native apps where you handle the redirect manually.

  ```tsx App.tsx theme={null}
  import { useBasic } from '@basictech/react'

  function App() {
    const { signInWithCode } = useBasic()

    const handleOAuthCallback = async (code: string, state: string) => {
      const result = await signInWithCode(code, state)
      if (result.success) {
        console.log('Signed in successfully!')
      } else {
        console.error('Sign in failed:', result.error)
      }
    }

    return <>{/* OAuth callback handling */}</>
  }
  ```

  **AuthResult type:**

  ```typescript theme={null}
  type AuthResult = {
    success: boolean
    error?: string
    code?: string
  }
  ```
</ParamField>

### getToken

<ParamField query="getToken" type="(options?: { forceRefresh?: boolean }) => Promise<string>">
  Fetches the user's JWT access token. The token is automatically refreshed when needed. Pass `{ forceRefresh: true }` to obtain a new token from the server even if the current one is still valid. Use this for authenticated calls to your backend or the Basic APIs.

  ```tsx App.tsx theme={null}
  import { useBasic } from '@basictech/react'

  function App() {
    const { getToken } = useBasic()

    const fetchFromMyAPI = async () => {
      const token = await getToken()
      const response = await fetch('/api/my-endpoint', {
        headers: { 'Authorization': `Bearer ${token}` }
      })
      return response.json()
    }

    return (
      <>
        <button onClick={async () => console.log(await getToken())}>Get token</button>
      </>
    )
  }
  ```
</ParamField>

### getSignInUrl

<ParamField query="getSignInUrl" type="(redirectUri?: string) => Promise<string>">
  Returns the OAuth sign-in URL without redirecting. Useful for custom sign-in flows, React Native apps, or opening in a popup/modal.

  ```tsx App.tsx theme={null}
  import { useBasic } from '@basictech/react'

  function App() {
    const { getSignInUrl } = useBasic()

    const handleCustomSignIn = async () => {
      const url = await getSignInUrl()
      // Open in popup, new tab, or handle as needed
      window.open(url, '_blank')
    }

    return <button onClick={handleCustomSignIn}>Custom Sign In</button>
  }
  ```

  <Note>`getSignInLink` is a deprecated alias for `getSignInUrl` and will be removed in a future version.</Note>
</ParamField>

## Development & schema status

### devInfo

<ParamField query="devInfo" type="BasicSchemaDevInfo | null">
  Snapshot comparing your local `basic.config` schema to the project schema on the server (project id, version, validity, last check). Intended for debugging and the dev toolbar; `null` if no schema is configured on the provider.
</ParamField>

### refreshSchemaStatus

<ParamField query="refreshSchemaStatus" type="() => Promise<void>">
  Re-runs the remote schema check and updates `devInfo`. Used by the dev toolbar and custom diagnostics UIs.
</ParamField>

## Database

### db

<ParamField query="db" type="BasicDB">
  The database object, which you can use to [read, add, update, and delete items](/sdk-reference/react-db).
</ParamField>

### dbStatus

<ParamField query="dbStatus" type="DBStatus">
  The current status of the database connection (string enum). Possible values include:

  * `'LOADING'` — Initializing
  * `'CONNECTING'` — Connecting to the sync server
  * `'ONLINE'` — Connected and syncing
  * `'SYNCING'` — Actively syncing
  * `'OFFLINE'` — No network (local data may still be available in sync mode)
  * `'ERROR_WILL_RETRY'` — Non-fatal error; will retry
  * `'ERROR_TOKEN_EXPIRED'` — Auth token expired for sync; refresh or sign in again
  * `'ERROR'` — Fatal error

    ```tsx App.tsx theme={null}
    import { useBasic } from '@basictech/react'

    function App() {
      const { dbStatus } = useBasic()

      return (
        <div>
          Database status: {dbStatus}
          {dbStatus === 'OFFLINE' && <span> (Working offline)</span>}
        </div>
      )
    }
    ```
</ParamField>

### dbMode

<ParamField query="dbMode" type="'sync' | 'remote'">
  The current database mode. See [Database Modes](/basic-nextjs/nextjs-modes) for details.

  * `'sync'` - Local-first with IndexedDB + real-time WebSocket sync (default)
  * `'remote'` - Direct REST API calls to server
</ParamField>

***

# useQuery

The `useQuery` hook is used to "subscribe" to data from the database, so that your component automatically re-renders when the data changes. It enables real-time sync between the local database, users' devices, and all other users connected to the same database.

<Note>`useQuery` only works in sync mode. In remote mode, use regular async/await patterns instead.</Note>

We use it primarily to wrap our `.get()` and `.getAll()` functions, and it takes a function as an argument.

```tsx theme={null}
import { useBasic, useQuery } from '@basictech/react'

function App() {
  const { db } = useBasic()

  // Example 1: Fetch a single item from the table
  const item = useQuery(() => db.collection('tablename').get('ID_OF_ITEM'))

  // Example 2: Fetch all items from the table
  const items = useQuery(() => db.collection('tablename').getAll())

  return (
    // render items
  )
}
```

<Info>The default value is an empty array `[]` while data is loading. This may change in a future version.</Info>
