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

# React

> Client-side React integration with Timeback

## Overview

The Timeback SDK provides React hooks, components, and a context provider for client-side integration.

If you are using coding agents, pair this page with [`timeback-client`](https://github.com/superbuilders/timeback-sdk-skills/tree/main/skills/timeback/timeback-client) from the [AI Skills](/beta/build-on-timeback/ai/skills) catalog.

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install @timeback/sdk
  ```

  ```bash pnpm theme={null}
  pnpm add @timeback/sdk
  ```

  ```bash yarn theme={null}
  yarn add @timeback/sdk
  ```

  ```bash bun theme={null}
  bun add @timeback/sdk
  ```
</CodeGroup>

## Provider Setup

Wrap your app with `TimebackProvider`:

```tsx app/providers.tsx theme={null}
'use client'

import { TimebackProvider } from '@timeback/sdk/react'

export function Providers({ children }: { children: React.ReactNode }) {
	return <TimebackProvider>{children}</TimebackProvider>
}
```

```tsx app/layout.tsx theme={null}
import { Providers } from './providers'

export default function RootLayout({ children }) {
	return (
		<html>
			<body>
				<Providers>{children}</Providers>
			</body>
		</html>
	)
}
```

## Hooks

### `useTimeback`

Access the Timeback client:

```tsx theme={null}
import { useTimeback } from '@timeback/sdk/react'

function MyComponent() {
	const timeback = useTimeback()

	// timeback is null if user is not authenticated
	if (!timeback) {
		return <div>Please sign in</div>
	}

	return <div>Welcome!</div>
}
```

### `useTimebackVerification`

Check authentication status:

```tsx theme={null}
import { useTimebackVerification } from '@timeback/sdk/react'

function ProtectedRoute({ children }) {
	const { state, refresh } = useTimebackVerification()

	if (state.status === 'loading') return <div>Loading...</div>
	if (state.status !== 'verified') return <Navigate to="/login" />

	return children
}
```

The `state` object has a `status` property that can be:

* `'loading'` - Verification in progress
* `'verified'` - User is verified (includes `timebackId`)
* `'unverified'` - User is not verified
* `'error'` - Verification failed (includes `message`)

### `useTimebackProfile`

Fetch user profile data:

```tsx theme={null}
import { useTimebackProfile } from '@timeback/sdk/react'

// Manual fetch
function ProfileButton() {
	const { state, canFetch, fetchProfile } = useTimebackProfile()

	if (state.status === 'loaded') {
		return (
			<div>
				<p>Welcome, {state.profile.name}</p>
				<p>XP Today: {state.profile.xp.today}</p>
				<p>Total XP: {state.profile.xp.all}</p>
			</div>
		)
	}

	return (
		<button onClick={fetchProfile} disabled={!canFetch}>
			{state.status === 'loading' ? 'Loading...' : 'Load Profile'}
		</button>
	)
}

// Auto-fetch when authenticated
function AutoProfile() {
	const { state } = useTimebackProfile({ auto: true })

	if (state.status === 'loading') return <div>Loading...</div>
	if (state.status === 'loaded') {
		return <div>XP: {state.profile.xp.today}</div>
	}

	return null
}
```

## Components

### `SignInButton`

Pre-built sign-in button:

```tsx theme={null}
import { SignInButton } from '@timeback/sdk/react'

function LoginPage() {
	return (
		<div>
			<h1>Welcome</h1>
			<SignInButton size="lg">Sign in with Timeback</SignInButton>
		</div>
	)
}
```

#### Props

<ParamField body="size" type="'sm' | 'md' | 'lg'" default="'md'">
  Button size
</ParamField>

<ParamField body="variant" type="'default' | 'outline'" default="'default'">
  Button style variant
</ParamField>

<ParamField body="showLoading" type="boolean" default="true">
  Show loading spinner on click
</ParamField>

<ParamField body="showLogo" type="boolean" default="true">
  Show Timeback logo
</ParamField>

<ParamField body="disabled" type="boolean" default="false">
  Disable the button
</ParamField>

<ParamField body="className" type="string">
  Additional CSS classes
</ParamField>

<ParamField body="style" type="CSSProperties">
  Inline styles
</ParamField>

<ParamField body="onClick" type="() => void">
  Additional click handler
</ParamField>

<ParamField body="children" type="ReactNode" default="'Sign In'">
  Button text
</ParamField>

## Custom Activities

The SDK supports two [activity models](/beta/about-timeback/concepts/activity-models) that capture how students spend time in your app and whether they complete what they started, producing [TimeSpentEvents](/beta/build-on-timeback/reference/events#timespentevent) and [ActivityCompletedEvents](/beta/build-on-timeback/reference/events#activitycompletedevent) that feed into dashboards, XP, and learning analytics.

### Single-session

A quiz, flashcard deck, or short lesson that a student completes in one sitting. The client tracks time and reports completion. Learn more about [single-session activities](/beta/build-on-timeback/sdk/activity-tracking/single-session).

### Stateful

A multi-part course or long-form project where students leave and come back across multiple sessions. The client tracks time per visit while the server records completion. Learn more about [stateful activities](/beta/build-on-timeback/sdk/activity-tracking/stateful).

## Next Steps

<CardGroup cols={2}>
  <Card title="Next.js Server" href="/beta/build-on-timeback/sdk/server/nextjs">
    Server-side setup
  </Card>

  <Card title="Custom Activities" href="/beta/build-on-timeback/sdk/activity-tracking/intro">
    Learn more about tracking
  </Card>
</CardGroup>
