---
title: InsForge Auth Components
description: Framework-agnostic authentication components guidance for customization
---

## Custom Authentication system

Use this approach when you need custom authentication pages in your application instead of redirecting to hosted pages.

### Step-by-Step: Custom Auth Pages Setup

#### Step 1: Setup Provider (Same as Quick Start)

The provider setup is identical:

```tsx src/main.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { InsforgeProvider } from '@insforge/react-router';
import App from './App';

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <InsforgeProvider
      baseUrl={
        import.meta.env.VITE_INSFORGE_BASE_URL || 'https://your-app.region.insforge.app' // Replace with your InsForge backend URL
      }
      afterSignInUrl="/dashboard"
    >
      <App />
    </InsforgeProvider>
  </StrictMode>
);
```

#### Step 2: Configure Router with Custom Pages

Set `builtInAuth: false` and provide your page components:

```tsx src/App.tsx
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import { getInsforgeRoutes } from '@insforge/react-router/router';
import Layout from './components/Layout';
import Home from './pages/Home';
import Dashboard from './pages/Dashboard';
// Import your custom auth pages
import SignInPage from './pages/auth/SignInPage';
import SignUpPage from './pages/auth/SignUpPage';
import ForgotPasswordPage from './pages/auth/ForgotPasswordPage';

const router = createBrowserRouter([
  {
    path: '/',
    element: <Layout />,
    children: [
      { index: true, element: <Home /> },
      { path: 'dashboard', element: <Dashboard /> },
    ],
  },

  // Custom auth routes
  ...getInsforgeRoutes({
    baseUrl: import.meta.env.VITE_INSFORGE_BASE_URL || 'https://your-app.region.insforge.app', // Replace with your InsForge backend URL
    afterSignInUrl: '/dashboard',
    builtInAuth: false, // Render custom components instead of redirecting
    pages: {
      signIn: <SignInPage />,
      signUp: <SignUpPage />,
      forgotPassword: <ForgotPasswordPage />,
    },
  }),
]);

export default function App() {
  return <RouterProvider router={router} />;
}
```

#### Step 3: Create Auth Page Components

Use our complete authentication components directly. These components are **full-featured page-level components** with all business logic included:

```tsx src/pages/auth/SignInPage.tsx
import { SignIn } from '@insforge/react-router';

export default function SignInPage() {
  return (
    <div className="h-screen flex items-center justify-center">
      <SignIn
        title="Welcome Back"
        subtitle="Sign in to your account"
        onError={(error) => {
          console.error('Sign in error:', error);
        }}
      />
    </div>
  );
}
```

```tsx src/pages/auth/SignUpPage.tsx
import { SignUp } from '@insforge/react-router';

export default function SignUpPage() {
  return (
    <div className="h-screen flex items-center justify-center">
      <SignUp
        title="Create Account"
        subtitle="Get started for free"
        onError={(error) => {
          console.error('Sign up error:', error);
        }}
      />
    </div>
  );
}
```

```tsx src/pages/auth/ForgotPasswordPage.tsx
import { ForgotPassword } from '@insforge/react-router';

export default function ForgotPasswordPage() {
  return (
    <div className="h-screen flex items-center justify-center">
      <ForgotPassword
        onError={(error) => {
          console.error('Password reset error:', error);
        }}
      />
    </div>
  );
}
```

**That's it!** The `<SignIn>`, `<SignUp>`, and `<ForgotPassword>` components are complete page-level components that include:

- Form UI with validation
- OAuth provider buttons (auto-detected)
- Error handling
- Loading states
- Password strength indicators (SignUp)
- All authentication logic

You only need to wrap them in your page components for layout/styling purposes.

### Key Difference from Built-in Auth

**Built-in Auth:**

- `/sign-in` → Redirects to `https://your-app.region.insforge.app/auth/sign-in`
- Authentication happens on hosted page
- Returns to your app with token

**Custom Components:**

- `/sign-in` → Renders your `<SignInPage>` component
- Authentication happens in your app
- SDK handles token management automatically

---

## Features

- **Built-in Auth**: React Router integration with deployed auth pages
- **Complete Components**: Pre-built `<SignIn>`, `<SignUp>`, `<UserButton>` with business logic
- **OAuth Support**: Google, GitHub, Discord, Facebook, LinkedIn, Microsoft, Apple, X, Instagram, TikTok, Spotify
- **React Hooks**: `useAuth()`, `useUser()`, `usePublicAuthConfig()`
- **Control Components**: `<SignedIn>`, `<SignedOut>`, `<Protect>`
- **Form Components**: Pure UI forms for custom logic
- **TypeScript**: Full type safety

---

## How It Works

### Built-in Auth Flow

```
1. User clicks "Sign In" → Visits /sign-in route
   ↓
2. getInsforgeRoutes() redirects → https://your-app.region.insforge.app/auth/sign-in?redirect=yourapp.com/you-defined-destination-after-sign-in
   ↓
3. User signs in on deployed page → Backend processes authentication
   ↓
4. Backend redirects → yourapp.com/you-defined-destination-after-sign-in?access_token=xxx&user_id=xxx
   ↓
5. InsForge SDK will:
   - Extracts token from URL
   - Saves to localStorage
   - Verifies with getCurrentUser()
   - Updates Provider state
   ↓
6. User sees the destination page (e.g /dashboard)
```

### Custom UI Flow

```
1. User visits /sign-in route → Renders <SignIn> component
   ↓
2. User enters credentials → Component calls SDK methods
   ↓
3. SDK communicates with backend → Returns auth token and user data
   ↓
4. Component adds token to URL and redirects → SDK auto-detects token from URL
   ↓
5. Provider automatically updates auth state → Components re-render
   ↓
6. User sees authenticated UI at destination
```

**Architecture:**

- **InsforgeProvider**: Manages authentication state globally using React Context
- **getInsforgeRoutes()**: Creates redirect routes for built-in auth
- **SDK Integration**: All auth operations go through `@insforge/sdk`, which auto-detects tokens from URL
- **React Context**: Provides auth state to all child components
- **Hooks**: Easy access to auth methods and user data

---

## Complete Components (with Business Logic)

These components include full authentication logic and work out of the box.

### `<SignIn />`

Complete sign-in component with email/password and OAuth:

```tsx
import { SignIn } from '@insforge/react-router';

function SignInPage() {
  return (
    <SignIn
      title="Welcome Back"
      subtitle="Sign in to continue"
      onError={(error) => {
        console.error('Error:', error);
      }}
    />
  );
}
```

**Key Features:**

- Email/password authentication
- OAuth provider buttons (auto-detected from backend)
- Password visibility toggle
- Error handling
- Loading states
- Customizable text

**Props:**

- `onError` - Callback on error
- `title` / `subtitle` - Custom heading text

### `<SignUp />`

Complete sign-up component with password strength validation:

```tsx
import { SignUp } from '@insforge/react-router';

function SignUpPage() {
  return (
    <SignUp
      title="Create Account"
      subtitle="Get started with your free account"
      onError={(error) => {
        console.error('Error:', error);
      }}
    />
  );
}
```

**Key Features:**

- Email/password registration
- Real-time password strength indicator
- OAuth provider buttons
- Form validation
- Customizable text

**Props:** Same as `<SignIn>`.

### `<UserButton />`

User profile dropdown with sign-out:

```tsx
import { UserButton } from '@insforge/react-router';

function Header() {
  return (
    <header>
      <nav>{/* Your navigation */}</nav>
      <UserButton afterSignOutUrl="/" mode="detailed" />
    </header>
  );
}
```

**Modes:**

- `detailed` (default): Shows avatar + name + email
- `simple`: Shows avatar only

**Props:**

- `mode` - Display mode: `"detailed"` or `"simple"`
- `afterSignOutUrl` - Redirect URL after sign out

### `<ForgotPassword />`

Complete password reset flow with automatic method detection:

```tsx
import { ForgotPassword } from '@insforge/react-router';

function ForgotPasswordPage() {
  return (
    <ForgotPassword
      onError={(error) => {
        console.error('Error:', error);
      }}
    />
  );
}
```

**Key Features:**

- Auto-detects reset method (code or link) from backend config
- **Link method**: Sends email with reset link
- **Code method**: Three-step flow (email → verify code → reset password)
- 60-second countdown timer for resend
- Built-in form validation
- Customizable text

**Props:**

- `onError` - Callback on error

### `<Protect />`

Protected content with conditional rendering:

```tsx
import { Protect } from '@insforge/react-router';

function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      {/* Simple protection */}
      <Protect redirectTo="/sign-in">
        <UserContent />
      </Protect>
      {/* Custom logic */}
      <Protect condition={(user) => user.subscription === 'premium'} fallback={<UpgradePrompt />}>
        <PremiumFeature />
      </Protect>
    </div>
  );
}
```

**Props:**

- `redirectTo` - URL to redirect if not authorized
- `condition` - Custom condition function `(user) => boolean`
- `fallback` - React node to show if not authorized

### `<SignedIn>` / `<SignedOut>`

Conditional rendering based on auth state:

```tsx
import { SignedIn, SignedOut } from '@insforge/react-router';

function NavBar() {
  return (
    <nav>
      <SignedOut>
        <a href="/sign-in">Sign In</a>
        <a href="/sign-up">Sign Up</a>
      </SignedOut>

      <SignedIn>
        <a href="/dashboard">Dashboard</a>
        <UserButton />
      </SignedIn>
    </nav>
  );
}
```

---

## Hooks

### `useAuth()`

Access authentication methods and state:

```tsx
import { useAuth } from '@insforge/react-router';

function LoginButton() {
  const { signIn, signUp, signOut, isSignedIn, isLoaded } = useAuth();

  const handleSignIn = async () => {
    try {
      await signIn('user@example.com', 'password');
    } catch (error) {
      console.error('Sign in failed:', error);
    }
  };

  if (!isLoaded) return <div>Loading...</div>;

  return (
    <button onClick={isSignedIn ? signOut : handleSignIn}>
      {isSignedIn ? 'Sign Out' : 'Sign In'}
    </button>
  );
}
```

**Returns:**

- `signIn(email, password)` - Sign in with email/password
- `signUp(email, password)` - Sign up new user
- `signOut()` - Sign out current user
- `isSignedIn` - Boolean auth state
- `isLoaded` - Boolean loading state

### `useUser()`

Access current user data:

```tsx
import { useUser } from '@insforge/react-router';

function UserProfile() {
  const { user, isLoaded, updateUser } = useUser();

  if (!isLoaded) return <div>Loading...</div>;
  if (!user) return <div>Not signed in</div>;

  const handleUpdate = async () => {
    await updateUser({ name: 'New Name' });
  };

  return (
    <div>
      <p>Email: {user.email}</p>
      <p>Name: {user.name}</p>
      <img src={user.avatarUrl} alt="Avatar" />
      <button onClick={handleUpdate}>Update Name</button>
    </div>
  );
}
```

**Returns:**

- `user` - User object with id, email, name, avatarUrl
- `isLoaded` - Boolean loading state
- `updateUser(data)` - Update user profile

### `usePublicAuthConfig()`

Get your authentication config in InsForge:

```tsx
import { usePublicAuthConfig } from '@insforge/react-router';

function SignInPage() {
  const { authConfig, isLoaded } = usePublicAuthConfig();

  if (!isLoaded) return <div>Loading...</div>;

  return (
    <div>
      <p>Available OAuth: {authConfig.oAuthProviders.join(', ')}</p>
      <p>Password min length: {authConfig?.passwordMinLength}</p>
    </div>
  );
}
```

**Returns:**

- `authConfig` - Authentication Configuration you set in InsForge dashboard.
- `isLoaded` - Boolean loading state

<Warning>
  **Performance**: Only use this hook in SignIn/SignUp components to avoid unnecessary API calls.
</Warning>

---

## Advanced Features

### Auth Change Callback

Track authentication state changes:

```tsx
<InsforgeProvider
  baseUrl={baseUrl}
  onAuthChange={(user) => {
    if (user) {
      console.log('User signed in:', user.email);
      analytics.identify(user.id);
    } else {
      console.log('User signed out');
      analytics.reset();
    }
  }}
>
  {children}
</InsforgeProvider>
```
