Skip to main content

Overview

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

Installation

npm install @timeback/sdk

Provider Setup

Wrap your app with TimebackProvider:
app/providers.tsx
'use client'

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

export function Providers({ children }: { children: React.ReactNode }) {
	return <TimebackProvider>{children}</TimebackProvider>
}
app/layout.tsx
import { Providers } from './providers'

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

Hooks

useTimeback

Access the Timeback client:
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:
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:
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:
import { SignInButton } from '@timeback/sdk/react'

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

Props

size
'sm' | 'md' | 'lg'
default:"'md'"
Button size
variant
'default' | 'outline'
default:"'default'"
Button style variant
showLoading
boolean
default:"true"
Show loading spinner on click
Show Timeback logo
disabled
boolean
default:"false"
Disable the button
className
string
Additional CSS classes
style
CSSProperties
Inline styles
onClick
() => void
Additional click handler
children
ReactNode
default:"'Sign In'"
Button text

Activity Tracking

Track learning activities:
import { useTimeback } from '@timeback/sdk/react'
import { useEffect } from 'react'

function LessonPage({ lessonId, lessonName }) {
	const timeback = useTimeback()

	useEffect(() => {
		if (!timeback) return

		const activity = timeback.activity.start({
			id: lessonId,
			name: lessonName,
			course: { subject: 'Math', grade: 3 },
		})

		return () => {
			activity.end({
				totalQuestions: 10,
				correctQuestions: 8,
				xpEarned: 80,
			})
		}
	}, [timeback, lessonId, lessonName])

	return <div>Lesson content...</div>
}

Next Steps