@tenminuteschool/auth-react
v1.0.0
Published
OAuth 2.0 + PKCE browser client for Login with 10MinuteSchool
Readme
@tenminuteschool/auth-react
Add "Login with 10MinuteSchool" to any React app in minutes.
AI Prompt
Copy and paste this into your AI assistant to get a full working implementation:
Implement "Login with 10MinuteSchool" in this project using @tenminuteschool/auth-react.
Steps:
1. Install: npm install @tenminuteschool/auth-react
2. Add to .env.local:
NEXT_PUBLIC_TENMS_CLIENT_ID=YOUR_CLIENT_ID
3. Create lib/auth.ts:
import { TenMSAuth } from '@tenminuteschool/auth-react';
export const CLIENT_ID = process.env.NEXT_PUBLIC_TENMS_CLIENT_ID!;
export const auth = new TenMSAuth({ clientId: CLIENT_ID, storage: 'localStorage' });
4. Create a login page that:
- Imports LoginButton and CLIENT_ID from the files above
- Shows the button with clientId={CLIENT_ID} and onSuccess handler
- In onSuccess, calls auth.handleLoginSuccess(response) then redirects to /dashboard
- If auth.isLoggedIn() on mount, immediately redirects to /dashboard
5. On the dashboard page:
- Get the user with auth.getUser() — it returns { sub, name, email, picture }
- Add a logout button that calls auth.logout() then redirects back to the login page
Do not hardcode the client ID anywhere. Do not change the storage value.Installation
npm install @tenminuteschool/auth-react
# or
pnpm add @tenminuteschool/auth-reactSetup
Add your client ID to .env.local:
NEXT_PUBLIC_TENMS_CLIENT_ID=your_client_id_hereThen create this file once at the root of your project:
// lib/auth.ts
import { TenMSAuth } from '@tenminuteschool/auth-react';
export const CLIENT_ID = process.env.NEXT_PUBLIC_TENMS_CLIENT_ID!;
export const auth = new TenMSAuth({
clientId: CLIENT_ID,
storage: 'localStorage',
});Login Button
import { LoginButton } from '@tenminuteschool/auth-react';
import { auth, CLIENT_ID } from '@/lib/auth';
<LoginButton
clientId={CLIENT_ID}
onSuccess={async (response) => {
const session = await auth.handleLoginSuccess(response);
// session.user → { sub, name, email, picture, ... }
window.location.href = '/dashboard';
}}
onError={(err) => console.error(err)}
/>Button appearance
<LoginButton
clientId={CLIENT_ID}
onSuccess={...}
theme="dark" // 'dark' (default) | 'light'
variant="fill" // 'fill' (default) | 'outline'
size="large" // 'large' (default) | 'medium' | 'small'
text="Sign in" // custom label
/>Reading the session
import { auth } from '@/lib/auth';
auth.isLoggedIn() // true/false — no network call
auth.getUser() // { sub, name, email, picture, ... } or null
await auth.getAccessToken() // valid token string, auto-refreshes if expired
await auth.logout() // revokes token + clears sessionTenMSAuth options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| clientId | string | required | Your registered client ID |
| storage | 'cookie' \| 'localStorage' | 'cookie' | Use localStorage for SPAs, cookie for SSR |
| redirectUri | string | window.location.origin | Override only if needed |
| scopes | string[] | ['profile', 'email', 'phone'] | OAuth scopes |
| debug | boolean | false | Logs every OAuth step to the console |
