Skip to content

Wiring Guide

Recipes for the three things every Khata front-end does: mount the provider, gate on the session, and edit the profile. All of these are presentational — swap in your own router or layout as needed.


📦 1. Mount the provider

import { AuthProvider } from "react-auth";
import type { AuthServerConfig } from "react-auth";

const authConfig: AuthServerConfig = {
  serverUrl: "https://api.example.com",
  loginPath: "/auth/login",
  registerPath: "/auth/register",
  logoutPath: "/auth/logout",
  mePath: "/auth/me",
  introspectPath: "/auth/introspect",
};

export default function Root() {
  return (
    <AuthProvider authConfig={authConfig} onUnauthorized={() => console.info("session expired")}>
      <App />
    </AuthProvider>
  );
}

AuthProvider must wrap any component that calls useAuth.


📦 2. Gate on the session

import { useAuth, AuthPage } from "react-auth";
import { useState } from "react";

function LoginGate({ children }: { children: React.ReactNode }) {
  const auth = useAuth();
  const [mode, setMode] = useState<"login" | "register">("login");

  if (auth.currentUser) return <>{children}</>;

  return (
    <AuthPage
      mode={mode}
      onBack={() => history.back()}
      onSwitchMode={() => setMode((m) => (m === "login" ? "register" : "login"))}
      login={auth.login}
      register={auth.register}
      loading={auth.loading}
      error={auth.error}
      currentUser={auth.currentUser}
    />
  );
}

Automatic redirect

AuthPage calls onBack on its own once currentUser becomes truthy, so it works as a route guard without a useEffect. mode is fully controlled, so the login/register toggle never unmounts the form.


📦 3. Profile screens

ProfileCreate, ProfileEdit and ProfileView render the profile UI and delegate persistence to callbacks you supply — the library does not know how your backend stores profiles.

The three screens take flat props, not a user object:

Component Props
ProfileView name, username, email, onEdit?, loading?
ProfileEdit name, username, email, onSubmit, onBack?, loading?, error?
ProfileCreate onSubmit, defaultUsername?, defaultEmail?, onBack?, loading?, error?
import { ProfileView, ProfileEdit, useAuth } from "react-auth";
import { useState } from "react";

function ProfileRoute() {
  const { currentUser } = useAuth();
  const [editing, setEditing] = useState(false);

  if (!currentUser) return null;
  const { username, email } = currentUser;
  const props = { username, email, name: username };

  if (editing) {
    return <ProfileEdit {...props} onBack={() => setEditing(false)} onSubmit={saveProfile} />;
  }
  return <ProfileView {...props} onEdit={() => setEditing(true)} />;
}

onSubmit always receives { name, email } — persistence is yours.

Client-side validation only

AuthPage validates username >= 3 and password >= 6 before calling your callback. The auth server remains the authority — never skip its validation.


📦 4. Authenticated API calls

1
2
3
4
import { createApiClient } from "react-auth";

const api = createApiClient("https://api.example.com");
const { data } = await api.get("/expenses"); // Authorization added automatically

Use createApiClient for any backend that shares the auth-server login. A plain axios instance is fine for unauthenticated endpoints.

For an existing client, attachAuthInterceptors(client) decorates it in place with the same request/response behaviour.