React Native
The SDK runs on React Native and Expo with no polyfills. It avoids the APIs Hermes lacks or only partly implements
(URL, URLSearchParams, DOMException), and its react-native entry points Metro at the right build.
There are no cookies to lean on in an app, so you keep the learner's tokens yourself.
Install
npx expo install @learnhouse/sdk expo-secure-storeCreate the client with getToken
import * as SecureStore from 'expo-secure-store'
import { createClient } from '@learnhouse/sdk'
export const lh = createClient({
baseUrl: 'https://learn.your-school.com',
getToken: () => SecureStore.getItemAsync('lh_access'),
})getToken runs before every request, so a refreshed token is picked up immediately.
Sign in
const res = await lh.auth.login({ email, password })
if (res.mfa_required) {
// Show a code field, then: await lh.auth.loginMfa({ mfaToken: res.mfa_token, code })
} else {
await SecureStore.setItemAsync('lh_access', res.tokens.access_token)
await SecureStore.setItemAsync('lh_refresh', res.tokens.refresh_token)
}Refresh before the access token expires
Access tokens last 8 hours. Refresh tokens are single-use: always store the new one.
export async function refreshSession() {
const refreshToken = await SecureStore.getItemAsync('lh_refresh')
if (!refreshToken) return false
try {
const tokens = await lh.auth.refresh({ refreshToken })
await SecureStore.setItemAsync('lh_access', tokens.access_token)
await SecureStore.setItemAsync('lh_refresh', tokens.refresh_token)
return true
} catch {
await SecureStore.deleteItemAsync('lh_access')
await SecureStore.deleteItemAsync('lh_refresh')
return false // send the learner to sign in again
}
}Using it
const trail = await lh.trail.get() // the learner's courses and progress
const course = await lh.courses.getMeta('course_…', { slim: true })
await lh.trail.completeActivity('activity_…') // mark a lesson doneNever ship an lh_ API token inside an app: anyone can extract it from the bundle. Apps act as the signed-in
learner, with their own tokens.
Showing lessons
@learnhouse/react renders with the DOM, so it doesn't run in React Native views. In an app, show a lesson in a
WebView pointed at its embed URL, or build native screens from the activity's content with the
SDK.