@insforge/nextjs
v1.0.1
Published
Pre-built authentication UI components for Next.js with Insforge backend - zero configuration required
Maintainers
Readme
@insforge/nextjs
Zero-configuration authentication for Next.js using Insforge backend. Get production-ready auth in 5 minutes.
Why @insforge/nextjs?
✅ Built-in Auth Pages - Backend-hosted UI, no React code needed
✅ 5-Minute Setup - Provider + API route + callback + middleware = done
✅ Full SSR Support - Works with Next.js App Router and Server Components
✅ Auto OAuth - 11 providers configured from backend automatically
✅ TypeScript First - Complete type safety out of the box
Need custom UI? Scroll to Customization for custom components and styling.
Installation
npm install @insforge/nextjsQuick Start
1. Setup Provider
Wrap your app with InsforgeProvider in the root layout:
// app/layout.tsx
import { InsforgeProvider } from '@insforge/nextjs';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<InsforgeProvider
baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}
afterSignInUrl="/dashboard"
>
{children}
</InsforgeProvider>
</body>
</html>
);
}Zero Configuration: Styles are automatically injected via Emotion CSS-in-JS. No CSS imports needed!
2. Create API Route
Create an API route to sync tokens to HTTP-only cookies (enables SSR):
// app/api/auth/route.ts
import { createAuthRouteHandlers } from '@insforge/nextjs/api';
const handlers = createAuthRouteHandlers({
baseUrl: process.env.INSFORGE_BASE_URL || process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!,
cookieName: 'insforge_token',
});
export const POST = handlers.POST;
export const GET = handlers.GET;
export const DELETE = handlers.DELETE;What it does:
POST /api/auth- Syncs localStorage token to HTTP-only cookieGET /api/auth- Retrieves user data server-sideDELETE /api/auth- Clears auth cookie on sign out
3. Setup Middleware
Protect routes with middleware:
// middleware.ts
import { InsforgeMiddleware } from '@insforge/nextjs/middleware';
export default InsforgeMiddleware({
baseUrl: process.env.INSFORGE_BASE_URL!,
publicRoutes: ['/auth/callback', '/'],
cookieName: 'insforge_token',
});
export const config = {
matcher: [
'/((?!api|_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
],
};What it does:
- Redirects unauthenticated users to backend auth pages
- Verifies tokens server-side
- Allows public routes without auth
4. Use Hooks & Components
// app/page.tsx
import { SignedIn, SignedOut, UserButton } from '@insforge/nextjs';
export default function Home() {
return (
<div>
<SignedOut>
<a href="/sign-in">Sign In</a>
</SignedOut>
<SignedIn>
<UserButton afterSignOutUrl="/" />
<h1>Welcome back!</h1>
</SignedIn>
</div>
);
}Available Hooks:
import { useAuth, useUser } from '@insforge/nextjs';
function Component() {
const { signIn, signUp, signOut, isSignedIn, isLoaded } = useAuth();
const { user, updateUser } = useUser();
return <div>Email: {user?.email}</div>;
}That's it! 🎉 Your app now has production-ready authentication.
How It Works
1. User clicks "Sign In" → Middleware redirects to backend auth page
↓
2. User signs in on backend (https://your-project.insforge.app/auth/sign-in)
↓
3. Backend redirects: yourapp.com?access_token=xxx&user_id=xxx...
↓
4. SDK auto-detects URL parameters:
- Stores token in localStorage
- Provider automatically reloads auth state
- Token syncs to HTTP-only cookie (via API route)
↓
5. User sees dashboard with authenticated stateTwo-Storage Architecture:
- localStorage: Client-side token access (hooks, components, SDK)
- HTTP-only cookie: Server-side token access (middleware, SSR)
Customization
Custom Auth Pages
Want custom branding? Create custom auth pages instead of using built-in pages:
// app/sign-in/page.tsx
'use client';
import { SignIn } from '@insforge/nextjs';
import { useRouter } from 'next/navigation';
export default function SignInPage() {
const router = useRouter();
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<SignIn
afterSignInUrl="/dashboard"
onSuccess={(user) => {
console.log('Signed in:', user);
router.push('/dashboard');
}}
/>
</div>
);
}Additional Auth Components:
// Password reset flow
import { ForgotPassword, ResetPassword, VerifyEmail } from '@insforge/nextjs';
// app/forgot-password/page.tsx
<ForgotPassword backToSignInUrl="/sign-in" />
// app/reset-password/page.tsx (with token from URL)
<ResetPassword token={token} backToSignInUrl="/sign-in" />
// app/verify-email/page.tsx (with token from URL)
<VerifyEmail token={token} />Available Atomic Components:
AuthContainer- Main form containerAuthHeader- Title and subtitleAuthFormField- Standard input fieldAuthPasswordField- Password field with visibility toggleAuthPasswordStrengthIndicator- Password requirement checklistAuthSubmitButton- Submit button with loading statesAuthErrorBanner- Error message displayAuthDivider- Visual separatorAuthOAuthProviders- OAuth provider buttons gridAuthOAuthButton- Individual OAuth buttonAuthVerificationCodeInput- OTP/2FA code inputAuthLink- Navigation linkAuthBranding- Insforge branding footer
Server-Side Usage
Access auth data in Server Components, API Routes, and Server Actions using the auth() helper:
Using in Server Components
// app/dashboard/page.tsx (Server Component)
import { auth } from '@insforge/nextjs/server';
export default async function Dashboard() {
const { userId, user } = await auth();
if (!userId) {
return <div>Not authenticated</div>;
}
return <div>Welcome, {user?.email}!</div>;
}Using in API Routes
// app/api/posts/route.ts
import { auth, createServerClient } from '@insforge/nextjs/server';
import { NextResponse } from 'next/server';
export async function GET() {
const { userId, token } = await auth();
if (!userId || !token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
// Option 1: Use auth info directly
return NextResponse.json({ userId, message: 'Authenticated!' });
// Option 2: Use createServerClient for database operations
const insforge = await createServerClient({
baseUrl: process.env.INSFORGE_BASE_URL!,
});
if (!insforge) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const result = await insforge.database.from('posts').select();
return NextResponse.json(result.data);
}Using in Server Actions
'use server';
import { auth } from '@insforge/nextjs/server';
import { revalidatePath } from 'next/cache';
export async function createPost(formData: FormData) {
const { userId } = await auth();
if (!userId) {
throw new Error('Not authenticated');
}
// Create post with userId
const title = formData.get('title');
// ... insert into database
revalidatePath('/posts');
}Conditional Rendering
import { Protect } from '@insforge/nextjs';
// Role-based access
<Protect condition={(user) => user.role === 'admin'}>
<AdminPanel />
</Protect>
// Custom logic
<Protect condition={(user) => user.emailVerified}>
<VerifiedUserFeature />
</Protect>Auth Change Callback
Track authentication events:
<InsforgeProvider
baseUrl={baseUrl}
onAuthChange={(user) => {
if (user) {
analytics.identify(user.id);
} else {
analytics.reset();
}
}}
/>Local Development
During local development, backend typically runs on a different port:
# .env.local
NEXT_PUBLIC_INSFORGE_BASE_URL=http://localhost:7130
INSFORGE_BASE_URL=http://localhost:7130TypeScript
Full TypeScript support with exported types:
import type {
InsforgeUser,
InsforgeCallbackProps,
SignInProps,
SignUpProps,
ForgotPasswordProps,
ResetPasswordProps,
VerifyEmailProps,
SignInAppearance,
SignUpAppearance,
UserButtonProps,
ProtectProps,
OAuthProvider,
} from '@insforge/nextjs';Support
- Documentation: https://docs.insforge.dev
- GitHub Issues: https://github.com/InsForge/InsForge/issues
- Discord Community: https://discord.com/invite/DvBtaEc9Jz
License
MIT
