The @insforge/nextjs package provides authentication for Next.js applications using hosted auth pages.
When users sign in, they’re redirected to your InsForge backend’s login page, then returned to your app after authentication—no UI code required.
Quick Start
Step 1: Create New Next.js Project (Required)
npm install @insforge/nextjs@latest
Step 2: Set Environment Variables
NEXT_PUBLIC_INSFORGE_BASE_URL=https://your-app.region.insforge.app
NEXT_PUBLIC_INSFORGE_ANON_KEY=your-anon-key-here
Step 3: Add Middleware
Create middleware to protect routes:
import { InsforgeMiddleware } from '@insforge/nextjs/middleware';
export default InsforgeMiddleware({
baseUrl: process.env.NEXT_PUBLIC_INSFORGE_BASE_URL || 'https://your-app.region.insforge.app', // Replace with your InsForge backend URL
publicRoutes: ['/'],
});
export const config = {
matcher: [
'/((?!api|_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
],
};
Step 4: Create API Route
Create an API route to enable server-side rendering (SSR) and cookie-based authentication:
import { createAuthRouteHandlers } from '@insforge/nextjs/api';
const handlers = createAuthRouteHandlers({
baseUrl: process.env.NEXT_PUBLIC_INSFORGE_BASE_URL || 'https://your-app.region.insforge.app', // Replace with your InsForge backend URL
});
export const POST = handlers.POST;
export const GET = handlers.GET;
export const DELETE = handlers.DELETE;
Why? This route syncs auth tokens to HTTP-only cookies for server-side middleware.
Step 5: Create InsforgeProvider Component
// app/providers.tsx
'use client';
import { InsforgeBrowserProvider, type InitialAuthState } from '@insforge/nextjs';
import { insforge } from '@/lib/insforge';
export function InsforgeProvider({ children }: { children: React.ReactNode }) {
return (
<InsforgeBrowserProvider client={insforge} afterSignInUrl="/dashboard">
{children}
</InsforgeBrowserProvider>
);
}
Step 6: Add InsforgeProvider to Root Layout
Wrap your application with the InsforgeProvider in your root layout:
import {
SignedIn,
SignedOut,
SignInButton,
SignUpButton,
UserButton,
} from '@insforge/nextjs';
import { InsforgeProvider } from './providers';
export const metadata: Metadata = {
title: 'InsForge Next.js Quickstart',
description: 'Generated by create next app',
};
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<InsforgeProvider>
<nav>
<SignedOut>
<SignInButton />
<SignUpButton />
</SignedOut>
<SignedIn>
<UserButton />
</SignedIn>
</nav>
{children}
</InsforgeProvider>
</body>
</html>
);
}
Preventing FOUC: The CSS import in your root layout ensures styles are loaded during
server-side rendering, preventing flash of unstyled content (FOUC). Without this import,
components may briefly appear unstyled when the page first loads.
That’s it! When users click “Sign In”, they’ll be redirected to your backend’s auth page automatically.
Next Steps
Client-side Hooks
useAuth()
Access authentication state in client side:
'use client';
import { useAuth } from '@insforge/nextjs';
function LoginButton() {
const { isSignedIn, isLoaded } = useAuth();
if (!isLoaded) return <div>Loading...</div>;
return <div>{isSignedIn ? 'Welcome!' : 'Sign In'}</div>;
}
Returns:
isSignedIn - Boolean auth state
isLoaded - Boolean loading state
useUser()
Access current user data in client side:
'use client';
import { useUser } from '@insforge/nextjs';
function UserProfile() {
const { user, isLoaded } = useUser();
if (!isLoaded) return <div>Loading...</div>;
if (!user) return <div>Not signed in</div>;
return (
<div>
<p>Id: {user.id}</p>
<p>Email: {user.email}</p>
<p>Name: {user.profile.name}</p>
<img src={user.profile.avatar_url} alt="Avatar" />
</div>
);
}
Returns:
user - User object with id, email, profile
user.profile - User profile object with name, avatar_url, and other custom fields
isLoaded - Boolean loading state
Server side functions
auth
Access current user data and access token in server side:
import { auth } from '@insforge/nextjs/server';
import { createClient } from '@insforge/sdk';
export async function POST(request: NextRequest) {
try {
// Authenticate the request and get user info
const { token } = await auth();
// Parse request body to get the prompt
const { prompt } = await request.json();
// Create InsForge SDK client with user's token for authenticated access
const insforge = createClient({
baseUrl: process.env.NEXT_PUBLIC_INSFORGE_BASE_URL || 'https://your-app.region.insforge.app',
edgeFunctionToken: token,
});
// Request for AI response
const completion = await insforge.ai.chat.completions.create({
model: 'anthropic/claude-3.5-haiku',
messages: [
{
role: 'user',
content: prompt,
},
],
});
const generatedResponse = completion.choices[0].message.content.trim();
// Return success response
return NextResponse.json(
{
success: true,
data: generatedResponse,
},
{ status: 201 }
);
} catch (error) {
console.error(error);
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
}
}
Returns:
user - User object with id, email, profile
userId - User ID
token - User’s access token