SDK
React SDK
@authon/react — Authon용 React 컴포넌트와 훅. Create React App, Vite, React 18+ 프로젝트에서 동작합니다.
npm: @authon/reactReact 18+TypeScript
설치
bash
npm install @authon/reactAuthonProvider
앱 루트를 AuthonProvider. 로 감싸세요. 모든 훅과 컴포넌트는 이 프로바이더 안에서 렌더링되어야 합니다.
src/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { AuthonProvider } from "@authon/react";
import App from "./App";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<AuthonProvider publishableKey="pk_live_your_publishable_key">
<App />
</AuthonProvider>
</StrictMode>
);Provider Props
| Prop | 타입 | 설명 |
|---|---|---|
| publishableKey | string | Your pk_live_ or pk_test_ key from the dashboard |
| config.apiUrl | string? | Override the Authon API base URL |
| config.theme | 'light' | 'dark' | 'auto' | Color theme for the modal (default: auto) |
| config.locale | string? | Locale string for the modal UI (default: en) |
| config.appearance | Partial<BrandingConfig>? | Override branding config programmatically |
훅
useAuthon()
인증 상태와 상호작용하는 기본 훅. 모달 열기, 토큰 가져오기, 로그아웃 메서드를 포함한 전체 컨텍스트 값을 반환합니다.
tsx
import { useAuthon } from "@authon/react";
function Header() {
const {
isSignedIn,
isLoading,
user,
openSignIn,
openSignUp,
signOut,
getToken,
} = useAuthon();
if (isLoading) return <Spinner />;
return (
<nav>
{isSignedIn ? (
<>
<span>Hello, {user?.displayName}</span>
<button onClick={() => signOut()}>Sign out</button>
</>
) : (
<button onClick={() => openSignIn()}>Sign in</button>
)}
</nav>
);
}useUser()
사용자 데이터와 로딩 상태만 반환하는 집중된 훅. 사용자 정보만 표시하는 컴포넌트에서 사용하세요.
tsx
import { useUser } from "@authon/react";
function ProfileCard() {
const { user, isLoading } = useUser();
if (isLoading) return <Skeleton />;
if (!user) return null;
return (
<div className="profile-card">
{user.avatarUrl && (
<img src={user.avatarUrl} alt={user.displayName ?? ""} />
)}
<h2>{user.displayName}</h2>
<p>{user.email}</p>
<span>Member since {new Date(user.createdAt).getFullYear()}</span>
</div>
);
}컴포넌트
SignedIn / SignedOut
인증 상태에 따라 자식 컴포넌트를 조건부 렌더링합니다. 수동 조건 없이 인증 인식 UI를 구축하는 가장 쉬운 방법입니다.
tsx
import { SignedIn, SignedOut } from "@authon/react";
function App() {
return (
<>
<SignedIn>
{/* Only rendered when user is signed in */}
<Dashboard />
<UserButton />
</SignedIn>
<SignedOut>
{/* Only rendered when user is NOT signed in */}
<LandingPage />
<SignInButton />
</SignedOut>
</>
);
}SignIn / SignUp
Authon 모달 UI를 트리거합니다. popup 모드에서는 마운트 시 모달이 열립니다. embedded 모드에서는 폼이 인라인으로 렌더링됩니다.
tsx
import { SignIn, SignUp } from "@authon/react";
// Popup — opens the modal when mounted
function LoginPage() {
return <SignIn mode="popup" />;
}
// Embedded — renders a form container in-place
function SignUpPage() {
return (
<div className="flex min-h-screen items-center justify-center">
<SignUp mode="embedded" />
</div>
);
}UserButton
로그아웃 드롭다운이 있는 드롭인 아바타 버튼. 사용자 아바타가 있으면 표시하고, 없으면 그라디언트 배경의 이니셜로 대체합니다. 로그인하지 않은 경우 null 를 반환합니다.
tsx
import { UserButton } from "@authon/react";
function AppHeader() {
return (
<header className="flex items-center justify-between p-4">
<Logo />
<UserButton />
</header>
);
}라우트 보호
useAuthon()와 React Router를 결합하여 비공개 라우트를 보호하세요:
components/ProtectedRoute.tsx
import { Navigate } from "react-router-dom";
import { useAuthon } from "@authon/react";
interface ProtectedRouteProps {
children: React.ReactNode;
redirectTo?: string;
}
export function ProtectedRoute({
children,
redirectTo = "/sign-in",
}: ProtectedRouteProps) {
const { isSignedIn, isLoading } = useAuthon();
if (isLoading) return <FullPageSpinner />;
if (!isSignedIn) return <Navigate to={redirectTo} replace />;
return <>{children}</>;
}
// Usage in router
const router = createBrowserRouter([
{ path: "/", element: <Home /> },
{
path: "/dashboard",
element: (
<ProtectedRoute>
<Dashboard />
</ProtectedRoute>
),
},
]);토큰 사용
getToken() 로 백엔드 API 호출에 JWT를 첨부하세요:
tsx
import { useAuthon } from "@authon/react";
function useApi() {
const { getToken } = useAuthon();
const apiFetch = async (path: string, init?: RequestInit) => {
const token = getToken();
return fetch(`/api${path}`, {
...init,
headers: {
...init?.headers,
Authorization: token ? `Bearer ${token}` : "",
"Content-Type": "application/json",
},
});
};
return { apiFetch };
}
// In a component
function OrdersList() {
const { apiFetch } = useApi();
const [orders, setOrders] = useState([]);
useEffect(() => {
apiFetch("/orders").then((r) => r.json()).then(setOrders);
}, []);
return <ul>{orders.map((o) => <li key={o.id}>{o.name}</li>)}</ul>;
}